Control Keys

move to next slide (also Enter or Spacebar).
move to previous slide.
 d  enable/disable drawing on slides
 p  toggles between print and presentation view
CTRL  +  zoom in
CTRL  -  zoom out
CTRL  0  reset zoom

Slides can also be advanced by clicking on the left or right border of the slide.

OpenGL

  • Library with about 670 graphic commands
  • All function names begin with "gl"", for example, glClear(), glBegin()
  • Graphics commands are passed to the graphics card (or more exactly to its driver) and are running on the hardware
  • OpenGL thus allows faster display of interactive 3D graphics than pure CPU programming

OpenGL

  • The graphics commands are implemented by the graphics card driver and are therefore independent of
    • the graphics card hardware
    • the operating system
    • the employed window manager
  • Graphics commands are reasonably close to the hardware and sufficient to achieve the core functionality
  • Various libraries are based on OpenGL and allow programming at a higher level of abstraction

OpenGL Versionen

  • Since its introduction (1992) OpenGL has been continuously extended to support new functionality of graphics cards
    • OpenGL 1.0 (1992), OpenGL 1.1 (1997), OpenGL 1.2 (1998), OpenGL 1.3 (2001), OpenGL 1.4 (2002), OpenGL 1.5 (2003)
    • OpenGL 2.0 (2004), OpenGL 2.1 (2006)
    • OpenGL 3.0 (2008), OpenGL 3.1 (2009), OpenGL 3.2 (2009), OpenGL 3.3 (2010)
    • OpenGL 4.0 (2010), OpenGL 4.1 (2010), OpenGL 4.2 (2011), OpenGL 4.3 (2012), OpenGL 4.4 (2013), OpenGL 4.5 (2014)
  • In this lecture, OpenGL 2 is used and in later chapters OpenGL version ≥ 3.1 is utilized
  • Since version 3.1 the so-called "fixed-function-pipeline" is no longer supported, which means "shaders" must always be implemented
  • This makes it difficult to get started. Therefore, this lecture uses the "fixed-function-pipeline" (OpenGL 2) up to Chapter 9 "GLSL Shading Language"

