I have subclassed CCSprite into FMObject as the base class of my game objects. This class creates a b2Body and uses a CCSpriteBatchNode. Problem is, making multiple copies of say FMSpaceShip will make multiple CCSpriteBatchNode objects that all use the same png. Will this result in the png being loaded again and again, or will there be some optimisation here?
Yes, you can count on Cocos2D internal cache optimization there. The texture will get loaded only once in the CCTextureCache, and will be referenced by each of the batch nodes, using reference counting.
That said, there should be no need to create a batch node per sprite, if i am reading your description correctly. You should consider instead to create the batch node once externally to your CCSprite class, then have your sprites (or derived FMSpaceShips) use that single batch node for rendering.
In some cases, it is still useful to create several batch nodes - For instance when you want them to render at different zOrder (say, you have clouds sprites that always need to render behind your main space ship sprites).
Related
I have written an entity component system for my game (C++). I have then refactored my render system to work with Entities / RenderComponents rather than some virtual drawable interface. Their are some classes for which I don't think it makes too much sense to force them to be a component. One of those classes is the map.
My map class consists of a tiled terrain class and some other data (not important). The tiled terrain class manages multiple layers in form of (what is at the moment) the TiledTerrainLayer class. Before refactoring the render system I simply inherited from Drawable and Transformable to enable this class to be drawn by the render system. Now it is required to be an entity with at least a TransformComponent and some RenderComponent.
Now, the TiledTerrainLayerRenderComponent should really only own the vertices and a reference of the texture and maybe a flag for whether it has been created yet. The TiledTerrainComponent would then own the list of tile indecies as well as tile and map size.
Now my problem is that when I set a tile (using something like a SetTile(size_t tileIndex, const Position & pos) method, I also have to update texture coordinates of the vertex array.
I am generally fine with one component requiring another component. For example the SpriteRenderComponent requires a TransformComponent and I am also fine with one component accessing the information of another. E.g. the GetBoundingBox() method uses the position of the transform component.
What I want to avoid is two components 'cross-referencing' each other like it would be the case with the TiledTerrainComponent (TTC) and TiledTerrainRenderComponent. (TTRC) (The TTRC gets the TTC's tileIndexList to create itself and the TTC calls the TTRC's UpdateVertices() method when its SetTile() method is called.
Lastly, I am aware that components should mainly be data. I have only added methods that directly get or modify that data such as SetTile() or GetTexture(). Would a system be viable in the case described above and if yes how would it look like?
It sounds like all you need here is a Dirty Flag.
When you change tile index, size, or other properties on your Tiled Terrain, you do not immediately phone the Tiled Renderer to update its vertices (after all, you might have many tile updates yet to come this frame — it could be wasteful to recalculate your vertices every time)
Instead, the Tiled Terrain renderer just sets its internal hasBeenModifiedSinceLastUse flag to true. It doesn't need to know about the Renderer at all.
Next, when updating your Tiled Renderer just prior to drawing, you have it ask its Tiled Terrain whether it's been updated since the last draw (you could even query a list of updates if you want to target the changes). If so, you update the vertices in one big batch, for better code & data locality.
In the process, you reset the modified flag so that if there are no updates on subsequent frames you can re-use the last generated set of vertices as-is.
Now your dependency points only one way — the renderer depends on the tile data, but the tile data has no knowledge of the rendering apart from maintaining its flag.
I developed a game with SDL2.00 and c++. I seemed to be having memory and CPU issues. CPU usage goes up to 40% and memory usage goes up by 5mg a second.
So I think the reason is the way Im handling Textures\Sprites.
My question is should I create a different/new sprite/texture for every instance ?
For example, I have a class called Enemy which contains all the variable and methods related to enemy monsters such as HP, damage, location , image(Texture) etc. This class contains its own texture to be rendered onto the renderer.
Is this the right way? Or should I create a Sprite/Texture for all the images before hand and render them as needed?
and I'm wondering if this will render two different images onto the renderer:
RenderCopy(renderer, image);
image->SetPosition(X,Y);
RenderCopy(renderer,image);
or is it going to move the sprite to the new position?
I think my issues are caused my overloading the renderer and/or having too many textures being loaded.
Let me know what you think .
OpenGL is not a scene graph. It's a drawing API. So everytime you're allocating a new texture you're creating a new data object that consumes memory. You should reuse and share resources where possible.
My question is should I create a different/new sprite/texture for
every instance ?
No, not unless every instance of the sprite uses different textures, otherwise you should reuse them, ie only load them once and store a pointer to the texture the sprite uses.
and I'm wondering if this will render two different images onto the
renderer:
RenderCopy(renderer, image);
image->SetPosition(X,Y);
RenderCopy(renderer,image);
or is it going to move the sprite to the new position?
This will copy the image twice. First at the old position and then at the new. What you will get is a trailing image. You should probably either clear the previous position or render the background at that position (or whatever should be there).
I am calling setTexture:withRect: on a particle emitter... My question is, is there any way I can give multiple rects so that the particles can be comprised of random sprites? Or is the only way to accomplish this to use multiple emitters?
I thought if there was a way to actually get the collection of particles that are being generated, then I could loop over them and set their rect, or even color properties, but in the cocos2d docs, I see no way to get individual particle objects...... Is there any way to do this?
If you want emitted particles to have different images, you can make sprite sheet of your particle images and subclass CCParticleSystemQuad overriding initTexCoordsWithRect: method so that instead of using same frame for very particle it uses different frames for different particles.
See here for example of such particle system using bitmap font. Using the same idea, I made CCParticleSystemQuad subclass which uses CCSpriteFrameCache to get frame information.
No, you can't access or modify individual particles.
If you want random sprites, simply run multiple particle systems with each using a different texture.
I want to know if there is any benefiting caching a sprite sheet and accessing the sprite by frame without using the CCSpriteBatchNode?
In some parts of my game the sprite batch node is useful because there is a lot on the screen, however on another part its not, because there are just a few things, and there are requirements for layers so CCSpriteBatchNode wouldn't be useful. However, for the sake of consistency I would like to use Sprite Sheets for all my sprites, and so was beginning to wonder if I would still receive any benefit from it? (Or worse that it could some how be slower...)
There is defiantly a benefit to putting all your sprites into a texture atlas or sprite sheet as you called it. Textures are stored in memory in power of 2 dimensions. So if you have a sprite that is 129px by 132px it is stored in memory as 256px by 256px which is the nearest power of 2 size. If you have many sprites that is quite a lot of extra memory used up.
By using a texture atlas you only have one texture in memory and then it pulls the pieces out of it that it needs for your sprites. These sprites can be whatever size you want without having to worry about power of 2 sizes.
You can read more details about it on this tutorial
http://www.raywenderlich.com/2361/how-to-create-and-optimize-sprite-sheets-in-cocos2d-with-texture-packer-and-pixel-formats
I'm new to the Qt3D module and am currently writing a game in Qt5/C++ using Qt3D. This question is about "Am I on the correct path?" or "Can you give me some advice on...".
The scene of the game has a static part (the "world") and some objects (buildings and movable units). Some of the buildings might be animated in the future, but most of them are very static (but of course destructible).
I divide the quesion into two parts: How to handle copies of the same model placed at different positions in the scene and how to manage the scene as a whole in the viewer class.
Redundant objects in the scene:
Of course the objects share the same library of buildings / movable units, so it would be dumb to upload the models for these objects to the graphics card for every instance of such a unit. I read through the documentation of QGLSceneNode, from which I guess that it is designed to share the same QGeometryData among multiple scene nodes, but apply different transformations in order to place the objects at different positions in my scene. Sharing the same QGLSceneNode for all instances of a building would be the wrong way, I guess.
I currently have a unit "library class" telling me the properties of each type of building / movable unit, among other things the geometry including textures. Now, I'd provide a QGeometryData for each building in this library class, which is uploaded on the loading procedure of the game (if I decide to do this for all buildings at startup...).
When creating a new instance of a unit, I'd now create a new QGLSceneNode, request the QGeometryData (which is explicitly shared) from the library and set it on the node. Then I set the transformation for this new node and put it in my scene. This leads us to the second part of my question:
Manage the scene as a whole:
My "scene" currently is neither a QGLSceneNode nor a QGLAbstractScene, but a struct of some QGLSceneNodes, one for each object (or collection of objects) in the scene. I see three approaches:
My current approach, but I guess it's "the wrong way".
The composition: Putting everything as child nodes in one root QGLSceneNode. This seemed the correct way for me, until I realized that it is very difficult to access specific nodes in such a composition. But when would I even need to access such "specific" nodes? Most operations require to take all nodes into account (rendering them, updating positions for animations), or even operate on a signal-slot-basis so I even don't need to find the nodes manually at all. For example, animations can be done using QPropertyAnimations. Acting on events can also be done by connecting a QObject in the game engine core (all buildings are QObjects in the engine's core part) with the corresponding QGLSceneNode.
But this approach has another downside: During rendering, I might need to change some properties of the QGLPainter. I'm not sure which properties I need to change, this is because I don't know Qt3D enough and can't guess what can be done without changing the properties (for example: using a specific shader to render a specific scene node).
Then I found QGLAbstractScene, but I can't see the advantages when comparing with the two solutions above, since I can't define the rendering process in the scene. But maybe it's not the correct location where to define it?
Which is the best approach to manage such a scene in Qt3D?
With "best" I mean: What am I going to do wrong? What can I do better? What other things should I take into account? Have I overlooked anything important in the Qt3D library?