Hi,
I'm currently working on osg 3.4.0 on windows 7, my shaders are #version 120,
and I'm using #extension GL_ARB_texture_rectangle.
I almost made a shader able to draw a text all along the selected line.
My main goal can be seen here :
http://docs.geoserver.org/stable/en/user/_images/label_underlines.png
where labels like "primary a road" and "non primary A road" are following the
lines.
Maps can be viewed with an ortho2D camera, and the text size needs to be
constant while playing with zoom.
Right now, I apply the shader to the osgText object, and use as uniform the
current zoom scale and the line coords.
After a few days of work, It is almost OK but I have a maybe unsolvable problem
in my vertex fragment :
- broken line is a set of segments
- Each letter is 4 vertices, but each of these vertices are processed -
individually.
- I can tell, for each vertices, which segments to use
- I cannot be sure that all 4 vertices of one letter are tied to the same
segment
As far as I understand shaders, the vertex fragment is called for each
vertices, and there is no way to pass any information from a call to another,
so when I'm compution the position of the upper right corner of a letter, the
position of the upper left corner can't be reached, and that why I am stuck.
I'm not really familliar with shaders (this one is the first I ever created) so
I may be forgetting the obvious, and that's why I need your help !
The only solution I can see is to generate an osgText object for each letter,
but I don't know if it is a good idea...
I may also be able to upgrade to a better shader level if needed, but I don't
even know if it could help me.
Thank you!
Cheers,
Valerian
------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=69823#69823
uniform vec4 lignePos[100]; //coords of the line to follow
uniform int pointsCount; //how many points in the line
uniform float zoom =1;//zoom factor
uniform int horizontalOffset=0;//0 to start at the first point of the line, 100
to start at 100 pixels from the start
uniform int verticalOffset = 10;//vertical offset in px
uniform int charWidth = 20;//should be the average width of a letter
in int gl_VertexID;
void main()
{
bool notFound = true;
float totalLineWidth = 0.0; //total length of the already
float currentWidth = 0.0; //Idem moins le segment courant
int i = 0;
float invZoom = 1.0/zoom;
vec4 origine = vec4(0.0, 0.0, 0.0, 0.0);
mat4 total;
vec4 my_vertex = gl_Vertex;
bool finish = false;
my_vertex.y = gl_Vertex.y+ 1 + charWidth * 0.5;
float deltaVertexX = (gl_Vertex.x - origine.x);
for (int i=0; notFound && i < pointsCount-1; i++)
{
float deltaY = invZoom*(lignePos[i+1].y - lignePos[i].y);
float deltaX = invZoom*(lignePos[i+1].x - lignePos[i].x);
float segmentLenght = sqrt(deltaY*deltaY+deltaX*deltaX);
totalLineWidth += segmentLenght;
if(i == (pointsCount -2)){finish = true;} ;
if((deltaVertexX -charWidth < totalLineWidth) || finish){
//check if the current vertex has to be pinned to the current segment
float sina = deltaY / segmentLenght;
float cosa = deltaX / segmentLenght;
mat4 retourChariot = mat4(
1.0, 0.0, 0.0,
0.0,
0.0, 1.0, 0.0,
0.0,
0.0, 0.0, 1.0,
0.0,
-currentWidth,
0.0, 0.0, 1.0);
mat4 rotation = mat4(cosa, -sina,0.0,0.0,
sina,
cosa,0.0,0.0,
0.0,0.0,1.0,0.0,
0.0,0.0,0.0,1.0);
mat4 translation_segment_start = mat4(
1.0, 0.0, 0.0,
0.0,
0.0, 1.0, 0.0,
0.0,
0.0, 0.0, 1.0,
0.0,
(lignePos[i].x
-lignePos[0].x)*invZoom , (-lignePos[i].y +lignePos[0].y)*invZoom, 0.0, 1.0);
mat4 translation_milieu = mat4(
1.0, 0.0, 0.0,
0.0,
0.0, 1.0, 0.0,
0.0,
0.0, 0.0, 1.0,
0.0,
0.0, 0.0, 0.0,
1.0) ;
total = gl_ModelViewProjectionMatrix *
translation_segment_start*rotation*retourChariot;
gl_Position = total*my_vertex ;
notFound = false;
}
else
{
currentWidth=totalLineWidth;
}
}
if (notFound)
{
gl_Position = total*my_vertex ;
}
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
}
_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org