OpenGL ES and WebGL

  • OpenGL ES is a version of OpenGL with reduced functionality
  • "ES" stands for "Enbedded Subsystem"", that is, target platforms are embedded systems such as mobile phones, televisions, tablets, etc.
    • OpenGL ES 1.0 (2003): similar to OpenGL 1.3 (fixed-function-pipeline)
    • OpenGL ES 1.1 (2004): similar to OpenGL 1.5 (backwards compatible)
    • OpenGL ES 2.0 (2007): similar to OpenGL 2.0 (but no fixed-function pipeline, always shader, not backwards compatible)
    • OpenGL ES 3.0 (2012): similar to OpenGL 3.3 (no geometry shader)
    • OpenGL ES 3.1 (2014): similar to OpenGL 4.3
    • OpenGL ES 3.2 (2015): similar to OpenGL 4.3
  • OpenGL ES is used for hardware-assisted graphics output on many smart phones (e.g., Apple's iPhone and Android-based devices)
  • WebGL is based on OpenGL ES 2.0 and allows 3D graphics on web pages (meanwhile supported by almost all browsers)

OpenGL Utility Library (GLU)

  • OpenGL Utility Library (GLU) was part of every OpenGL implementation up to version 3.0
  • GLU extends OpenGL by some functions (approx. 50) with a higher level of abstraction
  • Functions for drawing spheres, cylinders, or circles, camera functionality, texture functionality, etc.
  • In the current OpenGL versions GLU is no longer supported
  • The functionality must be either implemented by own code or provided by external libraries (see, e.g., glm library)

C/C++ Include Files

  • OpenGL defines its interfaces using C functions
  • For GL and GLU functions
    #include <GL/gl.h>
    #include <GL/glu.h>
  • Extensions
    #include <GL/glext.h>
  • Only OpenGL 3.1 functions (no fixed-function pipeline)
    #include <GL3/gl3.h>
    #include <GL3/gl3ext.h>

OpenGL Utility Toolkit (GLUT)

  • is a possible window manager for C/C++ programs
  • is not part of a standard installation and must be typically installed separately (freeglut)
  • provides the rendering context for OpenGL in which OpenGL functions can be called
  • handles mouse and keyboard input
  • provides a platform-independent interface
  • is included by
    #include <GL/freeglut.h>
    (Gl/gl.h and GL/glu.h are automatically included)

OpenGL Utility Toolkit (GLUT) as Window Manager

#include <GL/freeglut.h> // we use glut as window manager

class Renderer {
public:
  void init() {..}
  void resize(int w, int h) {...}
  void display() {...}
};

// static objects and callbacks
static Renderer *renderer;
static void glutResize(int w, int h) { 
  renderer->resize(w, h); 
}

static void glutDisplay() { 
  renderer->display(); 
  glutSwapBuffers(); 
}

int main(int argc, char **argv) {
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
  glutInitWindowPosition(100,100);
  glutInitWindowSize(320, 320);
  glutCreateWindow("WindowTitle");
  glutDisplayFunc(glutDisplay);
  glutReshapeFunc(glutResize);
  renderer = new Renderer;
  renderer->init();
  glutMainLoop();
}

Qt as Window Manager

  • As already discussed in Part 2, Chapter 3, Qt is a widely used class library for cross-platform development of GUIs (Qt website)
  • Qt can also be used in combination with OpenGL
  • To that end, the class QGLWidget must be overwritten
  • Furthermore, the corresponding QMake project file must be extended by the line "QT += opengl"
    QT += opengl
    TARGET = ApplicationName
    SOURCES += main.cpp Widget1.cpp Widget2.cpp
    HEADERS += Widget1.h Widget2.h
    

Qt as Window Manager

#include <QApplication>
#include <QGLWidget>

class Renderer {
public:
  void init() {..}
  void resize(int w, int h) {...}
  void display() {...}
};

class MyWidget : public QGLWidget {
private:
    Renderer *renderer;
public:
  MyWidget(QWidget *parent = NULL) : QGLWidget(parent) {
    this->setWindowTitle("OpenGL with Qt");
    this->resize(320, 320);
    renderer = new Renderer();
  }
  ~MyWidget() { delete renderer; }
protected:
  void initializeGL() { renderer->init(); }
  void resizeGL(int w, int h){ renderer->resize(w, h); }
  void paintGL() { renderer->display(); }
};

int main (int argc, char* argv[]) {
  QApplication appl(argc, argv);
  MyWidget widget;  // create a widget
  widget.show(); //show the widget and its children
  return appl.exec(); // execute the application
}

OpenGL and Java

  • Java can also be used in combination with OpenGL
  • For that purpose in this lecture JOGL (Java Binding for the OpenGL API) is used (JOGL website)
  • The OpenGL function calls have the same syntax as in C
  • JOGL needs to be installed in addition to the JDK (Installation instructions)

OpenGL and Java

Compilation: (in a shell)

javac -classpath "jar/gluegen-rt.jar;jar/jogl-all.jar" sourcefile.java

Execution:

java -classpath "jar/gluegen-rt.jar;jar/jogl-all.jar;." sourcefile

Java as Window Manager

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import com.jogamp.opengl.*;
import com.jogamp.opengl.awt.GLCanvas;
import com.jogamp.opengl.util.FPSAnimator;
import static com.jogamp.opengl.GL.*;  
import static com.jogamp.opengl.GL2.*;


class Renderer {
  public void init(GLAutoDrawable d) {...}
  public void resize(GLAutoDrawable d, int w, int h) {...}
  public void display(GLAutoDrawable d) {...}
}

class MyGui extends JFrame implements GLEventListener{
  private Renderer renderer;
 
  public void createGUI() {
    setTitle("JoglFirstTriangle");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   
    GLProfile glp = GLProfile.getDefault();
    GLCapabilities caps = new GLCapabilities(glp);
    GLCanvas canvas = new GLCanvas(caps);
    setSize(320, 320);
    getContentPane().add(canvas);
    final FPSAnimator ani = new FPSAnimator(canvas, 60, true);
    canvas.addGLEventListener(this);
    setVisible(true);
    renderer = new Renderer();
    ani.start();
  }

  @Override
  public void init(GLAutoDrawable d) { 
    renderer.init(d); 
  }

  @Override
  public void reshape(GLAutoDrawable d, int x, int y, 
                      int width, int height) { 
    renderer.resize(d, width, height); 
  }

  @Override
  public void display(GLAutoDrawable d) { 
     renderer.display(d); 
  }

  @Override
  public void dispose(GLAutoDrawable d) { }
}

public class JoglFirstTriangle {
  public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        MyGui myGUI = new MyGui();
        myGUI.createGUI();
      }
    });
  }
}

The first OpenGL program: Drawing a Triangle

  • Now that the different window managers (GLUT, Qt, Java) were introduced, a triangle will be drawn on the screen with OpenGL
  • In the following, only the functions init(), resize() and display() of the class Renderer are presented, which are completely independent of the employed window manager

The first OpenGL program: Drawing a Triangle

class Renderer {
public:
  void init() {}
  void resize(int w, int h) { glViewport(0, 0, w, h); }
  void display() {
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glLoadIdentity();
    glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);
    glColor3f(1.0f, 1.0f, 1.0f);
    glBegin(GL_TRIANGLES);
    glVertex2f(-0.5f, -0.5f); // vertex on the left
    glVertex2f( 0.5f, -0.5f); // vertex on the right
    glVertex2f( 0.0f,  0.5f); // vertex at the top of the triangle
    glEnd();
  }
};

The first OpenGL program: Drawing a Triangle

opengl_triangle

OpenGL as a State Machine

  • While drawing, OpenGL behaves like a state machine, where the current state influences the output
  • For example, the instruction glColor(...) sets the current drawing color
  • This state remains active until it is changed by another graphics command, e.g, until the next call of glColor(...)

OpenGL as a State Machine

  • OpenGL can push certain combinations of states by glPushAttrib() onto a stack and later re-active them by popping them from the stack with glPopAttrib()
