using glViewport

Hi to everyone, I’m trying to build some kind of GUI for my small geometry viewer nad trying to understand how to do it in the most efficient way. I attach a picture of what I’m going to do something like this:

[ATTACH=CONFIG]1549[/ATTACH]

That is, text must begin always at the point with coordinates (5,5) pixels from the left bottom corner, no matter how the window is reshaped.

For now, I’ve found the only one solution to do this:


GLint Width = 600, Height = 600;
GLsizei CurrentWidth = 960, CurrentHeight = 600;

void display(void)
{
    // Drawing geometry
    glClear(GL_COLOR_BUFFER_BIT);
    glDrawArrays(GL_LINES, 0, 12);

    // Drawing text
    glViewport(5, 5, CurrentWidth - 5, CurrentHeight - 5);
    glRasterPos2f(-1, -1);
    glutBitmapCharacter(GLUT_BITMAP_8_BY_13, sample_character);
    glViewport((CurrentWidth - Width) / 2, (CurrentHeight - Height) / 2, Width, Height);

    glFlush();
}

and the following code is used for reshaping function:


void reshape(GLsizei w, GLsizei h)
{
    CurrentWidth = w, CurrentHeight = h;
    glViewport((w - Width) / 2, (h - Height) / 2, Width, Height);
}

I use glViewport several times, first is to draw geometry in the centre of window, second is to draw the text and then to restore it to the previous state. It feels this approach is not so good, it would be amazing if someone can review this chunk of code and maybe suggest some better way to deal with it.

p.s. I’m allowed only to use the old glut.

Thank you for your replies.

Note that you can use glWindowPos() to set the raster position directly in window coordinates (independent of the viewport and the model-view and projection matrices).

Thank you, but could you explain please how to set the indentation in pixels there?

Upd.: Oh, I think I got it, glWindowPos2i sets exactly indentation in pixels.

I didn’t want to make another thread, so maybe I shall ask here. I decided to make a simple animation of geometry, I did it using a vertex shader, so I send the value of a rotation angle to it:


void display(void)
{
    // Geometry
    glClear(GL_COLOR_BUFFER_BIT);
    glUniform1f(Theta, theta);
    glLineWidth(1);
    glDrawArrays(GL_LINES, 0, 12);

    // Interface
    glUniform1f(Theta, 0); // line that solved the problem
    glWindowPos2i(5, 5);
    for (int i = 0; i < strlen(str); i++)
        glutBitmapCharacter(GLUT_BITMAP_8_BY_13, str[i]);

    glFlush();
}

During the first run my string (simple text button) also rotated with geometry, and then I realised that I should have added the commented above line to the display function. Though again I’m not sure of it’s a best practice, maybe it’s better to somehow separate interface and geometry drawing, but I don’t know how?

If the code was less trivial, you’d probably end up using different shader programs for the lines and bitmaps; the one for the bitmaps presumably wouldn’t have a [var]Theta[/var] uniform.

Note that “modern” OpenGL (i.e. OpenGL 3.2+ core profile) doesn’t support bitmaps or the raster position; you’d have to use textured triangles instead.

IIRC, updates to the raster position via glRasterPos()are fed through the vertex shader, while updates via glWindowPos() aren’t. And I think that incremental updates via glBitmap() shouldn’t be either, so if the text is being rotated, that may indicate a bug in the driver (or it may be that some versions of GLUT manually update the raster position after each character rather than letting glBitmap() do it).

IMHO, mixing shader programs and bitmaps is asking for trouble. While the compatibility profile specification does state how the two are supposed to interact, this combination isn’t likely to be well tested, or likely to be considered a high priority by hardware vendors.

[QUOTE=GClements;1288347]If the code was less trivial, you’d probably end up using different shader programs for the lines and bitmaps; the one for the bitmaps presumably wouldn’t have a [var]Theta[/var] uniform.

Note that “modern” OpenGL (i.e. OpenGL 3.2+ core profile) doesn’t support bitmaps or the raster position; you’d have to use textured triangles instead.

IIRC, updates to the raster position via glRasterPos()are fed through the vertex shader, while updates via glWindowPos() aren’t. And I think that incremental updates via glBitmap() shouldn’t be either, so if the text is being rotated, that may indicate a bug in the driver (or it may be that some versions of GLUT manually update the raster position after each character rather than letting glBitmap() do it).

IMHO, mixing shader programs and bitmaps is asking for trouble. While the compatibility profile specification does state how the two are supposed to interact, this combination isn’t likely to be well tested, or likely to be considered a high priority by hardware vendors.[/QUOTE]

Thank you very nuch. When you said textured triangles, you mean creating an image with text (in this case) and putting it as a texture? By the way, I think it indeed was some kind of a bug, with rotating text, since I can’t reproduce it again. I works even without that line.