As far as I'm aware of there is 2 "layers" of rendering: the projection set in the scene's camera and the orthographic UI above.
But there is some situations you want another layer. For example, draw a texture with a orthographic projection under the the 3D perspective world.
I have done this before in some of my projects like this prototype: https://dl.dropboxusercontent.com/u/60691076/arc_world/ss/ss_1.jpg
There is a 3D terrain and quads using perspective. The blue to white texture is stationary but it does very well the work of fill the background using few resources.
Other example is draw a skybox of stars in a 3D space game. No matter how much the player moves the skybox always seems to be far away and you can even use a different FOV for a cheap but cool effect.
Or draw a 3D object above the UI: http://i465.photobucket.com/albums/rr19/N0RTHW1ND/MU/Random%20Screens/05_17-17_55-0005.jpg
For that I suppose I should implement my own Renderer::RenderSceneToTarget but the default systems are kinda of locked.
Seems like the Renderer system ins't queried at runtime so I think it should by easy to change but I can't override the Application::CreateDefaultSystems.
Well this is more like a suggestion to make the default systems customizable per project than other thing.
This is a pretty interesting suggestion. We've got a task to add a
SkyboxComponent in the backlog, but this sounds like a more powerful variation on it.
Are there any use cases for this other than skyboxes / sky images? If not, then a specific
SkyImageComponent (For want of a better name) may be better. This is definitely worth considering through.
Allowing the replacement of default systems could also be pretty cool. Over the next few months the Renderer will be getting overhauled and part of that is to allow custom renderers, but we can definitely look into allowing the other default systems to be replaced too.
Draw 3D objects on top of the UI for example, although a 3D drawable component for the widget could work if orthographic projection is fine.
A Skybox/imageComponent should work for most situations if we can stack them together and be able to do things like a scrolling backgrounds with parallax.
Also debug draw.
I have to implement a class to draw debug information of the 2D physics engine.
The update method of the physics world (which is called inside OnFixedUpdate of the physics system) invoke the methods of the draw class whenever something happens.
class DebugDraw : public b2Draw
void DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color);
void DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color);
void DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color);
void DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color);
void DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color);
void DrawTransform(const b2Transform& xf);
void DrawPoint(const b2Vec2& p, float32 size, const b2Color& color);
void DrawString(int x, int y, const char* string, ...);
void DrawString(const b2Vec2& p, const char* string, ...);
void DrawAABB(b2AABB* aabb, const b2Color& color);
I'm still trying to grasp the render system but can I draw a polygon like
void DebugDraw::DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color)
glColor3f(color.r, color.g, color.b);
for (int32 i = 0; i < vertexCount; ++i)
above all the models or sprites?
Directly rendering using OpenGL like this may work, there will be a number of caveats:
- It will only work on Windows as these OpenGL methods don't exist in OpenGL ES 2.0 (the version of OpenGL we use on iOS and Android).
- It will be awkward to get it to actually render. The Renderer clears the screen when rendering begins which is after the Update life cycle event. This means the box2D method
b2World.Step(); will need to be called during the render event rather than Update. Doing this would be quite hacky: you'd need to Create a new RenderComponent and call
Render(), though make sure to only update during the Ambient shader pass.
- It's not future proof, as it's very likely that we'll be either moving to DirectX or changing to OpenGL 3.2 at some point in the next 5-6 months and in both cases this will no longer work.
It would be better to use ChilliSource's rendering methods. Polygons can be generated in the same manor as described in the Creating a Mesh thread.
These draw methods will be happening every frame so each Entity you add for a mesh will need to be removed again at the start of the next frame. Adding and removing entities from the scene is pretty efficient, but this may still be a bit of a performance hit. However, as this is only needed for debugging, that shouldn't be much of a problem. It'll probably help if you do some caching of meshes and entities so they're not being recreated every frame. Something like the following pseudocode could work:
void DebugDraw::DrawPolygon(verts, count, colour)
//check to see if an identical poly already exists in the cache.
//If so, use it, otherwise create and cache a new one.
polyEntity = GetCachedPolyEntity(verts, count, colour)
if (polyEntity == nullptr)
polyEntity = CreatePolyEntity(verts, count, colour)
//Add the debug entity to the scene.
//Remove all debug entities from the scene
//Update the physics world. This will call DrawPolygon and the
//other debug methods
//Debug polygon meshes which are no longer in the scene but are
//still in the cache will build up over time, so clear the cache
//of any entities which are not in use this frame. Remember to
//release the Mesh resource the entities are using too.
To ensure the debug entities are drawn on top just give them a Z depth closer to the Camera.
Strings will be a bit of a pain to render, since CS has no functionality for rendering a text as part of the scene. The easiest way to handle it would be to use
CameraComponent::Project() to find the screen space position of the string and render it as a label. This has the downside of meaning it'll always be rendered on top of all the other debug information, but I doubt that'll be a big issue!
Hope that's helpful!