Rendering 2D shapes

Since we have already learned how to draw our first rectangle on the screen, we will further enhance it in this section. We will take the previous example and continue from there.

How to do it…

  1. First, go to the paintGL() function in mainwindow.cpp and replace the quad in the previous example with new code. This time, we draw a quad together with a triangle:
    void MainWindow::paintGL()
    {
      // Initialize clear color (cornflower blue)
      glClearColor(0.39f, 0.58f, 0.93f, 1.f);
    
      // Clear color buffer
      glClear(GL_COLOR_BUFFER_BIT);
    
      glBegin(GL_QUADS);
      glVertex2f(-0.5f, -0.5f);
      glVertex2f(0.5f, -0.5f);
      glVertex2f(0.5f, 0.5f);
      glVertex2f(-0.5f, 0.5f);
      glEnd();
    
      glBegin(GL_QUADS);
        glColor3f(1.f, 0.f, 0.f); glVertex2f(-0.8f, -0.8f);
        glColor3f(1.f, 1.f, 0.f); glVertex2f(0.3f, -0.8f);
        glColor3f(0.f, 1.f, 0.f); glVertex2f(0.3f, 0.3f);
        glColor3f(0.f, 0.f, 1.f); glVertex2f(-0.8f, 0.3f);
      glEnd();
    
      glBegin(GL_TRIANGLES);
        glColor3f(1.f, 0.f, 0.f); glVertex2f(-0.4f, -0.4f);
        glColor3f(0.f, 1.f, 0.f); glVertex2f(0.8f, -0.1f);
        glColor3f(0.f, 0.f, 1.f); glVertex2f(-0.1f, 0.8f);
      glEnd();
    
      glFlush();
    }
  2. Next, in the resizeGL() function, add the following code to adjust the viewport and orthographic view so that the rendered image correctly follows the window's aspect ratio:
    void MainWindow::resizeGL(int w, int h)
    {
      // Initialize Projection Matrix
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
    
      glViewport(0, 0, w, h);
    
      qreal aspectRatio = qreal(w) / qreal(h);
      glOrtho(-1 * aspectRatio, 1 * aspectRatio, -1, 1, 1, -1);
    }
  3. Then, in the resizeEvent() function, call the resize() function and force the main window to refresh the screen:
    void MainWindow::resizeEvent(QResizeEvent *event)
    {
      resizeGL(this->width(), this->height());
      this->update();
    }
  4. After that, in the initializeGL() function, we call resizeGL() once so that the aspect ratio of the first rendered image is correct (before any window resize event is triggered):
    void MainWindow::initializeGL()
    {
      resizeGL(this->width(), this->height());
    }
  5. Once you're done with that, compile and run the program. You should see something like this:
    How to do it…

How it works...

The geometric primitive types supported by OpenGL are points, lines, linestrips, line loops, polygons, quads, quad strips, triangles, triangle strips, and triangle fans. In this example, we drew a quad and a triangle, where each of the shapes is provided with a set of vertices and colors so that OpenGL knows how the shapes should be rendered. The rainbow color is created by giving a different color to each of the vertices. OpenGL will automatically interpolate the colors between each vertex and display it onscreen. The shape that gets rendered later will always appear in front of other shapes. In this case, the triangle is being rendered later and hence it appears in front of the rectangle.

We need to calculate the aspect ratio of the main window every time it's resized, so that the rendered image will not be stretched and result in an odd appearance. Always reset the projection matrix by calling glMatrixMode() and glLoadIdentity() before calling glViewport() and glOrtho() so that the shapes are being rendered correctly when resizing the main window. Without resetting the projection matrix, we will be using the matrices from the previous frame and hence producing the wrong projection.

Note

Remember to call update() when the window is being resized, otherwise the screen will not be updated.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.217.254.118