Hi everyone!
I'm trying to create objects with an absolute size, independent of the size of the texture I use. For instance, I want every object to be of size 100x100 pixel, even if the textures have different aspect ratios.
There's only a scale parameter in an orxObject. I've also tried to use a phony camera as the ParentCamera, and enabling UseParentSpace = true, but I get:
[2012-07-18 11:05:15] [RENDER] [orxrender.c:orxRender_RenderObject():871] Scaling factor should not be equal to 0. Got (0, 0).
for every frame. The camera I've used is:
[WorldScaler]
FrustrumHeight = 100
FrustrumWidth = 100
FrustumNear = 0.0
FrustumFar = 1.0
Position = (0.0,0.0,0.0)
Zoom = 1.0
and the object I'm using is:
[StoneTop]
Graphic = StoneGraphic
Pivot = center
ParentCamera = WorldScaler
UseParentSpace = true
Scale = (1.0, 1.0, 1.0)
[StoneGraphic]
Texture = images/stone.bmp
Is this phony camera based approach possible / a good practice? Is there a better way to achieve this?
Thanks a billion!
Comments
Interesting and clever use of a camera to achieve a global fixed size from config.
It's currently not working because of a typo (Frustrum) for the first two values.
Now I'm curious to why you need an absolute size no matter which texture is used.
Objects don't actually have a global size.
What I mean by that is that size is used for 2 optional aspects of objects:
- if it has a body, that body will have parts that have their own size/position
- if it has a graphic, the size will be the graphic's one
What objects will always have though, is a transform node in the scene graph hierarchy (called orxFRAME here) that contains position, rotation and scale in both the parent local space and the world global one.
Hence my question about the use case of a fized "size".
If you want to display a given texture stretched on a 100x100 square, you have two options:
- either you know the texture size beforehand, when writing the config, and you can apply the appropriate scale that will result in a 100x100 "size"
- either you don't know the texture size for sure (or you're going to change it during runtime), in that case you can get the size of the object (which is the size of the graphic, really) and apply the appropriate scale to get a 100x100 final "size".
But again, all this depends on the actual use case you have as there might be better options out there.
Thanks a lot for your comprehensive answer. I'll be glad to tell you what I'm planning to do with fixed size textures
You can already see in the screenshot that the tiles can have different textures. The walls will eventually also have different textures. The map of the game is read from a text file that looks like this:
I know Scroll comes with a map editor, but I already have the parser for this... (I'll check ScrollEd as soon as possible regardless)
I have fixed size tiles in the game, so the objects have to be fixed size. I don't want to bother with checking the texture size, and scaling accordingly, because I'll make the game such that, using purely a config file you should be able to bind an ascii character on the map, to a new floor/wall/general purpose in-game object, so I want this to be quite simple.
I feel so stupid for spending hours, while I was 2 typos away from the solution from the beginning :S
I have two related questions at this point. 1) Do you think I'll have to bend ORX too much to achieve this type of a game, since the game world is sort of 2.5D? 2) When I load a texture in ORX, do you build and use the 2DMipMaps?
The more I look at ORX source code, the more I appreciate it
Cheers!
Thanks for the details!
Even with having ScrollEd, I like text-based approach for tile-based generation, edition is usually much faster.
If you don't want to store separate files (and maybe benefit of orx's encryption in the end for preventing users from "cheating"), you can store your text blob in a config value, wrapped in " " to keep the new lines" and get its content with a simple call to orxConfig_GetString();
My approach would be to use spritesheets (aka texture atlas) and enforce the tile size there using the config properties TextureOrigin & TextureSize in the graphics for delimiting the tiles.
If you want to use tiles with actually stretched graphics instead of fixed size ones (which might not look as good as with texture resulting in a 1:1 ratio), I'd then update the scale when objects are created, to correct the end size.
That being said, if your levels are very big and contains thousands and thousands of tiles, having one object per tile might get costly in the rendering process (there's not partitioner yet).
To avoid that cost there are 2 easy approaches:
- only create enough tiles to cover the camera size + 1 extra on each direction for scrolling purpose and update the orxGRAPHIC of the tiles based on the current camera position. The tiles can also be all grouped under a single parent which makes them very easy to move around to compensate for the scrolling.
- use a single object that covers the whole camera size using a dummy texture (the config keyword "pixel" works as a default 1x1 white texture and is handy for that) and then do custom rendering to display its content based on the camera position and your loaded level (you can easily blit rectangles using the orxDisplay API for convenience). In that case, one alternative of doing a custom rendering would be to attach a shader instead and doing all the rendering in it based on the visible tiles and their ID.
You can look at sausage's similar approach for his own game too: http://orx-project.org/wiki/en/orx/tutorials/community/sausage/semi-dynamic_objects_and_level_mapping
I think it happened at least once to all of us at some point!
If you use the open source editor Notepad++, jim created and maintains a very handy syntax highlighter/completion for it for orx config files: https://forum.orx-project.org/discussion/3158
Not finding a config value is an accepted behavior, however trying to access a value as a type that it cannot be converted to will also send a orxCONFIG_EVENT_INVALID event.
Here's an example that would trigger such event:
I don't think you need much bending, if at all, depending on your requirements you can do it in a very straightforward way (like creating fixed size orxGRAPHIC from spritesheets), or with not much effort (resizing objects after creation and/or using the aforementioned rendering tricks).
Thanks, it's much appreciated!
There's no mipmap creation by default when generating the OpenGL textures.
Usually mipmap transitions for objects perpendicularly facing the camera (which is always our case in 2D) is pretty noticeable and not very pretty. I'd recommend using filtering (called smoothing in orx) or even some AA of some sort instead if the goal was to get rid of visual artifacts coming from non 1:1 display ratio.
If the goal is different (like performance or memory concerns), let me know and I'll see what we can do without being too intrusive.
you get very smooth transitions while zooming in and out.
On a desktop, I can't imagine AA or smoothing causing a serious memory or performance problem in a 2D game, but on Android, this might possibly be an issue. I'd appreciate if 2DMipMaps were an option, but it doesn't have high priority really. Since it took one line in SDL, I thought maybe it wouldn't be that intrusive in ORX either (though now I realize having to change the Android and iOS sections as well), but if it is, just put it at the end of a long TODO list
Big thanks are in order as usual
Out of curiosity, in your SDL implementation, how did you generate them? With straight OpenGL code or with some SDL encapsulation? I've only used SDL up to 1.2.x and didn't remember any consequent OpenGL wrapping beside some of the very basics.
I'll add it to my TODO list which isn't that long but has some hefty features down the road, so I'll most likely do that as a pick-up task someday when I feel bored (if that ever happens
These three lines worked like a charm. You can check how smooth zooming is in the SDL implementation:
Whenever you feel like it
It's been a while now, I have got busy with my final year class and project
Regarding mipmap generation I want to say, for 2D games it is not absolute necessary, also mipmap works only when a image is scaled down, it does not work while zooming an image or stretching it. Mipmapped texture requires more memory, at least 33% more memory than normal texture. But mipmapped texture is helpful if a texture is frequently scaled up and down.
So, if one has to generate mipmap for a texture there are few ways.
Use either GL_GENERATE_MIPMAP (opengl 1.4 or above) or use glGenerateMipmap (opengl 3.0 or above). Using gluBuild2DMipmaps is not recommended to use. More info about mipmap generation can be found here
http://www.g-truc.net/post-0256.html
And just as an additional info, the way to go on OpenGL ES is to use glGenerateMipmap.