ARB_window_pos and 2d font display

Hi,

Today I tried to use the ARB_window_pos extension, for placing a texture font on the screen (“2D mode”), but that didn´t work.
Could one explain how to use that extension or can´t I use it here (thought it could be used for “2d overlays” / HUDs)???

OK, this is how I do it at the moment:

// enable 2D mode
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, ScrWidth, 0, ScrHeight);

// disable Z-testing and Z-writes
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);

// set letter position and draw it
glPushMatrix();
glTranslated(iXPos, iYPos, 0);
Draw_a_letter();
glPopMatrix();

// re-enable z-testing and z-writes
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);

// disable 2D mode
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();

The above code is not exactly like I have it in my app, but I´m sure it can be optimized and I guess I can use glWindowPos2iARB somehow … any hints?

Diapolo

[This message has been edited by Diapolo (edited 12-06-2002).]

ARB_window_pos updates the raster position which is used in conjunction with glDrawPixels. You sure you use that in Draw_a_letter()? I don’t see any glRasterPos* calls …

My hope was, that I use the raster position, to set the letter position, without the need to manually switch to a “2D mode” and avoid some state changes (matrix switching and the gluOrtho2d call).

But OK … any hints on how to do that better, than I currently do (even without ARB_window_pos g)?

Diapolo

[This message has been edited by Diapolo (edited 12-06-2002).]

That’s not what I meant.

If you draw your letters as textured primitives (glVertex and friends), neither glRasterPos* nor glWindowPos*ARB will do anything for you.

I kind of suspect that, though I can’t see it in the snippet you posted. Maybe you could clarify?

Raster position is exclusive to glDrawPixels.
You can do this:
glRasterPos2iARB(x,y); //0<x<ScrWidth ; 0<y<ScrHeight
glDrawPixels(letter_size_x,letter_size_y,blablabla,pixel_data_for_this_letter);

edit
Be warned that textured quads usually perform much better with lots of small things to draw (fonts are a perfect example).

[This message has been edited by zeckensack (edited 12-06-2002).]

The draw_a_letter() function calls and draws a series of display lists, that contain a textured triangle strip (quad form) -> font via textured primitives.

So I guess I can forget about the window_pos extension.

But have you got any ideas, how I could speed up my 2D drawing stuff?

Diapolo

Pushing/popping matrices and glTranslated per letter is IMO killing your performance. So you must somehow avoid doing these too often.

For text strings, you can prepare a vertex array large enough to hold a line of text. Say, 80 quads.

struct letter_vertex
{
   float x,y;
   float s,t;
};

letter_vertex font_vertex_array[80*4];

At initialization you can put x/y coords into the array, you don’t need to touch those again.

void init_font_vertices()
{
   for (int i=0;i<80;++i)
   {
      //counter-clockwise quads
      font_vertex_array[4*i].x=
      font_vertex_array[4*i+1].x=i*1.0f;
      font_vertex_array[4*i+2].x=
      font_vertex_array[4*i+3].x=(i+1)*1.0f;

      font_vertex_array[4*i].y=
      font_vertex_array[4*i+3].y=1.0f;
      font_vertex_array[4*i+1].y=
      font_vertex_array[4*i+2].y=0.0f;
   }
}

Next step is to lump your complete charset into one texture and precompute a set of texture coordinates for each letter.

Now you can implement a font::render_string(char* bla) style function that writes the appropriate texture coordinates to the vertex_array and then blasts it out as glDrawArrays(GL_QUADS,0,4*length_of_string);.

Good enough?