OpenGL 纹理未显示(纯色而不是纹理)或显示有瑕疵
OpenGL texture not displayed (solid color instead texture) or displayed with artifacts
我正在使用代码在 OpenGL (Qt4.8.3 + Linux (debian-like) 中将文本绘制为纹理。
代码是从 2D 项目移植过来的,它运行良好。
2D 项目使用 gluOrtho2D,现在我使用 gluLookAt 进行 3D。
问题是我看到的不是文本,而是彩色矩形。
如果我打开 GL_DEPTH_TEST,我会看到伪像而不是文本。顺便说一句,如果我移动相机,伪影会发生变化,这很奇怪。
代码如下:
void GLWidget::paintGL() {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //Set blending function.
glEnable(GL_BLEND); //Enable blending.
glShadeModel(GL_SMOOTH);
glEnable(GL_MULTISAMPLE);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glPushMatrix();
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 60.0f, (GLdouble) width() / (GLdouble) height(), 0.001f, 10000.0f );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
// Set up current camera
gluLookAt( cameraDistance * sin(cameraTheta * M_PI / 180) * cos(cameraPhi * M_PI / 180),
cameraDistance * sin(cameraTheta * M_PI / 180) * sin(cameraPhi * M_PI / 180),
cameraDistance * cos(cameraTheta * M_PI / 180),
0.0, 0.0, 0.0,
0.0, 0.0, 1.0);
glTranslatef(-4.5355, -4.5355, 0.0);
glPushMatrix();
// draw text labels
drawLabel(1, 0, 90, "1");
drawLabel(2, 0, 90, "2");
drawLabel(3, 0, 90, "3");
drawLabel(4, 0, 90, "4");
drawLabel(5, 0, 90, "5");
glPopMatrix();
glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
glPopMatrix();
}
void GLWidget::drawLabel(float xpos, float ypos, float angle, char *txt) {
float labelHeight = 0.3;
float labelWidth = labelHeight / 2;
float margin = labelWidth / 10;
float len = (float) strlen(txt);
glPushMatrix();
glRotatef(-angle, 0, 0, -1);
glTranslatef(xpos, ypos, 0.0f);
glRotatef(angle, 0, 0, -1);
glScalef(1.0, -1.0, 1.0);
glTranslatef(- len * labelWidth / 2, -labelHeight / 2 + margin, 0.0f);
// background
glColor3f(0.0f, 0.0f, 0.0f);
glBegin(GL_QUADS);
glVertex3f(-margin, -margin, 0);
glVertex3f(len * labelWidth + margin, -margin, 0);
glVertex3f(len * labelWidth + margin, labelHeight + margin, 0);
glVertex3f(-margin, labelHeight + margin, 0);
glEnd();
// text
glColor3f(0.5f, 0.5f, 0.5f);
glEnable(GL_TEXTURE_2D);
glBindTexture( GL_TEXTURE_2D, glFont->getTextureID() );
glFont->drawText(labelWidth, labelHeight, txt);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
glPopMatrix();
}
void oglFont::drawText(GLfloat cw, GLfloat ch, char *txt)
{
glBegin(GL_QUADS);
//character location and dimensions
GLfloat cx = 0.0f;
GLfloat cy = 0.0f;
//calculate how wide each character is in term of texture coords
GLfloat dtx = float(c_width) / float(m_width);
GLfloat dty = float(c_height) / float(m_height);
for (char * c = txt; *c != 0; c++, cx += cw) {
int index = getCharIndex(c);
int row = index / c_per_row;
int col = index % c_per_row;
if (index < 0) {
//qDebug() << "glFont: Character outside of font! char: " << c;
}
// find the texture coords
GLfloat tx = float(col * c_width) / float(m_width);
GLfloat ty = float(row * c_height) / float(m_height);
glTexCoord2f(0, 0);
glVertex2f(cx, cy);
glTexCoord2f(1, 0);
glVertex2f(cx + cw, cy);
glTexCoord2f(1, 1);
glVertex2f(cx + cw, cy + ch);
glTexCoord2f(0, 1);
glVertex2f(cx, cy + ch);
}
glEnd();
}
神器的原因是Z战
这个问题可以通过增加深度缓冲区的精度或使不同的对象彼此更远(来自 drawlable 的对象)来解决。
还要确保您生成的文本不会被远平面/近平面剔除(也许您生成的几何图形非常靠近边缘?)。
原来是因为纹理是在QGLWidget构造函数中加载的,上下文要么没有创建要么没有设置。
我在 initializeGL() 方法中移动了纹理加载,效果很好。
我正在使用代码在 OpenGL (Qt4.8.3 + Linux (debian-like) 中将文本绘制为纹理。 代码是从 2D 项目移植过来的,它运行良好。
2D 项目使用 gluOrtho2D,现在我使用 gluLookAt 进行 3D。
问题是我看到的不是文本,而是彩色矩形。 如果我打开 GL_DEPTH_TEST,我会看到伪像而不是文本。顺便说一句,如果我移动相机,伪影会发生变化,这很奇怪。
代码如下:
void GLWidget::paintGL() {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //Set blending function.
glEnable(GL_BLEND); //Enable blending.
glShadeModel(GL_SMOOTH);
glEnable(GL_MULTISAMPLE);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glPushMatrix();
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 60.0f, (GLdouble) width() / (GLdouble) height(), 0.001f, 10000.0f );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
// Set up current camera
gluLookAt( cameraDistance * sin(cameraTheta * M_PI / 180) * cos(cameraPhi * M_PI / 180),
cameraDistance * sin(cameraTheta * M_PI / 180) * sin(cameraPhi * M_PI / 180),
cameraDistance * cos(cameraTheta * M_PI / 180),
0.0, 0.0, 0.0,
0.0, 0.0, 1.0);
glTranslatef(-4.5355, -4.5355, 0.0);
glPushMatrix();
// draw text labels
drawLabel(1, 0, 90, "1");
drawLabel(2, 0, 90, "2");
drawLabel(3, 0, 90, "3");
drawLabel(4, 0, 90, "4");
drawLabel(5, 0, 90, "5");
glPopMatrix();
glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
glPopMatrix();
}
void GLWidget::drawLabel(float xpos, float ypos, float angle, char *txt) {
float labelHeight = 0.3;
float labelWidth = labelHeight / 2;
float margin = labelWidth / 10;
float len = (float) strlen(txt);
glPushMatrix();
glRotatef(-angle, 0, 0, -1);
glTranslatef(xpos, ypos, 0.0f);
glRotatef(angle, 0, 0, -1);
glScalef(1.0, -1.0, 1.0);
glTranslatef(- len * labelWidth / 2, -labelHeight / 2 + margin, 0.0f);
// background
glColor3f(0.0f, 0.0f, 0.0f);
glBegin(GL_QUADS);
glVertex3f(-margin, -margin, 0);
glVertex3f(len * labelWidth + margin, -margin, 0);
glVertex3f(len * labelWidth + margin, labelHeight + margin, 0);
glVertex3f(-margin, labelHeight + margin, 0);
glEnd();
// text
glColor3f(0.5f, 0.5f, 0.5f);
glEnable(GL_TEXTURE_2D);
glBindTexture( GL_TEXTURE_2D, glFont->getTextureID() );
glFont->drawText(labelWidth, labelHeight, txt);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
glPopMatrix();
}
void oglFont::drawText(GLfloat cw, GLfloat ch, char *txt)
{
glBegin(GL_QUADS);
//character location and dimensions
GLfloat cx = 0.0f;
GLfloat cy = 0.0f;
//calculate how wide each character is in term of texture coords
GLfloat dtx = float(c_width) / float(m_width);
GLfloat dty = float(c_height) / float(m_height);
for (char * c = txt; *c != 0; c++, cx += cw) {
int index = getCharIndex(c);
int row = index / c_per_row;
int col = index % c_per_row;
if (index < 0) {
//qDebug() << "glFont: Character outside of font! char: " << c;
}
// find the texture coords
GLfloat tx = float(col * c_width) / float(m_width);
GLfloat ty = float(row * c_height) / float(m_height);
glTexCoord2f(0, 0);
glVertex2f(cx, cy);
glTexCoord2f(1, 0);
glVertex2f(cx + cw, cy);
glTexCoord2f(1, 1);
glVertex2f(cx + cw, cy + ch);
glTexCoord2f(0, 1);
glVertex2f(cx, cy + ch);
}
glEnd();
}
神器的原因是Z战
这个问题可以通过增加深度缓冲区的精度或使不同的对象彼此更远(来自 drawlable 的对象)来解决。
还要确保您生成的文本不会被远平面/近平面剔除(也许您生成的几何图形非常靠近边缘?)。
原来是因为纹理是在QGLWidget构造函数中加载的,上下文要么没有创建要么没有设置。
我在 initializeGL() 方法中移动了纹理加载,效果很好。