A few questions...

Started by GP, April 19, 2003, 09:29:15 AM

Previous topic - Next topic

GP

Hello. I'm a student and a game progammer, I am currently planning to make a 3D online tabletop wargame simulation. I recently found jPCT and I must say it's really impressive, it's an API you can effectively use from day 1.

I have a few questions about 2D blitting. In the game, one has to display 2D info on a unit (status icons, unit name, morale/energy bars), as well as the classical sidebar a la Warcraft. Reading the documentation, I see that there are two ways to do that : with a Texture, and with an array (which is not advised for performance). Problem is, while the status icons can be just loaded from file and used, other elements can change. How do I display things like a status bar or text? The Texture class only has constructors for loading them from a file, not for modifying them on the fly (unless I write the new image to disk!). Is the slow method the only one? I remember that passing ints to OpenGL was painfully slow when I tried it... Isn't it a way to get, for example, an Image from the Texture and have an update(Image i) to change the texture after altering the Image?

I don't know if I was clear enough... this is my first real 3D project!
Thank you for your attention

GP

EgonOlsen

The int[]-method is only slower when using OpenGL. When using software rendering, both methods should perform the same. Another way to do it, is to use the "texture-method" and implement your output-code using ITextureEffect. By implementing this interface in a class of your own, you have direct access to the texture's binary data. Problem with this is, that for OpenGL, a texture upload has to take place everytime the texture-effect has been applied. The good thing with this is, that the upload takes place only after the texture has been changed and not for every blit. Another way would be to use the int[]-method and set "glUseIgnorantBlits" in Config to "true"...but be carefull with this, because it prevents any texture-upload from any int[] until you set it back to false.
I suggest to go with the ITextureEffect-approach and see how it performs.
Anyway, i suggest to precompute as much as possible to avoid costly conversions at runtime.

GP

Thanks for the reply :D  So I have to apply a texture effect whenever the user selects a new unit, I guess this is acceptable.

One more question : how do I calculate the 2D screen position of a 3D point/polygon in the worldspace? I think I have seen methods that do the opposite, i.e. that take a 2D point and return the picked polygon. If such a method does not exist, I think I'll have to do the math myself using tan's and sin's... would you have any suggestions?

Thanks again,
GP

EgonOlsen

Quote from: "GP"If such a method does not exist, I think I'll have to do the math myself using tan's and sin's... would you have any suggestions?
That won't work (and especially not by using trigonometric functions), because you would need some internal Camera-stuff for doing it. It shouldn't be a problem to add such a method for you to jPCT but the question is: What should it project into 2d? I can imagine the center of an Object3D, the rotation pivot (less likely to be usefull) or any point you throw at the method. But this would have to be a point in world-space, while the center is in object-space. Or in other words: Using the center takes the objects' transformations into account while using a point in world-space can't. I may add both methods as well. What do you want to use the method for exactly?

GP

Well, let's say I have a unit of 20 warriors. In my game they will just be 20 boxes with textures on their front and back faces on 20 bases (just like old tabletop games like D&D, but I'm getting off-topic). I want the player to be able, holding Shift or Caps Lock, for example, to display information over the units, under the form of 2D icons (I could do it with 3D objects hovering on the unit, but they wouldn't be well visible from every angle), for example an icon if the unit is fleeing.

So what I need is a method like : public Point get2DPosition(Camera c, 3DObject targetObject), (with -1 or something representing offscreen positions), for determining object center in the scene. Alternatively, any point in the world could be fine... I'm moving objects with only "rotate" and "translate" and not by "setOrigin", does that mean I can treat object- and world-coordinates as the same thing?

Ah, I was forgetting! A simple, non-vital thing this time  :) I'm implementing the sidebar blitting it from texture. It covers a quarter of the screen, wasting quite a lot of processing time... I remember that in OpenGL you can specify a subset of the frame buffer for rendering (i.e. a smaller rectangle), this way one can display a static image without performance loss. Is that possible to specify, at least in the OpenGL hardware renderer?

Thanks  :P I think these are quite handy features for many 3d games!

GP

EgonOlsen

