如何在OpenGL屏幕上同时显示形状和文本
How to display shape and text on OpenGL screen simultaneously?
下面的代码工作得很好,没有致命错误,但是,当我使用参数"w","h"在"gluortho2d"作为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 != ' '; 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
和投影矩阵设置:显示功能。在重塑处理程序中设置视口和投影矩阵是一个反模式。别这么做。
这样做
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();
}
更新(由于评论中的请求):
为什么在重塑处理程序中设置视口和投影参数是错误的?好吧,你刚刚经历了自己的原因:它们不是"一刀切"的状态,并且在渲染过程中稍微复杂一些的帧,而不仅仅是一个网格绘制,你将希望在渲染过程中混合和匹配不同的视口和投影。这里有一个(不完整的)事情的列表,需要有不同的视口和投影,而渲染单一帧:
- 渲染到纹理(FBO) -需要在纹理边界内的视口,通常也需要不同的投影(对于阴影映射,动态立方体映射和许多其他高级,多通道渲染技术很重要)
- 小地图/概览帧或类似的在角落(viewport只覆盖角落)
- 文本注释叠加(不同投影;通常是一个普通的恒等变换,以便直接在NDC空间中绘制文本矩形)
- "放大镜"叠加
因为改变视口和投影状态在稍微复杂一点的OpenGL绘图中会发生多次,所以
a)在重塑处理程序中设置它没有意义:无论处理程序设置什么,都将仅在第一帧绘制开始时设置,此后帧绘制代码本身必须重置为重塑处理程序设置的内容。那么为什么还要在重塑处理程序中做呢?
b)在重塑处理程序中放置视口和投影设置代码从长远来看是一个负担,因为它可能导致程序的其他部分依赖于它。如果发生这种情况,一旦你意识到你的错误,并试图将视口和投影设置代码移动到它所属的地方,依赖于它被从重塑处理程序调用的程序的其他部分中断,你也必须修复这些。
总而言之,没有理由在重塑处理程序中放置任何与绘图相关的调用(并且glViewport和投影设置肯定与绘图相关)。当然,"一次性"初始化是完全可以的,例如,如果你想调整FBO渲染目标的大小以匹配窗口,或者如果你想准备一个覆盖图像,稍后会被重复应用。
你可以让它更简单。对于您正在做的事情,根本不需要设置转换。
看起来,对于方框,您试图在两个坐标方向上使用[-1.0,1.0]范围内的坐标。这对应于OpenGL NDC(归一化设备坐标)坐标系统,这是在应用模型视图和投影转换之后的坐标空间顶点。如果你保持它们的默认单位矩阵,你可以直接在NDC空间中指定坐标。换句话说,要使用[-1.0,1.0]范围内的坐标,请……什么都不用,保持默认值。
当你调用:
gluOrtho2D(0.0, 0.0, 0.0, 0.0);
表示此调用将导致错误,如手册页所述:
如果左=右,或底=上,或近=远,则生成GL_INVALID_VALUE。
,因此将保持默认值不变,这正是您所需要的。
现在,对于文本,看起来您想要以像素为单位指定位置。您遇到的问题是,glRasterPos*()
通过转换管道运行指定的坐标,这意味着,使用默认的身份模型视图和投影转换,它期望输入坐标在[-1.0,1.0]范围内,就像您传递给glVertex2f()
的坐标一样。
glWindowPos*()
调用,唯一的区别是传递给它的坐标是窗口坐标,以像素为单位。
总结一下:
- 删除所有
glMatrixMode()
呼叫 - 删除所有
glLoadIdentity()
呼叫 - 删除所有
gluOrtho2D()
呼叫 在
drawBitmapText()
中,将glRasterPos3f()
替换为:glWindowPos2f(x, y);
glWindowPos2f(x, windowHeight - y);
在另一个答案中解决一些误导性信息:在reshape()
函数中调用glViewport()
是完全可以的,只要您对所有渲染使用相同的视口。在更复杂的应用程序中,你经常需要不同的视口来渲染不同的部分(例如,当你渲染到fbo时,或者只渲染到窗口的一部分),所以你需要在渲染期间在适当的地方调用glViewport()
。但对于一个简单的例子,你做你所有的渲染整个窗口,没有错调用它在reshape()
。
- 尝试使用 WinBGI 显示文本时出现编译器错误
- 动态填充的组合框不显示文本,列表未定义
- QTreeWidgetItem 突出显示文本问题
- 如何通过单击按钮在QTextEdit中显示文本?
- 在C Windows程序中显示文本文件内容
- findChild 从不显示文本浏览器
- C 在同一行中左右显示文本
- 使用 C++ 中的向量在新行上显示文本文件中的列
- 如何使用 Opengl 库显示文本文件中的 3D 点
- Qt. 方法显示文本() 如果我在 QStyledItemDelegate 中定义了 paint() 方法不起作用
- 如何在C 中的OpenGL中通过矩形显示文本
- 如何使用键盘输入和sf ::文本在SFML中添加一种文本框以显示文本字符串
- QMessageBox:无法在框中显示文本(使用 c++)
- 延迟窗口在 MFC 上显示文本
- Visual Studio代码集成的终端未显示文本
- SFML-不显示文本
- qprogressdialog未显示文本标签
- C++程序无法正确显示文本文件中的内容
- 如何在不显示文本的情况下分配Win32编辑控件的窗口名称
- SDL2 OpenGL SDL2_TTF:显示文本