QOpenGLWidget Won't Draw Triangle

匿名 (未验证) 提交于 2019-12-03 00:44:02

问题:

So I'm trying to implement an editor for my game using Qt, and I can't seem to decipher how the QOpenGLWidget works. Right now, I just want to get a simple triangle to render, then I can worry about moving in all the rest of my stuff.

Right now, it will open the window, and, in the QOpenGLWidget, will clear to the custom color I set in the subclass (so I did promote it), but it won't draw the triangle described in the class below. I've tried following the Qt OpenGLWindow example as well as the examples in QOpenGLWidget and QOpenGLShaderProgram, I also checked every function that returns a bool to make sure they were all being executed properly, and they are, but still no triangle.

Did I miss a vital function call? Am I doing things in the absolute wrong way? Or is it something super subtle and strange with Qt?

Here's the header:

#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" "   }"; }; 

and the source:

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); } 

回答1:

You specified the vertices of your triangle in clockwise order. OpenGL expects them in counterclockwise order by default. Switch the 2nd and 3rd vertex and you should see your triangle



回答2:

You are allocating and setting the attributes of your VBO everytime you call paintGL. VBOs are so that you can just initialize them once and then use them many times. Then you can just bind your VAO in your paintGL, call glDrawArrays and then unbind your VAO. Also, unbinding/releasing your VBO and VAO should be done after the glDrawArrays and after you first set the attribute data. You don't need a VAO if you are only using one VBO. VAOs only purpose is to hold multiple VBOs.

You are calling enableAttributeArray instead of setAttributeBuffer.

I am not sure which of the above caused your triangle not to draw properly but I am almost certain it was one of them :).



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!