在OpenGL和QT-C++中进行纹理映射

3

我在使用OpenGL和Qt时,遇到了纹理映射到四边形的问题。我查看了许多其他的SO线程,但很多函数调用必须稍微不同地使用才能编译(Qt版本4.8.6)。这是我相关的代码,现在只显示一个带有黑色背景的窗口,除此之外没有任何反应。

void LoadGLTextures( const char * name )
{
    QImage img;

    if(!img.load("resources/Green_Dragon.bmp")){
        std::cerr << "ERROR in loading image" << std::endl;
    }

    QImage t = QGLWidget::convertToGLFormat(img);

    glGenTextures(1, &texture[0]);
    glBindTexture(GL_TEXTURE_2D, texture[0]);
    glTexImage2D(GL_TEXTURE_2D, 0, 3, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.bits());

    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glBindTexture( GL_TEXTURE_2D, 0 );
}



void GLWidget::initializeGL()
{


    qglClearColor(qtBlack.dark());
    glEnable(GL_CULL_FACE);
    glShadeModel(GL_SMOOTH);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_MULTISAMPLE);
    static GLfloat lightPosition[4] = { 0.5, 5.0, 7.0, 1.0 };
    glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
    cameraPos = 0;
    glEnable(GL_TEXTURE_2D);
    LoadGLTextures("resources/Green_Dragon.jpeg");

}

void GLWidget::paintGL()
{
    glClearColor( 0.0f, 0.0f, 0.0f, 0.0f);
    glClear( GL_COLOR_BUFFER_BIT );


    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    glShadeModel( GL_FLAT );
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_TEXTURE_2D);
    glColor3f(0.5, 0.5, 0);
    glBindTexture(GL_TEXTURE_2D, texture[0]);

    glBegin(GL_QUADS);
    glTexCoord2f(0.0f, 1.0f); glVertex2f(-0.5f, 0.5f);  // vertex 1
    glTexCoord2f(0.0f, 0.0f); glVertex2f(-0.5f, -0.5f); // vertex 2
    glTexCoord2f(1.0f, 0.0f); glVertex2f(0.5f, -0.5f); // vertex 3
    glTexCoord2f(1.0f, 1.0f); glVertex2f(0.5f, 0.5f); // vertex 4
    glEnd();
    glDisable(GL_TEXTURE_2D);

    glFlush();
}

(注:您传递给“LoadGLTextures”的文件名被忽略了,不确定这是否是有意的。) - Jason C
你怎么知道文件名被忽略了?编辑:算了,因为我没有使用传递进来的变量,真蠢。 - midma101
我尝试了你的建议,但问题还没有得到解决,不过还是谢谢你的帮助。 - midma101
1
另外,我没有看到您在任何地方设置投影矩阵。默认情况下,GL将相机放置在(0,0,0)处,面向-Z。要么设置相机投影,要么将四边形移动到Z < 0的某个位置(尽管我不记得默认的剪辑平面距离是多少)。我建议前者。请查看gluPerspective(应用于GL_PROJECTION)和gluLookAt(应用于GL_MODELVIEW以重新定位相机)。 QGLWidget :: resizeGL()是设置投影矩阵的好地方(因为组件调整大小时纵横比会发生变化)。 - Jason C
1
此外(哈哈),除非您的硬件支持ARB_texture_non_power_of_two,否则纹理尺寸必须是2的幂。如果您的图像不是2的幂,则传统技术是创建最小可能的大于等于图像大小的2的幂纹理,并使用glTexSubImage2D将图像加载到其中一部分,并相应地调整纹理坐标(基于图像在大型纹理中占用宽度/高度的比例)。我建议首先尝试绘制一个单色四边形,以确保其他所有内容都正常。 - Jason C
所以我移除了 glEnable(GL_DEPTH_TEST),现在它可以工作了。不太确定为什么会这样,但感谢您帮助我解决了这个问题,正是您对视口的讨论让我找到了答案。 - midma101
2个回答

4
看了您的评论,现在答案已经很清楚了,很抱歉我在问题评论中错过了它。
您看到黑屏是因为您启用了深度测试,但在帧之间没有清除深度缓冲区。因此,上一帧的深度缓冲区值仍然存在,并且对于所有后续帧,深度测试都会失败(请注意默认深度函数为GL_LESS)。
您可以保留深度测试的启用状态。正确的解决方案是在每次渲染之前清除深度缓冲区和颜色缓冲区。您有:
glClear( GL_COLOR_BUFFER_BIT );

但你需要:

glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

另请参阅: glClear()


1
虽然我下面的回答解决了问题,但这才是真正的答案。感谢帮助! - midma101

0

对于我来说,移除glEnable(GL_DEPTH_TEST)解决了这个问题,以防有人遇到类似的问题。


1
哦,对不起,在问题评论中我让你绕了一圈,没注意到你没有清除深度缓冲区(你不需要禁用深度测试,只需要在清除颜色缓冲区时清除深度缓冲区)。希望那些评论至少在其他方面有所帮助。 - Jason C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接