... // draw something here
glPushAttrib(GL_LINE_BIT);    
  glEnable(GL_LINE_SMOOTH);       
  glEnable(GL_LINE_STIPPLE); 
glPushAttrib(GL_COLOR_BUFFER_BIT);
  glEnable(GL_BLEND);
  glDisable(GL_DITHER);
... // drawing something special here
glPopAttrib(); // restore GL_COLOR_BUFFER_BIT
glPopAttrib(); // restore GL_LINE_BIT
... // draw more here

OpenGL-Pipeline

openglpipeline
openglpipeline
openglpipeline
openglpipeline
openglpipeline
openglpipeline
openglpipeline
Source: based on Mark Segal, Kurt Akeley, The OpenGL Graphics System: A Specification Version 2.0, 2004, Figure 2.1. Block diagram of the GL (modified)

OpenGL-Pipeline

  • In the following slides, the individual building blocks of the OpenGL pipeline are explained
  • Currently the aim is only to obtain a rough overview
  • Details will follow in later parts of the lecture

Framebuffer

  • The framebuffer is the "canvas" on which OpenGL draws
  • The framebuffer is a raster graphics, i.e., it has a certain width and height and contains pixels that are arranged on a fixed grid
  • Later, we will learn that OpenGL can draw in multiple attached framebuffers at the same time

Vertex Data

  • A vertex is a coordinate point of graphic object, such as a line, triangle, or polygon
  • With glVertex(...) the vertices are passed individually
    glBegin(GL_TRIANGLES);
    glVertex2f(-0.5f, -0.5f); // vertex on the left
    glVertex2f( 0.5f, -0.5f); // vertex on the right
    glVertex2f( 0.0f,  0.5f); // vertex at the top of the triangle
    glEnd();
  • Later in this lecture, we will get to know techniques that will allow us to pass large memory blocks containing vertex data to the OpenGL pipeline

Evaluators

  • Instead of defining graphic objects by vertex data, a parametric descriptions can be used, e.g. by defining control points of parametric curves or surfaces
  • Evaluators convert the parametric description into vertex data, so that the rest of the pipeline can always work with vertex data
curve
curve
control point
vertex data

Per-Vertex Operations

  • In this step, a series of operations is performed for each vertex
  • When using the fixed-function pipeline these comprise, for example,
    • The transformation from the global world-coordinate system in the camera coordinate system and projection in the camera image plane
    • Generation of normals or texture coordinates and their transformation
    • Calculation of a vertex color for a given lighting
  • When using shaders, this step is implemented by means of a so-called vertex shader

Primitiv Assembly

  • While assembling primitives the vertex data can be used in different ways. This dependents on the argument that is passed to glBegin(...)
prim_types

Primitiv Assembly

  • Furthermore, in this step, 3D clipping operations are performed. By clipping, additional vertex points can be generated.
  • Then a perspective division is performed, which generates the perspective 2D projection of the objects
  • Hidden primitives can be removed
  • Then the 2D coordinates are scaled and/or shifted according to the selected image resolution and position
  • The generated primitives now know their 2D coordinates (real numbers) in the frame buffer and are transferred to the 2D rasterizer

Pixel Data

  • OpenGL is able to process raster graphics
  • In addition, raster images are often used as textures ("color wallpaper")
  • It is also possible to use the image from the frame buffer as input for a secondary rendering pass

Pixel Operations

  • Pixel data are converted from the main memory of the computer into a particular OpenGL storage format
  • Image manipulations can be performed such as zoom in, zoom out, turn the image, manipulate color values, apply filters, etc.
  • Many of these operations are part of the fixed-function pipeline and are nowadays generally realized by texture and framebuffer objects

Texture Assembly

  • Pixel data can also be used as textures
  • Textures are stored in texture objects, which are equipped with an ID (key) and can be referenced and reused
  • That is, for generation of a texture the pixel data must be transferred only once from the computer's main memory onto the graphics card memory and stays available there
  • The graphics card hardware supports fast access to textures

Rasterizer

  • The rasterizer converts the processed vertex or pixel data in so-called fragments
  • Even on modern graphics hardware (with programmable shader units) the raster conversion is still realized by dedicated hardware
  • Each fragment knows its interpolated color value, depth value, and possibly its texture coordinate

Per-Fragment Operations

  • Before the fragment data ends up as pixel values in the framebuffer, a series of operations for each fragment is performed
  • When using the fixed-function pipeline these comprise, for example,
    • Texturing
    • Color generation or manipulation
    • Fog
  • When using shaders, this step can be implemented by means of a so-called fragment shader

Per-Fragment Operations

  • The resulting fragment is then passed through a few more (optional) processing steps until the information reaches the framebuffer:
  1. Scissor-Test
  2. Alpha-Test
  3. Depth-Test
  4. Stencil-Test
  5. Blending
  6. Dithering
  7. Logical operations

Are there any questions?

questions

Please notify me by e-mail if you have questions, suggestions for improvement, or found typos: Contact

More lecture slides

Slides in German (Folien auf Deutsch)