【问题标题】:How to draw text letter by letter in glut?如何在过剩中逐个字母地绘制文本?
【发布时间】:2014-11-06 14:14:13
【问题描述】:

我的 GLUT 程序无法正常工作。我想以毫秒为间隔逐个字母地绘制文本(字符数组)。我的程序:

#include <string.h>
#include <windows.h>
#include <glut.h>
#include<iostream>

int hei = glutGet(GLUT_SCREEN_HEIGHT)/2;
int wid = glutGet(GLUT_SCREEN_WIDTH)/2;
void *font = GLUT_BITMAP_TIMES_ROMAN_24;
void *fonts[] =
{
  GLUT_BITMAP_9_BY_15,
  GLUT_BITMAP_TIMES_ROMAN_10,
  GLUT_BITMAP_TIMES_ROMAN_24
};

void selectFont(int newfont)
{
  font = fonts[newfont];
  glutPostRedisplay();
}

void selectColor(float r, float g, float b)
{
glColor3f(r, g, b);
  glutPostRedisplay();
}




char *msg;

void tick(void)
{
  glutPostRedisplay();
}
void timer(int value) {

}
int element=0;
void output(int x, int y, char *string, bool center=true) {
  int len;
  len = strlen(string);
  if(center){
  glRasterPos2f((wid-len), y);
  }
  else {
  glRasterPos2f(x, y); 
  }
 for(int i=0;i<len;i++) {
    glutBitmapCharacter(font, string[i]);
    glPopMatrix();
    glutSwapBuffers();
    Sleep(500);
 }
}
void outputmsg(int x, int y, bool center=true) {
  int len;
  len = strlen(msg);
  if(center){
  glRasterPos2f((wid-len), y);
  }
  else {
  glRasterPos2f(x, y); 
  }
 for(int i=0;i<len;i++) {
     glutBitmapCharacter(font, msg[i]);
 }
}
void updatemsg() {
    msg="test msg letter by letter";
}
void display(void)
{
  glClear(GL_COLOR_BUFFER_BIT);
  msg="|";
  updatemsg();
  if(msg!="|")
    output(wid, hei, msg, true);
  else
    output(wid,hei,msg,true);
}
void reshape(int w, int h)
{
  glViewport(0, 0, w, h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluOrtho2D(0, w, h, 0);
  glMatrixMode(GL_MODELVIEW);
}
void keyboard(unsigned char key, int x, int y) {
    switch(key){
    case 27:
        exit(1);
        break;
    }
}
int main(int argc, char **argv)
{
  int i, msg_submenu, color_submenu;

  glutInit(&argc, argv);
  for (i = 1; i < argc; i++) {
    if (!strcmp(argv[i], "-mono")) {
      font = GLUT_BITMAP_9_BY_15;
    }
  }
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
  glutInitWindowSize(wid*2, hei*2);
  glutCreateWindow("CHAT");
  glutFullScreen();
  glClearColor(0.0, 0.0, 0.0, 1.0);
  glutDisplayFunc(display);
  glutReshapeFunc(reshape);
  glutKeyboardFunc(keyboard);
  glutIdleFunc(tick);
  selectFont(0);
  glutMainLoop();
  return 0;             /* ANSI C requires main to return int. */
}

它确实很奇怪,例如擦除前一个字符然后打印然后打印下一个字符和已擦除的字符。我尝试了所有我能在论坛上找到的关于这个主题的东西。我该如何解决?

【问题讨论】:

  • 我们不是“给我密码!!!”网站,向我们展示您可以做什么,我们可以尝试进一步提供帮助
  • google opengl text tutorial。向我们展示一些关于您已经完成的研究工作,寻找教程并不是一项如此的工作。
  • 我用整个程序代码编辑了代码。
  • 你在滥用显示回调。它的存在是要求您绘制一帧,而不是同时绘制大量阻塞的帧。

标签: c++ opengl text draw glut


【解决方案1】:

你应该做的也是保持你想要显示的字符串的长度,并每隔几毫秒增加一次:

int len;
char *msg;

void incrementLength(int value){
   if(msg[len]==0)return; //end of string stop the callback
   len++;
   glutTimerFunc(100, incrementLength, 0);
   glutPostRedisplay();
}

void updatemsg() {
    msg="test msg letter by letter";
    len=0;
    glutTimerFunc(100, incrementLength, 0);
}

然后在 outputmsg 中(如果你真的调用它的话)你只循环直到 len:

void outputmsg(int x, int y, bool center=true) {

  if(center){
  glRasterPos2f((wid-len), y);
  }
  else {
  glRasterPos2f(x, y); 
  }
 for(int i=0;i<len;i++) {
     glutBitmapCharacter(font, msg[i]);
 }
}

【讨论】:

    【解决方案2】:

    这段代码有几个问题:

     for(int i=0;i<len;i++) {
        glutBitmapCharacter(font, string[i]);
        glPopMatrix();
        glutSwapBuffers();
        Sleep(500);
     }
    
    1. 您正在弹出一个从未在任何地方推送过的矩阵,并且您正在这样做len-很多次。

    2. 您正在交换缓冲区而不清除中间的屏幕...这将导致未定义的结果(通常是前一帧的乱码)。

    你真的需要重新思考你是如何实现这个的。

    我建议您在您的 display (...) 函数中执行一些经过时间检查,以确定要打印的字符,而不是在调用 Sleep (...) 的循环中执行此操作。

    【讨论】:

    • 我提出的不仅仅是一个建议。 OP 的方法是不是如何使用glutDisplayFunc 回调。
    • @LightnessRacesinOrbit:嗯,正如您从棘轮怪胎的回答中看到的那样,有多种方法可以解决这个问题。它可以用计时器完成,也可以每帧完成一次。然而,它确实不能保持现在的样子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-21
    • 1970-01-01
    • 1970-01-01
    • 2020-12-12
    • 2012-08-27
    • 1970-01-01
    相关资源
    最近更新 更多