You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Qt中绘制3D正方形无显示问题排查求助

Qt中绘制3D正方形无法显示的问题排查

问题描述

在Qt中尝试绘制一个简单的3D正方形,但始终无法显示。已确认上下文、VAO、VBO设置、顶点数据分配以及Shader链接都正确,猜测问题可能出在VBO数据处理或3D空间视图设置上,同时对很多示例不使用MVP矩阵感到困惑。

使用的Shader代码

顶点着色器

#version 330 core
layout(location = 0) in vec4 position;
layout(location = 1) in vec4 color;

out vec4 f_color;

void main()
{
    gl_Position = position;
    f_color = color;
};

片段着色器

in vec4 f_color;
out vec4 outputColor;

void main()
{
    outputColor = vec4(0.5, 0.5, 0, .5);
};

注:颜色为测试用随机设置。

相关实现代码

GLfloat cube[] = {
         //pos                          color
         -0.5f, -0.5f, -1.0f, 1.0f,     1.0f, 0.0f, 0.5f, 0.5f,
          0.5f, -0.5f, -1.0f, 1.0f,     1.0f, 1.0f, 0.5f, 0.5f,
          0.5f,  0.5f, -1.0f, 1.0f,     1.0f, 0.5f, 0.5f, 0.5f,
         -0.5f,  0.5f, -1.0f, 1.0f,     0.0f, 0.5f, 0.5f, 0.5f,
    };

void MyOpenGLWidget::paintGL(){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    m_program->bind();
    m_program->enableAttributeArray(attributePos);
    m_program->enableAttributeArray(attributeColor);

    m_vao.bind();
    glDrawArrays(GL_LINES, 0, 4);
    m_vao.release();
    m_program->release();
}


void MyOpenGLWidget::initializeGL()
{
    initializeOpenGLFunctions();
    glClearColor(1, 1, 1, 0.5);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_BLEND);

    m_vao.create();
    if (m_vao.isCreated())
        m_vao.bind();

    m_vbo.create();
    m_vbo.bind();
    m_vbo.setUsagePattern(QOpenGLBuffer::StreamDraw);
    m_vbo.allocate(sizeof(cube));

//...... setup m_program (QOpenGLShaderProgram) .....

    attributePos = m_program->attributeLocation("position");
    attributeColor = m_program->attributeLocation("color");

    int stride = 8 * sizeof(GLfloat);
    m_program->enableAttributeArray(attributePos);
    m_program->setAttributeBuffer(attributePos, GL_FLOAT, 0, 4, stride);

    m_program->enableAttributeArray(attributeColor);
    m_program->setAttributeBuffer(attributeColor, GL_FLOAT, 4 * sizeof(GLfloat), 4, stride);

    m_vbo.release();
    m_program->release();
    m_vao.release();
}


void MyOpenGLWidget::resizeGL(int w, int h){
    glViewport(0, 0, (GLsizei)w, (GLsizei)h);
}

问题排查与解决

  1. VBO数据未写入
    你调用了m_vbo.allocate(sizeof(cube)),但没有将cube数组的数据复制到VBO中。allocate仅分配内存空间,需用write方法写入数据:

    // 方式一:直接分配并写入
    m_vbo.allocate(cube, sizeof(cube));
    // 方式二:先分配再写入
    m_vbo.allocate(sizeof(cube));
    m_vbo.write(0, cube, sizeof(cube));
    

    这是核心问题——VBO内无顶点数据,自然无法绘制。

  2. 绘制模式问题
    当前使用GL_LINES绘制4个顶点,只会生成两条独立线段(0-1、2-3),无法形成完整正方形。应改用GL_LINE_LOOP(绘制闭合线框),若需填充四边形,OpenGL 3.2+核心模式已移除GL_QUADS,需用GL_TRIANGLE_FAN或拆分两个三角形:

    glDrawArrays(GL_LINE_LOOP, 0, 4);
    
  3. MVP矩阵的困惑
    直接将顶点坐标赋值给gl_Position,相当于使用正交投影且视锥体刚好覆盖[-1,1]的XYZ范围。你的顶点z值为-1,刚好处于默认近裁剪平面(-1),所以理论上能显示,但这种方式仅适用于简单2D或极小范围3D场景。
    实际3D场景中需要MVP矩阵处理透视投影、模型变换和视图变换,否则物体的缩放、旋转、远近关系会不符合预期。很多基础示例不使用MVP矩阵,是为了简化代码,聚焦顶点数据与着色器的基础流程。

  4. 混合与深度测试细节
    你开启了GL_BLEND但未设置混合函数,默认混合逻辑可能导致绘制内容被背景覆盖,可添加:

    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    

    同时背景glClearColor的alpha设为0.5可能导致异常,建议改为1.0:

    glClearColor(1, 1, 1, 1.0f);
    

内容的提问来源于stack exchange,提问作者symanoz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 16:20:48