使用 OpenGL 和 QT 进行纹理映射 - C++

Posted

技术标签:

【中文标题】使用 OpenGL 和 QT 进行纹理映射 - C++【英文标题】:Texture mapping with OpenGL and QT - C++ 【发布时间】:2014-03-04 20:51:57 【问题描述】:

我无法使用 OpenGL 和 Qt 将纹理映射到四边形。我已经查看了其他几个 SO 线程,但是很多函数调用的使用必须略有不同才能编译(Qt Verison 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();

【问题讨论】:

(P.S. 您传递给 LoadGLTextures 的文件名被忽略,不确定这是不是故意的。) 你怎么知道文件名被忽略了?编辑:没关系,这是因为我没有使用我传入的变量,duh。 我尝试了您的建议,但仍未解决问题,但感谢您的帮助。 我也没有看到你在任何地方设置你的投影矩阵。默认情况下,GL 将相机放置在 (0,0,0) 处,朝向 -Z。设置您的相机投影,或者将您的四边形移动到 Z gluPerspective(适用于GL_PROJECTION)和gluLookAt(适用于GL_MODELVIEW以重新定位相机)。 QGLWidget::resizeGL() 是设置投影矩阵的好地方(因为调整组件大小时纵横比会发生变化)。 (笑),除非您的硬件支持 ARB_texture_non_power_of_two,否则纹理尺寸必须是 2 的幂。如果您的图像不是2,传统技术是创建最小可能的 2 次幂纹理,即 >= 使用 glTexImage2D 的图像大小(传递 NULL 数据为空白),然后将图像加载到它与glTexSubImage2D 并相应地调整您的纹理坐标(基于您的图像在大纹理中占据的宽度/高度的分数)。我建议先尝试绘制一个纯色四边形,以确保其他一切正常。 【参考方案1】:

看了你的评论,现在答案已经很清楚了,抱歉我在问题cmets中错过了。

您看到黑屏是因为您启用了深度测试,但您没有清除帧之间的深度缓冲区。因此,前一帧的深度缓冲区值保持不变,并且所有后续帧的深度测试都失败(注意the default depth function is GL_LESS)。

您可以启用深度测试。正确的解决方案是在每次渲染之前清除深度缓冲区和颜色缓冲区。你有:

glClear( GL_COLOR_BUFFER_BIT );

但你需要:

glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

另见:glClear()

【讨论】:

虽然我在下面的回答解决了这个问题,但这是真正的答案。感谢您的帮助!【参考方案2】:

删除 glEnable(GL_DEPTH_TEST) 为我解决了这个问题,以防万一有人遇到类似问题。

【讨论】:

哦。呃......对不起,我在问题 cmets 中给了你问题并错过了你没有清除深度缓冲区(你不需要禁用深度测试,你只需要在清除颜色缓冲区时清除深度缓冲区) )。我希望至少其中一些 cmets 在其他方面有所帮助。

以上是关于使用 OpenGL 和 QT 进行纹理映射 - C++的主要内容,如果未能解决你的问题,请参考以下文章

将纹理添加到 QT OpenGL 场景图

OpenGL 纹理映射内存泄漏

顶点着色器 glsl qt 中的纹理映射

不断更新OpenGL窗口

使用 OpenGL 进行纹理映射后的奇怪结果

opengl纹理映射总结