title: Why does QGLWidget only render a blank screen?
body: <p>I have used OpenGL in SDL before, but I have just started to learn QT. In QT, using OpenGL is proving to be somewhat of a pain. I have the following two files:</p>
  
  <p>main.cpp</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;QApplication&gt;
  #include "glwidget.hpp"
  #include &lt;QGLFormat&gt;
  
  int main(int args, char *argv[]) {
      QApplication app(args, argv);
  
      GLWidget openGLWidget;
      openGLWidget.show();
  
      return app.exec();
  }
  </code></pre>
  
  <p>glwidget.hpp</p>
  
  <pre><code>#include &lt;GL/glew.h&gt;
  #include &lt;QGLWidget&gt;
  class GLWidget : public QGLWidget {
      protected:
          void initializeGL();
          void paintGL();
  };
  
  void GLWidget::initializeGL() {
      if(glewInit() != GLEW_OK) {
          fprintf(stderr, "GLEW failed to initialize.");
      }   
  }
  void GLWidget::paintGL() {
      glClearColor(1, 0, 0, 1); 
      glClear(GL_COLOR_BUFFER_BIT);
      QGLWidget::swapBuffers();
  }
  </code></pre>
  
  <p>helloworld.pro</p>
  
  <pre><code>TEMPLATE = app 
  INCLUDEPATH += .
  LIBS += -lGL -lGLEW
  
  # Input
  SOURCES += main.cpp
  HEADERS += glwidget.hpp
  QT += widgets opengl
  </code></pre>
  
  <p>When I compile and run this, I get a window that has whatever was behind it at the time of creation imprinted on it. What I am expecting is a red screen. What am I missing?</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>I have edited my GLWidget implementation, and I got it to work. However, it only works when I call glDrawArrays (see the paintGL function below). In SDL, glDrawArrays wasn't necessary to see a blank colored screen. Without glDrawArrays, qt seems to ignore glClear() for some reason. Does anyone know why? </p>
  
  <pre><code>GLWidget::GLWidget(QGLWidget* parent) : QGLWidget(QGLFormat(), parent) {
  }
  
  void GLWidget::initializeGL() {
      if(glewInit() != GLEW_OK) {
          fprintf(stderr, "GLEW failed to initialize.");
      }   
      glClearColor(1, 0, 0, 1); 
      glClear(GL_COLOR_BUFFER_BIT);
      shaderProgram.addShaderFromSourceFile(QGLShader::Vertex, 
                                            "vertexShader.vert");
      shaderProgram.addShaderFromSourceFile(QGLShader::Fragment, 
                                            "fragmentShader.frag");
      shaderProgram.link();
      GLuint vertexBuffer; 
      glGenBuffers(1, &amp;vertexBuffer);
  }
  
  void GLWidget::paintGL() {
      shaderProgram.bind();
      glClearColor(1, 0, 0, 1); 
      glClear(GL_COLOR_BUFFER_BIT);
      setAutoBufferSwap(false);
      //glDrawArrays(GL_TRIANGLES, 0, 1);
      swapBuffers();
      shaderProgram.release();
  }
  
  void GLWidget::resizeGL(int width, int height) {
      if(height == 0) {
          height = 1;
      }   
  
      if(width == 0) {
          width = 1;
      }   
  
      glViewport(0, 0, width, height);
  }
  </code></pre>
  
  <p><strong>UPDATE 2</strong></p>
  
  <p>I thought that maybe Qt was doing something sneaky under the hood, and that if I did everything manually, I would get rid of the problem. But qt still somehow knows whether I am using a program or not, and whether I am using glDrawArrays or not. In the code below, taking out either glDrawArrays or glUseProgram makes the code not work. It must have something to do with what happens inside QGLContext. </p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;fstream&gt;
  #include &lt;string&gt;
  #include "glwidget.hpp"
  
  GLWidget::GLWidget(QWidget* parent) : QGLWidget(QGLFormat(), parent) {
  }
  
  void GLWidget::initializeGL() {
      if(glewInit() != GLEW_OK) {
          fprintf(stderr, "GLEW failed to initialize.");
      }
      glContext = this-&gt;context();
      if(!glContext-&gt;create()) {
          fprintf(stderr, "Failed to create context.\n");
      }
      glContext-&gt;makeCurrent();
      program = glCreateProgram();
      addShader(program, GL_VERTEX_SHADER, "vertexShader.vert");
      addShader(program, GL_FRAGMENT_SHADER, "fragmentShader.frag");
      linkProgram(program);
      setAutoBufferSwap(false);
  }
  
  void GLWidget::paintGL() {
      glUseProgram(program);
      glClearColor(1, 0, 0, 1);
      glClear(GL_COLOR_BUFFER_BIT);
  
      glDrawArrays(GL_TRIANGLES, 0, 1);
      glContext-&gt;swapBuffers();
      glUseProgram(0);
  }
  
  void GLWidget::resizeGL(int width, int height) {
      if(height == 0) {
          height = 1;
      }
  
      if(width == 0) {
          width = 1;
      }
  
      glViewport(0, 0, width, height);
  }  
  
  GLuint GLWidget::addShader(GLuint programID, GLuint shaderType, std::string fileName) {
      GLuint shader = glCreateShader(shaderType);
      std::ifstream file(fileName.c_str());
      std::string source = "";
  
      if(file.is_open()) {
          std::string line;
          while(getline(file, line)) {
              source += line + "\n";
          }
      } else {
          fprintf(stderr, "File %s failed to open.\n", fileName.c_str());
      }
      const char* sourceC = source.c_str();
      glShaderSource(shader, 1, &amp;sourceC, NULL);
  
      glCompileShader(shader);
      GLint compileStatus;
      glGetShaderiv(shader, GL_COMPILE_STATUS, &amp;compileStatus);
      if(compileStatus == GL_FALSE) {
          fprintf(stderr, "Shader %s failed to compile.\n", fileName.c_str());
          return 0;
      }
      glAttachShader(programID, shader);
      return shader;
  }
  
  void GLWidget::linkProgram(GLuint programID) {
      glLinkProgram(programID);
      GLint linkStatus;
      glGetProgramiv(programID, GL_LINK_STATUS, &amp;linkStatus);
      if(linkStatus == GL_FALSE) {
          fprintf(stderr,"Failed to link program.\n");
      }
  }
  </code></pre>