【问题标题】:QOpenGLWidget Won't Draw TriangleQOpenGLWidget不会画三角形
【发布时间】:2015-05-07 02:17:05
【问题描述】:

所以我正在尝试使用 Qt 为我的游戏实现一个编辑器,但我似乎无法理解 QOpenGLWidget 是如何工作的。现在,我只想得到一个简单的三角形来渲染,然后我可以担心移动我所有的其他东西。

现在,它将打开窗口,并且在 QOpenGLWidget 中,将清除我在子类中设置的自定义颜色(所以我确实推广了它),但它不会绘制下面类中描述的三角形.我已经尝试遵循 Qt OpenGLWindow 示例以及 QOpenGLWidget 和 QOpenGLShaderProgram 中的示例,我还检查了每个返回 bool 的函数以确保它们都被正确执行,它们是,但仍然没有三角形。

我错过了一个重要的函数调用吗?我是否以绝对错误的方式做事?还是 Qt 有一些非常微妙和奇怪的东西?

这是标题:

#include<qopenglwidget.h>
#include<QtGui/qopenglfunctions.h>

class EditorViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
public:
    EditorViewWidget(QWidget *parent);
protected:
    void initializeGL();
    void resizeGL(int w, int h);
    void paintGL();
    QOpenGLShaderProgram* shaderProgram;
    QOpenGLVertexArrayObject vao;
    QOpenGLBuffer VBO;
    int position_attribute;
    int color_uniform;
    float Vertices[9];
    const char* vert="#version 150          \n"
"                                           \n"
"   in vec3 position;                       \n"
"                                           \n"
"   void main()                             \n"
"   {                                       \n"
"       gl_Position = vec4(position, 1.0);  \n"
"   }";
    const char* frag="#version 150          \n"
"                                           \n"
"   uniform vec3 Color;                     \n"
"   out vec4 outColor;                      \n"
"                                           \n"
"   void main()                             \n"
"   {                                       \n"
"       outColor = vec4(Color, 1.0);        \n"
"   }";
};

来源:

EditorViewWidget::EditorViewWidget(QWidget* parent)
    :QOpenGLWidget(parent)
{
    float v[] = {
        0.0, 0.5, 0.0,
        0.5, -0.5, 0.0,
        -0.5, -0.5, 0.0
    };
    for (int i = 0; i < 9; i++)
        Vertices[i] = v[i];
}

void EditorViewWidget::initializeGL()
{
    initializeOpenGLFunctions();
    vao.create();
    vao.bind();

    //glGenBuffers(1, &VBO);
    glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
    shaderProgram = new QOpenGLShaderProgram(this);
    shaderProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, vert);
    shaderProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, frag);
    shaderProgram->link();
    shaderProgram->bind();
    position_attribute = shaderProgram->attributeLocation("position");
    color_uniform = shaderProgram->uniformLocation("Color");
    VBO.create();
    VBO.bind();
    VBO.allocate(&Vertices, 9*sizeof(float));
    shaderProgram->enableAttributeArray(position_attribute);
    shaderProgram->setAttributeArray(position_attribute, Vertices, 3);
    shaderProgram->setUniformValue(color_uniform, 1.0f, 1.0f, 1.0f);
    //glVertexAttribPointer(position_attribute, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
}

void EditorViewWidget::resizeGL(int w, int h)
{
}

void EditorViewWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT);
    VBO.bind();
    VBO.allocate(&Vertices, 9 * sizeof(float));
    shaderProgram->enableAttributeArray(position_attribute);
    shaderProgram->setAttributeArray(position_attribute, Vertices, 3, 0);
    shaderProgram->setUniformValue(color_uniform, 1.0f, 1.0f, 1.0f);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    shaderProgram->disableAttributeArray(position_attribute);
}

【问题讨论】:

  • 提示:仔细查看用于将顶点数据从v 复制到Verticesfor 循环。
  • ......真的吗?......好吧,修正了这个愚蠢的错误,但它仍然不起作用。在我有一个 for 循环之前,我使用的是 std::copy,但我切换只是因为这似乎更易于调试。

标签: c++ qt opengl


【解决方案1】:

您按顺时针顺序指定了三角形的顶点。默认情况下,OpenGL 期望它们按逆时针顺序排列。切换第二个和第三个顶点,你应该会看到你的三角形

【讨论】:

  • 我没有看到代码中启用了背面剔除,所以这应该没什么区别。
  • 有点死灵,嗯?我必须在某个时候去挖掘这段代码,看看它是否那么简单。如果是这样,我会非常难过,因为这不工作让我为这个作业丢了一个字母等级。 >_
  • 是的,进一步看,默认是CCW,但我读过的教程是使用CW order。这可能是整个时间的问题。 :|这实际上解释了我在游戏引擎中遇到的很多问题。
【解决方案2】:

每次调用paintGL 时,您都在分配和设置VBO 的属性。 VBO 是这样的,您可以只初始化它们一次,然后多次使用它们。然后你可以在你的paintGL中绑定你的VAO,调用glDrawArrays然后解开你的VAO。此外,应在 glDrawArrays 之后和首次设置属性数据之后完成 VBO 和 VAO 的解除绑定/释放。如果您只使用一个 VBO,则不需要 VAO。 VAO 的唯一目的是持有多个 VBO。

您正在调用 enableAttributeArray 而不是 setAttributeBuffer。

我不确定上述哪一项导致您的三角形无法正确绘制,但我几乎可以肯定它是其中之一:)。

【讨论】:

  • 至少如果enableAttributeArray()glEnableAttributeArray() 的包装,则第二部分不正确。此调用绝对与 VBO 一起使用。问题很可能是它应该使用setAttributeBuffer() 而不是setAttributeArray()
  • @RetoKoradi 我从我的答案中删除了这部分,因为我只看到它使用了我所说的但你可能是对的。
猜你喜欢
  • 1970-01-01
  • 2015-10-09
  • 2015-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-04
相关资源
最近更新 更多