Quote from: "GP"Well, let's say I have a unit of 20 warriors. In my game they will just be 20 boxes with textures on their front and back faces on 20 bases (just like old tabletop games like D&D, but I'm getting off-topic). I want the player to be able, holding Shift or Caps Lock, for example, to display information over the units, under the form of 2D icons (I could do it with 3D objects hovering on the unit, but they wouldn't be well visible from every angle), for example an icon if the unit is fleeing.

I see...instead of doing 2D blitting, it is also possible to use billboarded 3d objects. But that may be overkill. Doing it the 2D way should be a fine solution.

Quote from: "GP"So what I need is a method like : public Point get2DPosition(Camera c, 3DObject targetObject), (with -1 or something representing offscreen positions), for determining object center in the scene. Alternatively, any point in the world could be fine...
I think i'll head for the "center"-way of doing it. It's easier to understand for "non-3ders".

Quote from: "GP"I'm moving objects with only "rotate" and "translate" and not by "setOrigin", does that mean I can treat object- and world-coordinates as the same thing?
No, the object-space never changes (unless you are using the unfamous rotateMesh() and translateMesh() methods). However, a center of (0,0,0) will be virtually translated to (0+xt,0+yt,0+zt) if you translate the object by (xt,yt,zt)...so if your object's center is at the origin (in object-space) and you are doing translations only (or the rotation pivot is at the origin too), then your approach should work, but i like the idea of directly projecting the center more.

Quote from: "GP"Ah, I was forgetting! A simple, non-vital thing this time  :) I'm implementing the sidebar blitting it from texture. It covers a quarter of the screen, wasting quite a lot of processing time... I remember that in OpenGL you can specify a subset of the frame buffer for rendering (i.e. a smaller rectangle), this way one can display a static image without performance loss. Is that possible to specify, at least in the OpenGL hardware renderer?
I'm not sure about that...blitting in OpenGL is actually done using textured quads, so limiting the output for rendering would kill your blitted bitmap too. For the software renderer, it may be possible. I'll think about it later.

I hope to release a version featuring the projection-thingy within the next few days.

EgonOlsen

0.88 has been released. The projection-methods you requested can be found in Interact2D. Please let me know, if this helps you.

GP

Thanks! I already downloaded it and I'll try it tomorrow. Hehe, I'll post a screenshot as soon as possible.

GP

GP

It works great! It's already displaying the unit's name on it. Thanks, since miniatures are boxes, they are pretty confusing when seen from above; putting their name as a bitmap on them makes everything much cleaner.

Now my friends and I just have to actually make the game...  8) I'll let you know as the thing progresses.

GP

EgonOlsen

Two things i've forgotten to mention:

1.) Don't use textures with a height other than a power of 2 when doing OpenGL (not for blitting either). OpenGL doesn't support this and jPCT has to do a conversion run on every texture. This is very slow, because it's just a naively implemented better-than-an-exception-method. In addition, the converted textures are not very pretty...

2.) I'll try to speed up texture upload performance a little bit for 0.89. The problem is, that i can't do much about it because most of the time is wasted inside OpenGL and the video card's driver, not in jPCT. I already tried some things and got a 50% increase (but we are talking about 2fps compared to 3fps after the optimization)....anyway, i'll add it to the next release.

GP

Quote from: "EgonOlsen"Two things i've forgotten to mention:

1.) Don't use textures with a height other than a power of 2 when doing OpenGL (not for blitting either). OpenGL doesn't support this and jPCT has to do a conversion run on every texture. This is very slow, because it's just a naively implemented better-than-an-exception-method. In addition, the converted textures are not very pretty...

I had read about it... no problem, all the icons/stuff will be kept in a single texture of legal size.

Quote from: "EgonOlsen"
2.) I'll try to speed up texture upload performance a little bit for 0.89. The problem is, that i can't do much about it because most of the time is wasted inside OpenGL and the video card's driver, not in jPCT. I already tried some things and got a 50% increase (but we are talking about 2fps compared to 3fps after the optimization)....anyway, i'll add it to the next release.

