[2.1] Rendering simple 2D shapes.

Discussion area about developing with Ogre-Next (2.1, 2.2 and beyond)


Post Reply
Jay721
Halfling
Posts: 62
Joined: Mon Jan 29, 2018 8:19 am

[2.1] Rendering simple 2D shapes.

Post by Jay721 »

Hi all,

I'm looking into rendering things like rectangles, circles and text on the user's screen. (potentially hundreds of shapes)

I took a similar approach to farso (discussed by others here), where essentially the shapes are drawn onto a SDL_Surface before being blited to an Ogre texture. This approach is too slow to me, as I'm needing to call

Code: Select all

blitFromMemory
every frame, on a texture that is 2048x1024 - it was taking up to 250ms!

Now I've drawn rectangles without the texture/blitting part, but I'm not sure about:
- How to change the vertices of the VAO on the fly
- Would this be a good approach to resizing/re-positioning shapes?
- Can you draw circles without the SDL/Texture/blitting, would I have to create a massive list of vertices?
- How would I draw the text?
- Is there a better approach that I'm missing.

I've tried looking into how MyGUI draws, but couldn't really gather any insights other than there's no SDL_surfaces.

Thanks
Hrenli
Halfling
Posts: 73
Joined: Tue Jun 14, 2016 12:26 pm
x 19

Re: [2.1] Rendering simple 2D shapes.

Post by Hrenli »

I also did look at farso for GUI inspiration and also did not like "render everything to texture first" approach. Can't say what is the best way to find the balance between how much you want to do as geometry and how much as texture though... But IMO at least with text it's definitely better to play with vertexes/UV coordinates of a set of rectangles (one per glyph) instead of having one rectangle per whole text thing and then render everything to it's texture every time you wan to change it.

I'd recommend to look at dynamic geometry samples for examples on how to change VAO vertexes on the fly and to source code of TextAreaOverlayElement (it is in overlay component) for an example of rendering text as two triangles per glyph using Ogre fonts.
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: [2.1] Rendering simple 2D shapes.

Post by dark_sylinc »

The first problem is how dynamic your rendering is. Do you need to render a few circles? Or do you need complex vector art that changes all the time?

If it's the latter, you're screwed. Unless you develop a very advanced vector rendering solution like Slug, you would have to rely on a CPU vector rasterization library, then copy the results to a texture and draw that as a quad.

If it's the former, you can render:
  1. Render everything as chained triangles. The vertex count could get humongous. Not recommended.
  2. Render everything as a quad, displaying either a texture or a special shader. It may waste fill rate due to the empty spaces (eg. a circle inside a rectangle)
  3. Render everything as a simplified geometry, with a texture or a special texture. This is the same as the above, but e.g. instead of rendering a circle as a quad, you render a circle as an hexagon, thus less waste. If you use many triangles, you get the small triangle problem, if you use too few you waste a lot of empty space.
Regarding "texture" vs "special shader", you can rely on a texture (which may need a lot of resolution, consumes memory) or you can use a simple shader.

For example a circle can be rendered with:

Code: Select all

//Non-smooth
float4 circle(float2 p, float2 center, float radius)
{
	return length(p) - r;
}

//Smooth
float4 circle(float2 p, float2 center, float radius)
{
	return lerp(float4(1,1,1,0), float4(1,0,0,1), smoothstep(radius + 0.005, radius - 0.005, length(p - center)));
}
Example 1 in Shadertoy, Example 2. Iñigo has a useful reference on 2D drawing functions for basic shapes.

The advantage of using a shader is that it adapts to all resolution without consuming memory, and should be very fast, but it requires more knowledge and getting familiar with more advanced features. You would have to either use v1 low level materials to setup your shaders (more user friendly and easier to start with, but may get difficult to manage if you have many basic shapes and settings), or get familiar with writing a custom Hlms implementation.

As to how to change the vertices of the VAO on the fly, see DynamicGeometry and CustomRenderable samples.
Post Reply