C++ 使用 GLUT 在 3D OpenGL 世界中显示固定位置的 2D 文本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18847109/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:15:31  来源:igfitidea点击:

Displaying fixed location 2D text in a 3D OpenGL world using GLUT

c++openglglut

提问by Papouh

I have an OpenGLproject which uses GLUT(not freeglut) wherein I would like to display 2D text on the viewport at a fixed location. The rest of my objects are in 3D world co-ordinates.

我有一个OpenGL使用GLUT(不是 freeglut)的项目,我想在固定位置的视口上显示 2D 文本。我的其余对象在 3D 世界坐标中。

This answerto a related old question says that,

这个对相关旧问题的回答说,

the bitmap fonts which ship with GLUT are simple 2D fonts and are not suitable for display inside your 3D environment. However, they're perfect for text that needs to be overlayed on the display window.

GLUT 附带的位图字体是简单的 2D 字体,不适合在 3D 环境中显示。但是,它们非常适合需要覆盖在显示窗口上的文本。

I've tried the approach outlined in the accepted answer, but it does not give me the desired output. Following is a code snippet of the display function:

我已经尝试了接受的答案中概述的方法,但它没有给我想要的输出。以下是显示功能的代码片段:

void display()
{
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glLoadIdentity();  
  glTranslatef(0.0, 0.0, -(dis+ddis));   //Translate the camera
  glRotated(elev+delev, 1.0, 0.0, 0.0);  //Rotate the camera
  glRotated(azim+dazim, 0.0, 1.0, 0.0);  //Rotate the camera

       .
       .
       .
  draw 3D scene
       .
       .
       .

  glMatrixMode(GL_PROJECTION);
  glPushMatrix();
  glLoadIdentity();
  gluOrtho2D(0.0, win_width, 0.0, win_height);
  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  glLoadIdentity();
  glRasterPos2i(10, 10);
  string s = "Some text";
  void * font = GLUT_BITMAP_9_BY_15;
  for (string::iterator i = s.begin(); i != s.end(); ++i)
  {
    char c = *i;
    glColor3d(1.0, 0.0, 0.0);
    glutBitmapCharacter(font, c);
  }
  glMatrixMode(GL_MODELVIEW);
  glPopMatrix();
  glMatrixMode(GL_PROJECTION);
  glPopMatrix();

  glFlush();
  glSwapBuffers();
}

A similar questionto what I want seems to have been asked, but has no accepted answers by the author.

一个类似的问题,以我想要的东西似乎已经问过,但一直没有接受了笔者的答案。

Answers in general seem to suggest using other libraries (mostly OS specific) to achieve the overlay. However, there is no clear indication to whether this can be achieved with GLUTalone. Can it be done?

一般来说,答案似乎建议使用其他库(主要是操作系统特定的)来实现覆盖。然而,没有明确的迹象表明这是否可以单独实现GLUT。可以做到吗?

采纳答案by PeterT

As I said, the code you posted works perfectly fine. Here's the code I used to test it:

正如我所说,您发布的代码运行良好。这是我用来测试它的代码:

#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif

#include "GL/glu.h"
//glm not required
//#include <glm.hpp>
//#include <gtc/matrix_transform.hpp>
#include <string>

int win_width = 500, win_height = 500;

void renderScene(void) {

    static float dis=0, ddis=0, elev=0, delev=0, azim=0, dazim=0;

    azim += 0.5f;
    if (azim >= 360.0f){
        azim -= 360.0f;
    }

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();
    glTranslatef(0.0f, 0.0f, -(dis + ddis));
    glRotated(elev + delev, 1.0, 0.0, 0.0);
    glRotated(azim + dazim, 0.0, 1.0, 0.0);
    glScalef(2.0f,2.0f,2.0f);

    glBegin(GL_TRIANGLES);
        glColor3f(1.0f, 1.0f, 0.0f);
        glVertex3f(-0.5f, -0.5f, 0.0f);
        glColor3f(0.0f, 1.0f, 0.0f);
        glVertex3f(0.5f, 0.0f, 0.0f);
        glColor3f(0.0f, 0.0f, 1.0f);
        glVertex3f(0.0f, 0.5f, 0.0f);
    glEnd();


    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    //I like to use glm because glu is deprecated
    //glm::mat4 orth= glm::ortho(0.0f, (float)win_width, 0.0f, (float)win_height);
    //glMultMatrixf(&(orth[0][0]));
    gluOrtho2D(0.0, win_width, 0.0, win_height);
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
    glColor3f(1.0f, 0.0f, 0.0f);//needs to be called before RasterPos
    glRasterPos2i(10, 10);
    std::string s = "Some text";
    void * font = GLUT_BITMAP_9_BY_15;

    for (std::string::iterator i = s.begin(); i != s.end(); ++i)
    {
        char c = *i;
        //this does nothing, color is fixed for Bitmaps when calling glRasterPos
        //glColor3f(1.0, 0.0, 1.0); 
        glutBitmapCharacter(font, c);
    }
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glEnable(GL_TEXTURE_2D);

    glutSwapBuffers();
    glutPostRedisplay();
}

int main(int argc, char **argv) {

    // init GLUT and create Window
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(win_width, win_height);
    glutCreateWindow("GLUT Test");

    // register callbacks
    glutDisplayFunc(renderScene);

    // enter GLUT event processing cycle
    glutMainLoop();

    return 1;
}

The usual disclaimers about deprecated fixed function pipeline and others apply.

有关已弃用的固定功能管道和其他人的通常免责声明适用。

回答by SyntaxRules

I ran into this same problem using glut to create a model of the solar system. Here's how I solved it: (using your code from above)

我使用 glut 创建太阳系模型时遇到了同样的问题。这是我解决它的方法:(使用上面的代码)

glDisable(GL_TEXTURE_2D); //added this
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0.0, win_width, 0.0, win_height);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glRasterPos2i(10, 10);
string s = "Some text";
void * font = GLUT_BITMAP_9_BY_15;
for (string::iterator i = s.begin(); i != s.end(); ++i)
{
  char c = *i;
  glColor3d(1.0, 0.0, 0.0);
  glutBitmapCharacter(font, c);
}
glMatrixMode(GL_PROJECTION); //swapped this with...
glPopMatrix();
glMatrixMode(GL_MODELVIEW); //...this
glPopMatrix();
//added this
glEnable(GL_TEXTURE_2D);


You'll note i switched glMatrixMode(GL_PROJECTION);and glMatrixMode(GL_MODELVIEW);near the end. I decided to do this because of this website. I also has to surround the code section with glDisable(GL_TEXTURE_2D)and glEnable(GL_TEXTURE_2D).


你会注意到我切换了glMatrixMode(GL_PROJECTION);并且glMatrixMode(GL_MODELVIEW);接近尾声。我决定这样做是因为这个网站。我还必须用glDisable(GL_TEXTURE_2D)和包围代码部分glEnable(GL_TEXTURE_2D)

Hope that helps- I worked for me. My solar system uses classes to perform all of this, I'd be happy to share more details upon request.

希望有帮助 - 我为我工作。我的太阳系使用类来执行所有这些,我很乐意应要求分享更多细节。

回答by simerekentel

There is a tricky way to solve your problem.

有一种棘手的方法可以解决您的问题。

Please write a code before you call a function or what ever it is as written below:

请在调用函数之前编写代码或如下所示:

glutBitmaCharacter(font, ' ');// 

Does it....! And it should work...

可以....!它应该工作......