c++ - 如何在 OpenGL 屏幕上同时显示图形和文字?

标签 c++ opengl text textures screen

下面的代码工作得很好,没有 fatal error ,但是,当我在“gluortho2d”中使用参数“w”,“h”作为 reshape 函数中的 gluortho2d(0,w,h,0) 时,我在屏幕上得到了文本,而如果我将这些参数“0,0”作为 gluortho2d(0,0,0,0) 我得到盒子的形状。 如何在屏幕上同时显示它们(框和文本)?

#include"glut.h"

void drawBitmapText(char *string, float x, float y, float z);
void reshape(int w, int h);
void display(void);

void drawBitmapText(char *string, float x, float y, float z)
{
    char *c;
    glRasterPos3f(x, y, z);//define position on the screen where to draw text.

    for (c = string; *c != '\0'; c++)
    {
        glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, *c);
    }
}

void reshape(int w, int h)
{
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();//Resets to identity Matrix.
    gluOrtho2D(0, w, h, 0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

}

void display(void)
{

    glBegin(GL_POLYGON);//1
    glVertex2f(-0.2, 0.6 - 0.3);
    glVertex2f(-0.1, 0.6 - 0.3);
    glVertex2f(-0.1, 0.5 - 0.3);
    glVertex2f(-0.2, 0.5 - 0.3);
    glEnd();


    glColor3f(0, 1, 0);
    drawBitmapText("Usama Ishfaq", 200, 400, 0);//drawBitmapText("Usama Ishfaq", x(how much right), y(how much down), z);

    glutSwapBuffers();
}


int main(int argc, char* argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); 
    glutInitWindowSize(500, 500);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("Usama OGL Window");
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutMainLoop();

    return 0;
}

最佳答案

通过不遵循糟糕的教程并将对 glViewport 的调用和投影矩阵设置放在唯一有效的地方:显示函数。 在 reshape 中设置视口(viewport)和投影矩阵handler 是一种反模式。不要这样做。

这样做

void display(void)
{
    int const w = glutGet(GLUT_WINDOW_WIDTH);
    int const h = glutGet(GLUT_WINDOW_HEIGHT);

    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();//Resets to identity Matrix.
    gluOrtho2D(-1, 1, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();    

    glBegin(GL_POLYGON);//1
    glVertex2f(-0.2, 0.6 - 0.3);
    glVertex2f(-0.1, 0.6 - 0.3);
    glVertex2f(-0.1, 0.5 - 0.3);
    glVertex2f(-0.2, 0.5 - 0.3);
    glEnd();

    /* viewport doesn't change in this
     * application, but it's perfectly
     * valid to set a different
     * glViewport(...) here */
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();//Resets to identity Matrix.
    gluOrtho2D(0, w, h, 0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glColor3f(0, 1, 0);
    drawBitmapText("Usama Ishfaq", 200, 400, 0);//drawBitmapText("Usama Ishfaq", x(how much right), y(how much down), z);

    glutSwapBuffers();
}

更新(根据评论中的要求):

为什么在reshape handler中设置viewport和projection参数是错误的?好吧,您刚刚亲 body 验了原因:它们不是“一刀切”的状态,并且在渲染稍微复杂的帧的过程中,不仅仅是绘制的网格,您会想要在整个渲染过程中混合和匹配不同的视口(viewport)和投影.这是一个(不完整的)列表,列出了在渲染单个帧时需要具有不同视口(viewport)和投影的事物:

  • 渲染到纹理 (FBO) – 需要具有纹理边界的视口(viewport),通常还需要不同的投影(对于阴影贴图、动态立方体贴图和许多其他高级多 channel 渲染技术很重要)
  • 小 map /概览框架或类似的角落(视口(viewport)覆盖角落)
  • 文本注释叠加(不同的投影;通常是普通的身份转换,以便直接在 NDC 空间中绘制文本矩形)
  • “放大镜”叠加层

由于在稍微复杂一点的 OpenGL 绘图中会多次更改视口(viewport)和投影状态,所以这使得

a) 在 reshape 处理程序中设置它的零意义:无论处理程序设置什么,都只会在第一帧的绘制开始时设置,此后帧绘制代码本身必须重置为 reshape 处理程序设置的内容.那么,为什么还要费心在 reshape 处理程序中这样做呢?

b) 将视口(viewport)和投影设置代码放在 reshape 处理程序中从长远来看是一种负担,因为它可能会导致程序的其他部分依赖它。如果发生这种情况,一旦您意识到自己的错误并尝试将该视口(viewport)和投影设置代码移动到它所属的程序的其他部分,这些部分依赖于从 reshape 处理程序中断调用它,您也必须修复这些代码。

总而言之,没有理由在 reshape 处理程序中放置任何与绘图相关的调用(并且 glViewport 和投影设置肯定与绘图相关)。当然,“一次性”初始化在那里非常好,也就是说,如果您想要调整 FBO 渲染目标的大小以匹配窗口,或者如果您想要准备一个稍后重复应用的叠加图像。

关于c++ - 如何在 OpenGL 屏幕上同时显示图形和文字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38857307/

相关文章:

c++ - 使用 TransparentBlt

opengl - 重新调整后对整个场景进行抗锯齿处理

qt - qt 4.8.4 中的文本渲染

python - 将类似系列的数据文件导入 pandas

javascript - 生成重新格式化的文本列表

c++ - boost::lockfree::spsc_queue的read_available和write_available应该如何使用?

c++ - 在 C++ 中制作此指针的本地拷贝

java - JNAerator - 使用由 typedef 生成的接口(interface)

c++ - 尝试为屏幕的每个像素着色时出现线条?

python - 使用 glGetFloatv 检索 pyglet 中的模型 View 矩阵