Disclaimer: I am not familiar with Ogre3D.
You can manage to do the effect you want via shaders.
Since I am only familiar with GLSL I will be using that...
First off all, whatever changes from quad to quad (for example the speed of the vehicle) you need to pass it as an attribute. I will assume we pass four such properties (based on the example image) and they dictate the intensity of the colors of the bands.
Note: I say quad, but there is no difference if you are using triangle primitives. I fact I tested this with triangles.
Now, how does the shader knows the positions to place those colors? Well, you need to pass an additional attribute for that. Sure, it can be standard texture coordinates, but it does not need to be. It makes no difference.
With that said, our vextex shader will be doing passthrough, so we can use the properties in the fragment shader:
#version 330
layout (location = 0) in vec3 VertexPosition;
layout (location = 1) in float prop1;
layout (location = 2) in float prop2;
layout (location = 3) in float prop3;
layout (location = 4) in float prop4;
layout (location = 5) in float pos;
smooth out float vprop1;
smooth out float vprop2;
smooth out float vprop3;
smooth out float vprop4;
smooth out float vpos;
void main()
{
vprop1 = prop1;
vprop2 = prop2;
vprop3 = prop3;
vprop4 = prop4;
vpos = pos;
gl_Position = vec4(VertexPosition, 1.0f);
}
OpenGl will interpolate the values for us. Thus, if we pass pos=0
on one side of the quad and pos=1
on the other, we get a gradient. That is what we will be using that on the fragment shader to place the colors.
The other attributes (prop1
, prop2
, prop3
, prop4
) are going to tell the intensity of the colors. The code I wrote for that uses a vec4
to specify the color of each band and use scalar product.
Notice also that - with this shader code - OpenGL will also interpolate the values of the other attributes. This means that if you set the old values on the bottom of the quad and the new ones on the top you get a nice gradient.
This is the fragment shader I wrote for this:
#version 330
smooth in float vprop1;
smooth in float vprop2;
smooth in float vprop3;
smooth in float vprop4;
smooth in float vpos;
out vec4 FragColor;
void main()
{
vec4 s =
((step(0.75, vpos) - step(1.00, vpos)) * vec4(0.0, 1.0, 1.0, 0.5) * vprop1)
+ ((step(0.50, vpos) - step(0.75, vpos)) * vec4(0.0, 0.0, 1.0, 0.5) * vprop2)
+ ((step(0.25, vpos) - step(0.50, vpos)) * vec4(0.0, 1.0, 0.0, 0.5) * vprop3)
+ ((step(0.00, vpos) - step(0.25, vpos)) * vec4(1.0, 1.0, 0.0, 0.5) * vprop4);
FragColor = s;
}
Here the step
function will give me hard edges for the colors. ((step(0.75, vpos) - step(1.00, vpos))
will be 1
when vpos
is in the range from 0.75
to 1.00
, and it will be 0
otherwise. Similarly happens with the other terms. Yes, I have extra zeroes after the comma, for readability.
The code above puts alpha on 0.5
. Use whatever you need.
Aside from that, you are probably better off using an array to store your vertex, and use it as a circular buffer (once you get to the end, you start overwriting at the start). Using Triangles or Quads primitive type (but not strips or fans). Doing that you know it won't grow. I do not know how permisive Ogre3D is about that.
As, as I said, you can animate the quads fading away. You can add another attribute for the time when the quad was created, and pass the current time as a uniform
to the shaders (Note: you do not need passthrough uniforms, you can use them directly in the fragment shader). That way the fragment shader knows how much time has passed since the Quad was created, and use that for setting alpha. Figure out what do you need to do on Ogre3D to get alpha blending working properly for the transparency effect.