How 2D in 3D (Anthony Flack's Cletus)?

Blitz3D Forums/Blitz3D Programming/How 2D in 3D (Anthony Flack's Cletus)?

coffeedotbean(Posted 2003) [#1]
After buying Blitz3D about 2 months ago and not realy touching it :( still stuck in 2D mode, Ive decided to meet it half way and convert my Alphabreed game from BB2D to BB3D ( but keeping it in a 2D view) and take advantage of the Alpha stuff and vertex shading etc.

Anthonty Flacks game cletus showed me how effective it is and I wanna do that.

Any simple expamles about the place I could rip apart, especialy something about an animated sprite or what ever I would use to display my charaters.


(tu) ENAY(Posted 2003) [#2]
It's all done with quads. But I think you'll find it rather difficult to convert your existing 2D game to 3D. Since the approach of quads to sprites is quite different. Still, you could always give it a try, but personally since your game seems to look finished, I'd stick with how it is in Blitz2D.


simonh(Posted 2003) [#3]
The Cletus method of 2D using 3D is actually quite advanced. I wouldn't recommend trying that as your first project in B3D.

If you just want the speed-up that 2D using 3D gives, then run your project in BlitzPlus using the OpenGL driver, this should give it quite a boost.

And if you're lucky, maybe Mark will add alpha-blending and real-time rotation to BlitzPlus.


Beaker(Posted 2003) [#4]
There are a few examples of syntax-alike libraries for this stuff in the code archive. JPickfords comes to mind.


(tu) ENAY(Posted 2003) [#5]
> The Cletus method of 2D using 3D is actually
> quite advanced.

I'd have to agree there too. Once you start messing about with quads, texturing and moving the camera about, simple things start getting complicated.
It's certainly a lot more complicated than using DrawImage.
And then you've got to manage your layer priorities, collision detections and stuff manually. So no ImagesCollide or drawing your objects in a set order.
If you do decide to use Blitz3D for this then you're better off making an entirely new game instead of converting your old game, as it isn't quick or easy. I'm just getting my head round it.


Dr Derek Doctors(Posted 2003) [#6]
John Pickford's released a lovely 2D in 3D library. Have a look on the general forums for a post called SNES like graphics or 2D in 3D or summat. Makes tilemaps and stuff like that easy to use.


Anthony Flack(Posted 2003) [#7]
Yeah, however you do it you're likely to be in for a monster task converting your game - if it were me I'd finish it as is, and start your next game in 3d (actually, that IS what I did...) Definitely check out JP's library, it's good, it's fast, it's free and it takes all the pain out of 2d-in-3d


John Pickford(Posted 2003) [#8]
My code allows you to program just like in 2D. Drawing objects in a set order works just fine.

Collision detection has to be done yourself, but that's the best way to do it anyhow.

coffedot, Email me (john@...) if you want the latest code.


coffeedotbean(Posted 2003) [#9]
Thanks for the replys peeps, i knew it wasnt gonna be an easy process. Ill try out your code John, Alphabreed probaly will stay in 2D its about 80% done, Players of the demo from my sig want recognize the current version... but im keeping it secret for a while.... ohhh the tension. :)


Jeppe Nielsen(Posted 2003) [#10]
You could always add alpha stuff on top of your current 2d game. But thats just a suggestion :)


RiK(Posted 2003) [#11]
The Cletus method of 2D using 3D is actually quite advanced. I wouldn't recommend trying that as your first project in B3D.

Any chance you could give us a quick overview of what that method is Anthony? A few people here seem to know how you've done it, sorry if its already been discussed elsewhere.


Anthony Flack(Posted 2003) [#12]
I outlined some of the key points a while back on Blitzcoder. Here it is again:


First of all, I have to say it took me a little while to get everything set up and working satisfactorily, before I could really get down to making a game at all. So be prepared for a bit of not very exciting coding at the very start of the project... I'm not going to go into much technical detail here, just give a brief overview about the kinds of issues I faced and what I did about them; hopefully some of this is helpful.

First of all, I don't recommend mixing direct-draw style 2d with 3d-as-2d. It messes up when you change res, it messes up on certain cards and drivers, and it's just messy (and slower) in general. Once you have a working set of routines for 2d-in-3d, just use that for everything; much nicer.

Also I didn't use any sprites. Originally, it was because I couldn't apply lighting effects to them, and later it was mostly because of the need to combine things on a single surface - handmade quad meshes are definitely the way to go for maximum flexibility. Faster too.

I had to ditch the ortho camera as well, unfortunately... it was messing with the z-buffer a little on my card. I substituted a camera that was 100000 units away, and zoomed right in and restricted to a very narrow z-band (999900-100000) - a bit of a nuisance, but it fixed the problem, and gives virtually the same result.

Next, I knew I was going to need a thousand sprites or more on screen at once, and there was no way I was going to get away with having a separate surface for each of them, so it meant I had to go with a single surface system. More about that in a minute.

Now, the power-of-two textures was causing me trouble too. First off, I had to deal with a main character whose arms and legs were all over the place - some frames needed to be tall and thin, some short and wide. Others just plain big. To accomodate all of this in a power of 2 square at any kind of acceptable res, would have required a 128x128 square, with lots of wasted space on most frames. With over 150 animation frames needed for the little guy, this would have chewed through the video memory in no time. So what I did was, I took a 256x256 square (this being the maximum size that is guaranteed to be supported by virtually all 3d cards), and I squeezed as many graphics onto this as I could. All the graphics in the game are arranged on tiles of 256x256, and arranged according to themes. The main character takes up 8 tiles. The baddies take up 7. Collectable items are all crammed onto 1. Now, of course a single surface system requires that all the graphics be on a single texture, so I created a big 1024x2048 texture at runtime, and all the 256x256 tiles are loaded in one by one and copied onto this big texture, like a big bank of 4x8 tiles. Doing it like this means I can load and free up different 256x256 tiles according to what graphics set I need for any given level. Of course this raises another issue... only some cards can support a 1024x2048 texture... more on THIS later...

Oh, by the way - never EVER load in textures that aren't powers of 2 to start off with. Yes, blitz will scale them up, but not only is this wasteful, but far more seriously, it looks UGLY. Blitz does NOT do a good job of scaling them up, all it does is double some of the rows of pixels... end result is you get some rows of pixels that are twice as fat as others, and it looks really bad. Avoid like the plague.

Okay, next thing I did was make a little editor that would load up a single 256x256 tile and display it full screen. You could then stretch bounding boxes all over it to define where all the different sprites are. The program would translate the corners of the boxes on screen into UV coordinates on the texture. It then saved a data file that went along with that tile, like, this tile has 34 sprites on it, and these are their UV coordinates. Since the bounding boxes can be of any sizes within that 256x256 tile, this solves the power of 2 problem, and means I get to use my odd rectangular sprites of arbitrary pixel dimensions, and minimise wasted video RAM... providing I can pack them all nice and tightly onto the tiles, which I have more or less managed to do.

I could now start writing the single surface system for the game.

When the program starts, the big texture is created, the tiles are loaded onto it, along with the uv data that goes along with the tiles (Of course the program also has to remember where each tile is on the big texture... and offset its UV coordinates accordingly). A blank surface is created using this texture.

Then I made my draw3dsprite function. This function takes as input which tile you want to draw from, which image in the tile, the x and y co-ordinates, size, rotation, colour, opacity, and other game-specific stuff like whether it should be affected by lights or shadows. What it basically does is it creates 4 new vertexes and 2 new triangles on the big surface, centered around the x and y coordinates you give it. It textures the trianges according to the uv coordinates in the data file, referenced by the tile and frame number. It scales it according to the size, but also taking into account the uv coordinates, so that long skinny frames still come out long and skinny, etc. The colour of the sprite is set using vertex colours, and the opacity is set using vertex alpha (brilliant; I was waiting for this function!). Rotation is a bit trickier, I had to get a bit more maths-y than I usually like in order to rotate it properly, but I think there's stuff in the code archives for this...

I don't keep track of any of the vertices created. Every frame, I do a clearsurface and scrap all of it, and rebuild them all again from scratch. Some speed tests I did showed this was only a tiny, tiny bit slower than moving preexisting vertices around, and it is a lot easier. Plus it has some other advantages, as you'll see... Basically, clearsurface becomes my CLS, and the draw3dsprite function becomes my drawimage.

Right, other issues...

All the sprites in my game use an alpha channel for transparency (which was a big part of why I wanted to use 3d in the first place). This causes problems since, due to the nature of transparent textures, they can't use the z-buffer properly. In other words, don't expect to be able to sort the priority of sprites by changing the z-value, if you're using alpha channels (note that my draw3dsprite command doesn't ask for a z-value!). Instead, you must be aware that all triangles in the surface will be rendered in the order you added them to the surface. The last thing you draw will go on the top. Just like using drawimage, really. Also, this method is only good for triangles that are part of that big, merged surface. If a triangle isn't in that big surface, you CAN'T make it appear, say, behind one object that is in the big surface, and in front of another that is in the big surface. It's either behind them all or in front of them all. Um, did that make sense?

Anyway, that's why I needed to get all the sprites onto the one 1024x2048 surface. Actually, what I do is, the background, like the sky and the mountains, is made up of several surfaces, the font is made up pf another surface, but all the main action stuff, the things that have to go in front and behind each other freely, MUST be part of that same surface.

There are some other issues with using a single surface though - since so many effects are applied on a per-entity basis - you can't apply different blend modes for different sprites... my laser beams can't use an additive blend, sadly, unless they were given their own single surface - and if I did that, then they wouldn't be able to go in front and behind objects in the main surface (they'd either have to be in front of all of them, like the font, or behind all of them, like the background). This is a bit of a bummer, but I just have to work with it. You can't make things full bright either though. This WAS a problem, as I wanted certain things (like laser beams, explosions, etc) to be full-bright even if it was a night-time scene. So I ditched the DX lights altogether, and wrote a custom lighting function that simulated DX lights by manipulating the vertex colours, and was just as flexible as I cared to make it. So I get my full bright objects. And thank you so much, Mark, for adding vertex alpha - before that there was no way to control the opacity of different sprites, except by making them semi-transparent in the source file. As soon as vertex alpha was added, I added another parameter to my draw3dsprite command.

Now, everything's working sweet, it's fast, it's functional, it's more or less just like using a supercharged drawimage command... but there's one problem... remember the cards that don't support 1024x2048 textures? Oops, they're screwed...

Some people would probably say at this point, "Ah, too bad, let them get a new card, I don't want those luddites holding me back, blah blah blah...) - but I didn't want to do that. I wanted to make it work for as many machines as possible... so, one of the first things the game does is create a 1024x2048 texture, and then checks its dimensions... if they come back as anything other than 1024x2048, you know the card won't do it, so it kicks into plan B:

Remember that all the graphics are stored as 256x256 tiles. This is a pretty safe size, even a voodoo 1 can handle it. So plan B involves loading up all these tiles, but instead of merging them into one big texture, it keeps them seperate and creates a surface for each of them. Texture size problem solved - but it raises another problem...

Remember I said that you could only z-order the triangles WITHIN a surface, not between surfaces? But in this case, all of these tile surfaces have to be able to intermingle for the game to look right. Can't be done, so I have to ditch the alpha transparency (ouch!) - the game reverts to using masked transparency. Using masks means that you can use the z-buffer for z-ordering again. So in this way, I can get the sprites to intermingle, at the expense of losing the cool alpha effects - ah well, it's better than having it not working at all. In this case, I have a variable, z_order, which gets set to 0 at the start of each game loop. Then, when the first draw3dimage function is called, it creates the first quad at the z-position of the z_order variable, and then it increments z_order by .01 - meaning the next quad will be drawn slightly in front of it. In this way, the plan B drawing method works just like the plan A one - the last sprite drawn goes on the top.

Whew! Okay, that's the basics of what I did.

Oh, one more thing - since all uv coords are stored as a value between 0 and 1, regardless of the size of the texture, it wasn't too difficult to add an option to load all the graphics in at half resolution - every second pixel, onto a texture half the size - the UV data stays the same. The big advantage here, of course, is saving memory - it doesn't look pretty, but it reduces memory requirements from 16 megs to 4. The game will do this as a last-ditch effort to provide a playable framerate on cards with very little memory.

Sheesh, now that is one long post! Just as well I didn't go into technical details! I hope this is somehow informative or helpful, since even though I was trying to be brief, it sure took a long time to explain...




RiK(Posted 2003) [#13]
Thanks Anthony, interesting reading!


Anthony Flack(Posted 2003) [#14]
A bit of a novel, though, isn't it?

It's funny how long it can take to explain things. Even relatively simple things.


RiK(Posted 2003) [#15]
Well thanks anyway, it was a useful read. I've been experimenting with some 2d in 3d mode stuff myself, and contemplating a single-surface system.

Having done some initial speed tests versus blitz sprites it is fairly apparent this is the way to go, and I guess a fundamental reason why Mark hasn't implemented a more extensive hardware-accelerated sprite system in 2d yet. Either that or perhaps he doent think it would be that popular...

Habing downloaded the Cletus demo I was very impressed by just how smooth you've got it running, damed fine job so far! Any rough estimates as to when you'll be hoping to release it?


Anthony Flack(Posted 2003) [#16]
Ah, now that is the question! Um, 3 months? But only if it's good and ready though, not before...

but why not go to the website and sign up for the mailing list? I'll email ya the minute it comes out.

There is a new demo coming out on the blitz demo CD, by the way, which is far more advanced than the old demo. But which is now also quite a lot behind the version on my harddrive...


FlameDuck(Posted 2003) [#17]
I guess a fundamental reason why Mark hasn't implemented a more extensive hardware-accelerated sprite system in 2d yet.
You'd be guessing right. The reason as it turns out is that hardware accellerated 2D is a figment or your imagination. A long time ago there was this company called 3Dfx who developed some chips that could do accelerated 3D, to a much higher degree than what was previously possible. In the rush that ensued and in an effort to grab a peice of the enormous sales that these new 3Dfx cards had, executive decisions to abandon 2D hardware was made. You're GeForceFX, for all it's 3D glory has the exact same 2D capabilities as the Riva 128. The only two companies that didn't abandon 2D hardware where Neo-Geo and Sega. And look what happened to them. They have kick-ass 2D hardware, but nobody hardly cares because the same effects can now be acheived in 3D (except it doesn't look as pretty).


Anthony Flack(Posted 2003) [#18]
Sigh. Don't I know it.


(tu) ENAY(Posted 2003) [#19]
Anthony, I'm in the middle of doing what you're doing with your multiple quads in a single surface and mesh. But for some reason I can't seem to texture any more than the first quad I create within the mesh, the first 4 vertices contain the texture I add to it, but the rest remain empty.

I've been looking closely at JohnP Pickfords SNES style engine but I can't seem to figure out what I'm doing wrong or how he's achieved it.

Any pointers you could give me on perhaps what I'm doing wrong? ;)

Cheers.


RiK(Posted 2003) [#20]
Anthony - I signed up already... ;)

Not that I'm impatient or anything.... oh no, not me...

I am geniunely gobsmacked by your engine though, it just looks *so* sweet. I loved Platypus and I'm still amazed by how much you got moving without dropping the framerate. You must let us in on the secret some day.. come on admit it, Mark told you some secret stuff that nobody else knows right... You signed your soul over to get some extra clock cycles?


Anthony Flack(Posted 2003) [#21]
ENAY - hmm, you know that all the quads in the surface must be textured with the same texture, right? All you can change is the UV co-ordinates.

RiK - if there's a secret I'm not aware of it... maybe it's just because I tend to avoid fancy maths (because my brain doesn't like it), my code tends to run fast. Dunno. Anyway, I'm just glad it's running fast!


Warren(Posted 2003) [#22]
Anthony

Thanks for the big write up earlier in the thread. I started hacking around with my own version of it tonight and it came together a lot faster having read your post.


(tu) ENAY(Posted 2003) [#23]
Arrrrrrggggghhhhhhh. :)

I finally figured it out. I had the equivalent of a 'for loop=0 to 0. So it's no wonder I've had so many annoying problems with only quad working. I only ever HAD one quad. I almost tried everything in the loop until I had a quick look at start of it. I mean FFS how stupid can you get?

Feel free to give me a damn good slapping.


I'm well impressed with the speed increase for using quads in a single surface.
I thought sprites were quick, then I discovered quads and now quads in a single surface.

I could only get 200 sprites on screen before without getting slowdown.
Then about 500 quads with individual surfaces.
But now I can get 1500 quads on screen with no sign of slowdown.
You could probably get even better performance by just using triangles instead of quads and offsetting the uv coords to the centre of the triangle instead of the square. Which would be ideal for small low detailed particles.

Although it's probably not too surprising getting more performance since the complexity of the code is also increasing.

But the best thing for me is that I can now also flip the uv coords in real time. No more needing two seperate frames for facing left and right. And not to mention being able to do some cool distortion techniques now, of which you couldn't do with blitz's sprites. :)


Anthony Flack(Posted 2003) [#24]
Oh, don't I know it...

Mirroring, all go.
Scaling and distortion, no problem.
Rotation, looks great.
Alpha transpareny, lovely.
Vertex colours, not as good as palettes but surprisingly versatile nonetheless, and a heck of a lot better than nothing.

And don't forget you have the not-to-be-underrated subpixel accuracy. Like for eg, the moons in platypus moved really slowly, so it was really noticeable when they "clicked" over onto the next pixel. Not so with 3d; it interpolates the whole thing beautifully, and you get super-smooth, imperceptibly slow motion.

Plus the whole thing, while being not quite so backwards compatible, is at least more future-proofed... and safe from things like the nvidia driver fiasco.

I wouldn't recommend using triangles though - you'll waste 50% of your vidram, and the increased fill area is likely to kill off any benifits you might see. Though I think the major bottleneck is usually in reconstructing the mesh every frame, rather than polygon count or (unless you're going really crazy), fill rate. 3000 polys vs 1500 polys isn't that big a deal to a 3d card. Hacking around with mesh geometry, they don't seem to like quite so much.


(tu) ENAY(Posted 2003) [#25]
> I think the major bottleneck is usually
> in reconstructing the mesh every frame

Woah. Is that wise. What I've done is make the max amount of quads I'll ever need and then just move the quads I'm not using way off screen and no UV. That way I've got a fairly static framerate.

Are you reconstructing them every frame in Cletus?
Although it does depend on how many quads you're making I suppose.


Anthony Flack(Posted 2003) [#26]
I did tests, and I found that moving already constructed vertices was just *slightly* (like, 0.001% or something) faster than reconstructing the mesh every frame. I think that whether you reconstruct the whole mesh, or move even just one vertice, incurs the same hit to the video card... because it has to go fetch the mesh, send it to system memory, do the changes, then send it back, and reconstruct it. Or so my limited understanding of such things would have it.

Anyway, the upshot is, it's not any slower to destroy the mesh (with clearsurface), and reconstruct it every frame. In your case, I actually think it would be faster, specifically because you only have create the quads you need, and not have a bunch of spare quads hiding away in the corner (which, if I understand it correctly, would still give a speed hit even if you weren't moving them, because they are still part of the entity you are modifying).

But the difference isn't likely to be large. The real decider for me was, that clearsurface() and reconstruct is much, much easier to work with. You can read a bit about how I set up that system in the whopping great quote box above.


(tu) ENAY(Posted 2003) [#27]
I've just read that actually. Interesting stuff, kind of almost what I've been doing.

I've been reading through some of JohnPs comments in his source code and he does the same as me, keeps the meshes, it's true that you process them even when they're not in use but that's kind of what is good about it. You get a constant CPU hit which should mean no sudden jerks or speed ups in frame rate.
So the game will run more like a console.


Anthony Flack(Posted 2003) [#28]
Yeah, that was JPs stated goal. With me, the number of polygons changes quite a lot; but there's no limit to the maximum number of polygons on screen. It's possible to have things go absolutely crazy - hundreds of particles, explosions, all sorts of stuff all happening at once. Perhaps the framerate at these times would go down on slow hardware, but the frameskipping should make it not too noticeable. And the good part is, as soon as things have calmed down, everyting runs smooth again.


(tu) ENAY(Posted 2003) [#29]
I agree about that one pixel movement thingy. It seems that moving from between one pixel is untra smooth in 3D the way it interpolates across, slow moving objects do look well sexy now. :)
Anthony, have you mastered pivot point rotation on your quads? I can get mine to rotate in the centre but I haven't
yet managed to be able to spin them a point.
Doh. I wish I could find my maths books.


(tu) ENAY(Posted 2003) [#30]
Cracked it, I've now got my quads to rotate in a pivot point and also at the same time within the centre of the quad. Sorted :)


Anthony Flack(Posted 2003) [#31]
Sweet - mine just rotate in the centre... for speed, but mostly so I don't have to think too hard.


RiK(Posted 2003) [#32]
So any chance of another demo soon then Anthony?


Anthony Flack(Posted 2003) [#33]
There'll be one on the blitz demo CD. So ask Mark or Simon when that's coming out.


RiK(Posted 2003) [#34]
Err,

"Mark or Simon, when's the Blitz demo CD coming out...?"

:)


(tu) ENAY(Posted 2003) [#35]
It's useful for if you want to rotate a sprite that is using multiple quads. Say if in Cletus you had a tree quad and then multiple leaf quads. Group them together and then pivot it around the centre and have a nice rotating tree. :)


Anthony Flack(Posted 2003) [#36]
yeah, I do have quite a number of objects made from multiple quads. I seem to be favouring multiple quad objects more and more at the moment... ufo objects are made from as many as 15 quads...

I probably should have put in pivot points... I didn't know I was going to make such heavy use of multi-quad objects when I put the system together. The way I'm doing it now, I just rotate the centre of each quad around the object's centre, and then rotate the quad - same effect, not quite so simple.

I think I'll put in pivots when the game is finished, and I hack the routines out for future use.


(tu) ENAY(Posted 2003) [#37]
How are you arranging your multi-quads btw?
If you're offsetting in the X and Y direction from the objects main central X and Y then you won't be able to rotate them by a pivot point later.

When you need to do is offset your quads from the centre in a pivotal point. So instead of X and Y offset you have an angle(0-360) and a distance param. So therefore an angle of 0 and distance of 10 would be the same as an offset of Y=10, and an angle of 45 and distance of 10 would be X=10,Y=10 etc.

All depending on where your 0 degrees is pointing and in which direction your Y is, i doubt it'll be up, but you can always have a general offset of 90/180 degrees depending on where it is.

It's a bit more complex at first setting up your multiquads. But because you have them arranged already in radians. All you have to do is offset all your combined quads Sin and Cos values by a central parameter angle of rotation and they all move around automatically. Simple, well once you get the hang of it that is. :)

What you could also do is add a tilt paramater on top of all that. That goes between 3- and 3 degrees which adjusts as Cletus moves around. So cletus will fractionally lean forwards or backwards as he runs, giving it that 'seemingly more frames of animation' effect.

Also, you could have a wind parameter that is connected to the top two vertices of your flower and tree quads.
This way they could be gently rotated and bent as if they were blowing in the wind. ;)


Anthony Flack(Posted 2003) [#38]
I do use an angle and a distance to place everything :o)
It's all working sweet; it's just slightly more long-winded than if I had've built the pivot point into the main routine.


(tu) ENAY(Posted 2003) [#39]
Ok Anthony I have another question ;)
I noticed in your Cletus game you had a nice background. I'm trying to stretch an image the size of the screen but I get that annoying slowdown you get when the fill rate is full. Or something like that.
I've tried splitting it up into 4 smaller quads but I still get the same slowdown.
How did you manage to get around this, am I on the right lines, should I segment more?


Anthony Flack(Posted 2003) [#40]
Really? Fill rate problems? Bummer.
I don't do anything clever, you know. The background is made up of 4x4 tiles, each 256x256 and on its own surface. Probably 2x2 tiles is a screen full, so it's the same as you.

Sometimes an odd tile doesn't have anything on it, in which case it won't be created, but this is rare. Other tiles, in the middle, don't require a transparency and so don't use it. Apart from that, it's just slapping 'em down. Plus there's the sky and the hills in the background, and I plan to add some more parallax in the middle sometime. Once again, just slapping 'em down - fill rate be damned, if I can do this much in 2d it can bloody well work in 3d too. I guess running at low res helps.

Dunno why it's not working for you. Perhaps you need to firmly say to your card, "if you can do this much in 2d, you can bloody well do it in 3d too."


(tu) ENAY(Posted 2003) [#41]
Well it's odd. I can have a 1000 thousand quads floating about that is paired together are about 30 times bigger than the screen. But as soon as one is stretched to the size of the display I can wave bye bye to processor power.
I'll keep tinkering and see what I find.

I'll try preaching to it later, or I'll threaten it by installing WInXP.


JoeGr(Posted 2003) [#42]
The following will probably seem like an odd/stupid suggestion and I've never heard of anyone else doing this, but in case it happens to be of use to somebody...

If you just rotate the camera 180 degrees around the x-axis (so that its upside down) and place all your quads at a distance in a single x/y plane (use z-order to draw overlapping quads), you can position them all using x- and y- 3d coordinates almost exactly as if you were using sceen coordinates in 2d! Just takes a small amount of fiddling initially to get the distances right so that the 2d/3d coordinates correspond. Any x/y movement you apply is then roughly in pixels too.

Its much simpler than I just made it sound btw. Doesn't solve any of the real problems you get trying to do 2d in 3d (see above), but if you're used to 2d it might help. Or not. :)


Anthony Flack(Posted 2003) [#43]
Hey, now that's actually pretty smart! After years of 2d, it took me a while to get used to the "negative" y axis in 3d.


(tu) ENAY(Posted 2003) [#44]
There's something seriously wrong going on now. If I just have one quad the size of the screen with a texture size of 1x1. I still have herrondous slowdown. What the hell is going on?
It seems impossible to fill the screen up with any type of gfx.
And it's only the equivalent of CLSColor.

> After years of 2d, it took me a while to get
> used to the "negative" y axis in 3d.

You could just cheat and plot your stuff as if it was in Blitz2D and then just translate the Y axis later.


Anthony Flack(Posted 2003) [#45]

What the hell is going on?



Buggered if I know. But my game works okay? Weird. And annoying I'm sure!


JoeGr(Posted 2003) [#46]
Enay, if you figure out why that slowdown happens, be sure to let us know. Its been a problem for me too.

Could it be something to do with the distance between the quads and the camera?


(tu) ENAY(Posted 2003) [#47]
I have no idea yet what's causing it.


John Pickford(Posted 2003) [#48]
I wonder if its a bug when a triangle is clipped on both\all sides of the screen at once? I can imagine that causing bugs.


BlitzSupport(Posted 2003) [#49]
I think it just happens on older/slower cards because they have to 'manually' fill in/texture a huge area that can be changing its size & shape every frame, so it takes longer when bigged-up; totally different to just slapping a fixed-size image on the screen. That's my theory, anyway.


(tu) ENAY(Posted 2003) [#50]
Well I've tried segmenting the image into smaller pieces and also into seperate quads, at 2x2 it still slows down in the same way. Perhaps at 4x4 and 8x8 it might make a difference. I'll have to try that.

But it still baffles me that you can have thousands of the same quad everywhere and it still be faster than one or two big quads. And it's not just that it's a problem in Blitz3D in general. You can gave a FPS style room with clearly 3 walls taking up the entire screen with no slowdown.
Although it's not just quads, it's the same with sprites too. So it must be something to do with the texturing or size of it rather than the object type.


BlitzSupport(Posted 2003) [#51]

But it still baffles me that you can have thousands of the same quad everywhere and it still be faster than one or two big quads.


I guess when they're far away you're only rendering a few tens/hundreds of pixels for each one, whereas for full-screen quads you're doing, eg. 1024 x 768 = 786432.

I can't explain how come a card can fill a full-screen's worth of polys (eg. the 3 walls you mentioned) yet slow down for one poly filling the same total area... must be some sort of exponential slowdown the larger a polygon is...? Then I guess you've got mip-mapping, etc, to take into account (ie. lower-res textures further away)...


(tu) ENAY(Posted 2003) [#52]
Well. I've still not figured it out. Segementing the quads makes it much worse.


BlitzSupport(Posted 2003) [#53]
Weird. How does this run?

http://www.blitzbasic.com/codearcs/codearcs.php?code=177


(tu) ENAY(Posted 2003) [#54]
Didn't see that. I'll give it a twirl.

Heh illegal memory address. No wonder, I've got to add my own pic ;)


BlitzSupport(Posted 2003) [#55]
It's pretty dumb, as it just uses sprites, but just wondering if it'll be affected speed-wise the same as the system you've been trying...


Anthony Flack(Posted 2003) [#56]
Is it scaling a small texture up by a huge amount that's doing it, perhaps?


John Pickford(Posted 2003) [#57]
Texturing is done by sampling one or more texels for every pixel plotted. The size of the texture relative to the size of the triange shouldn't be important. Large textures can theoretically cause bandwidth issues, but I can't see how small textures can be problematic.


(tu) ENAY(Posted 2003) [#58]
Well, incredibly James, using your code it doesn't slow down at all when stretching to full screen. Even at high resolutions.
I'm going to test it some more, I wonder why your code is so amazingly quick. It must be down to how you're initialising the gfx or something.
I'll have to merge it in with my current code and see if the performance increase still remains.
I've changed it a little bit already, added a fullscreen flag to the function so the texture is resized to the screen resolution, so that changing the size doesn't affect the backdrop to screen size ratio.
Finally some light at the end of the tunnel, hopefully :)


Anthony Flack(Posted 2003) [#59]
It's all very odd. I wonder what the cause is?


(tu) ENAY(Posted 2003) [#60]
Actually it doesn't seem to be as effective as I first thought. But it still seems to be slighter better than the way I was doing it. It's still a perplexing phenominen.


Anthony Flack(Posted 2003) [#61]
But my game works okay?


(tu) ENAY(Posted 2003) [#62]
What speed processor do you have Anthony?


Anthony Flack(Posted 2003) [#63]
P4 1.4

pretty speedy.

So does my game work okay for you, or not?


(tu) ENAY(Posted 2003) [#64]
Jessooos. Well I doubt you'd ever notice that slowdown with that machine. I'll have to try cletus again in some higher resolutions, if I still have it on my hd.


Anthony Flack(Posted 2003) [#65]
Really? You think it is a processor issue? I would think it was more of a gfx card issue. And I "only" have a geforce2.

Of course, the recommended res for Cletus is 640x480; I guess fill rate isn't such an issue. What res you running at?


(tu) ENAY(Posted 2003) [#66]
Well I've no idea which one it is, it's got to be one of the two. But if you have a faster processor you won't notice it.

I swear that drawing the image in 2D mode and then sticking the 3D graphics on top would be faster. I'll have to try that. Or at least give the option of both drawing methods. I'm sure it may be faster on some machines either way.


BlitzSupport(Posted 2003) [#67]
That thing of mine probably isn't much use as it scales an image on a 1:1 pixel basis, ie. a 640 x 480 image will still appear 640 x 480 on a 1024 x 768 screen (rather than scaling)...


JoeGr(Posted 2003) [#68]
Neil, are you using the latest version of Blitz?


BlitzSupport(Posted 2003) [#69]

ENAY: I've changed it a little bit already, added a fullscreen flag to the function so the texture is resized to the screen resolution, so that changing the size doesn't affect the backdrop to screen size ratio

...

ME: That thing of mine probably isn't much use as it scales an image on a 1:1 pixel basis, ie. a 640 x 480 image will still appear 640 x 480 on a 1024 x 768 screen (rather than scaling)...


Shows how much attention I was paying... :)


(tu) ENAY(Posted 2003) [#70]
My version of blitz isn't the latest one though. It's the one before the compiler and debugger split. I can't get on with it like that. But I doubt that would make a difference tbh.


Anthony Flack(Posted 2003) [#71]

It's the one before the compiler and debugger split. I can't get on with it like that.



If you install it, you'll see it behaves exactly the same by default.


wedoe(Posted 2003) [#72]
Program your whole game in 2d. When it all works fine and dandy
you still use the 2d GFX for collisions and stuff but you change
the stuff the player actually sees with 3d objects.

It's actually very easy. I used this tecnique on my "Rocket Mission" game.

-norc- did a great 2D in 3D environment snippet som time ago, it's on the code archives area and are better than my amateur routine.