That's great! In fact, most 3D games actually need to display 2D stuff one way or another, whether it's a cockpit, a sidebar, or a weapon list for first person shooters, so this is quite important in my opinion. As to performance, I haven't tried hardware rendering yet, mainly because I'm working on a PowerMac and LWJGL doesn't support it yet. However the machine can run it decently at 800x600 with 200x600 texture blitting (which had no visible effect on performance when added), even if I disabled texel filtering. The machine is quite high-end (667 MHz RISC) and there are only about 600 triangles in the world, but it's encouraging for the OpenGL software renderer (i.e. it's playable, nearly 15 fps unless zooming out a lot, 8-10 fps in that case). I'll try the hardware rendering later, on another Win laptop, but the development (at least my part of it) takes place here. We might also decide to support lower resolutions for the sake of software rendering...

EgonOlsen

Make sure to use software rendering in MODE_OPENGL to ensure that soft- and hardware will almost look the same. The reason is, that jPCT's default rendering mode is software legacy which uses a different lighting model that OpenGL doesn't support (and that's sad because i think that it, may it be realistic or not, produces better results than the standard lighting OpenGL supports). Have a look at the terrain example's sources to see what i mean. Or, if you are already doing this, ignore my post... :wink:

BTW: Texel filtering shouldn't be much slower than not using it...if it's noticable at all. I've put a lot of affords into optimizing the software renderer may it be with or without filtering.

GP

Thanks for everything... maybe I noticed a performance increase when disabling filtering because I'm using a small texture stretched on a relatively large plane (it's the "wood" texture from the bounce example)...

After a few tests, there is one minor thing I could improve with the sidebar. As I told earlier, it covers a quarter of the screen, and this brings a "convergence" problem : perspective converges at the middle point of the frame buffer, which is not the center of the playing area, but a bit on its left. I don't know if I'm clear enough, it's about like if you were watching the scene with a patch partially covering your left eye (which is what is actually happening). So, when zooming in/out, the camera will zoom to a different point than the player is expecting, because the player will naturally believe the "gaming area" is his real FOV. I think that playing with matrix coefficients might help with it, am I wrong?

Bye
GP

EgonOlsen

Before the days of the OpenGL renderer, this would have been rather simple. You can access the Image-instance that holds the pixels generated by the software renderer and blit it into whatever and whereever you want. But though it's possible, it's not very convenient. Therefor, i once added an option to jPCT (that isn't available via the API at the moment) that "shifts" the projected 2D coordinates in any direction, because this is, what's actually needed to avoid the problem: If your sidebar is for example 100 pixels, you would like to start the rendering not at x=0 but at x=100. This is no problem with the software renderer, because i have full access to every pixel and can do whatever i want to. However, i didn't find a working way to tell OpenGL not to start rendering at (0,0) but somewhere else. That's why the option to do this is not publicly available.
Manipulating the matrices doesn't help btw, because what you want is basically a 2D operation...just tell the stupid polygon to start at (x+a,y+b) instead of (x,y) on screen (the position in 3D wouldn't change). I just don't know how to achieve this in OpenGL ATM...maybe i'll have a closer look again one day (glViewport comes to mind...but i tried that once and it failed somehow...well, maybe i'll give it a shot again...). For now, i suggest to take it as feature. Maybe you want to make the sidebar removable... :wink:

Edit: About the filtering: Maybe it hurts performance on PowerPC's and their VMs more than it does on Intel...can't wait to see what happens when LWJGL comes out for Mac (byteorder anyone... :roll: ?).

Edit2: I forgot to mention this in the docs of 0.88: The coords the projectCenter...stuff returns are backbuffer coords, i.e. if you are using 1.5 or 2 times oversampling, you have to divide them by 1.5 (or 2) to get the actual coords of the frontbuffer (for blitting and stuff). 0.89's docs will mention this.

EgonOlsen

Update on the sidebar problem: I've uploaded a pre-release of 0.89 which has an option included to apply an offset to the viewport and it hopefully works in software as well as in OpenGL. There are two new configuration options in Config called viewportOffsetX and viewportOffsetY. The offset is in fact a factor and independent of the resolution...have a look at the docs for futher detail about these settings.
This should also help to reduce the amount of polygons overdrawn by the sidebar anyway, so it should be a little faster too.
The version can (only) be download here: *removed*...the normal distribution contains this option now.
Let me know, if it helps.

Edit: Fixed the link...