All notes
Opengl

# Intro

• OpenGL is an API used for drawing 3D graphics.
• OpenGL is not a programming language.
• The API is typically used to interact with a GPU, to achieve hardware-accelerated rendering.

## Coordinates

Matrix44. There are multiple coordinate Systems involved in 3D Graphics:

• Object Space
• World Space (aka Model Space)
• Camera Space (aka Eye Space or View Space)
• Screen Space (aka Clip Space)

OpenGLWiki. The model matrix is used to describe where an object exists in the world. The view matrix is used to describe the vantage point of our view. The view matrix can be thought of as the position and angle of a camera used to take a picture. The projection matrix is used to give our view perspective such as making close objects appear larger than distant objects. The projection matrix also provides a field of view which can be thought of as a camera lens; you can decide to use a wide-angle lens or a telephoto lens.

Cartersian Space in 3D (left), and Object Space (right).

If we want to position the cube in World coordinates at position X=5, Y=0, Z=0, multiply each vertix with the World matrix

[1,0,0,5,
0,1,0,0,
0,0,1,0,
0,0,0,1]

• Multiply every vertex in the World Space with our View Matrix. Each Vertex is then in Camera Space – and the scene looks like we are looking at it through the camera.
• Imagine the camera as an abstract thing which is on the positive Z-Axis and looks down the negative end of the Z-Axis. Imagine also a rotation and translation of the World around you so that you can see what you want to see – this rotation and translation is the View Matrix.
• The last Coordinate System transformation is from Camera to Screen Space
• It is essentially nothing more than going from the 3D Coordinate System to the 2D Screen in front of us.
• This transformation is necessary as long as we don’t have real 3D Holographic Screens.
• In the process of transforming from Camera to Screen Space you can either choose a Orthographic or Perspective Projection. The difference between those two is that the Orthographic Projection does not apply a perspective distortion and the perspective one does. Perspective Projection is the natural one as we Humans see in a perspective Way – things farther away from us appear smaller.
• MODELVIEW Matrix. Because moving an Object around and “positioning the camera” is actually the same, people usually use this one matrix.

#### Viewing volume

FalloutSoftware. The Viewing Volume is also known as the Clipping volume or the Frustum. Here's the visual representation of the viewing volume.

There are two planes, the viewing plane and the far clipping plane. The viewing plane is actually the screen and the far plan indicates how far you can "see", whatever is behind the far clipping plane will not be visible. The viewing volume is the space between those two planes. The viewing volume is sometimes called clipping volume because you usually want to clip your polygons against it.

## VAOs, VBOs, Vertex and Fragment Shaders

• The OpenGL 3.2 core specification removes the majority of the fixed function pipeline previously used, and replaces it with a completely programmable architecture using shaders.
• A Vertex Array Object (VAO) is an object which contains one or more Vertex Buffer Objects and is designed to store the information for a complete rendered object.
• A Vertex Buffer Object (VBO) is a memory buffer in the high speed memory of your video card designed to hold information about vertices. In our example we have two VBOs, one that describes the coordinates of our vertices and another that describes the color associated with each vertex. VBOs can also store information such as normals, texcoords, indicies, etc.
• A Vertex Shader in OpenGL is a piece of C like code written to the GLSL specification which influences the attributes of a vertex.
• A Fragment Shader is similar to a Vertex Shader, but is used for calculating individual fragment colors. This is where lighting and bump-mapping effects are performed.
• The shaders are compilied and then chained together into a Shader Program.
• The shaders receive input data from our VAO through a process of attribute binding, allowing us to perform the needed computations to provide us with the desired results.

# Functions

Die. glrasterpos3f.

• Specify the raster position for pixel operations.
• The GL maintains a 3D position in window coordinates. This position, called the raster position, is used to position pixel and bitmap write operations. It is maintained with subpixel accuracy. See glBitmap, glDrawPixels, and glCopyPixels.
• The current raster position consists of three window coordinates ($x$, $y$, $z$), a clip coordinate value ($w$), an eye coordinate distance, a valid bit, and associated color data and texture coordinates.
• The $w$ coordinate is a clip coordinate, because $w$ is not projected to window coordinates. glRasterPos3 specifies object coordinate $x$, $y$, and $z$ explicitly, while $w$ is implicitly set to 1. glRasterPos2 uses the argument values for $x$ and $y$ while implicitly setting $z$ and $w$ to 0 and 1.
• The object coordinates presented by glRasterPos are treated just like those of a glVertex command: They are transformed by the current modelview and projection matrices and passed to the clipping stage.
• If the vertex is not culled, then it is projected and scaled to window coordinates, which become the new current raster position, and the GL_CURRENT_RASTER_POSITION_VALID flag is set.
• If the vertex is culled, then the valid bit is cleared and the current raster position and associated color and texture coordinates are undefined.
• Initially, the current raster position is (0, 0, 0, 1), the current raster distance is 0, the valid bit is set, the associated RGBA color is (1, 1, 1, 1), the associated color index is 1, and the associated texture coordinates are (0, 0, 0, 1). In RGBA mode, GL_CURRENT_RASTER_INDEX is always 1; in color index mode, the current raster RGBA color always maintains its initial value.
• The raster position is modified both by glRasterPos and by glBitmap.
• GL_INVALID_OPERATION is generated if glRasterPos is executed between the execution of glBegin and the corresponding execution of glEnd.

# Culling

• Triangle primitives after all transformation steps have a particular facing. This is defined by the order of the three vertices that make up the triangle, as well as their apparent order on-screen.
• Face culling allows non-visible triangles of closed surfaces to be culled before expensive Rasterization and Fragment Shader operations.
• To activate face culling, GL_CULL_FACE must first be enabled with glEnable​. By default, face culling is disabled.
• To select which side will be culled, use the following function: void glCullFace​(GLenum mode​);, mode​ can be set to GL_FRONT, GL_BACK, or GL_FRONT_AND_BACK. The latter will cull all triangles. This is different from glEnable(GL_RASTERIZER_DISCARD)​, as the latter will shut off all Primitives, while culling both faces will only cull triangles (since only they have faces). By default, GL_BACK is the face to be culled.

# FAQ

## GL3/gl3.h

• Various functions and enumerators were removed from OpenGL at version 3.1. The purpose of gl3.h is to provide a header that includes only the functions and enumerators relevant to 3.1 and above.
• If you're using GLEW, then you should not care about gl3.h; just use GLEW's headers and you'll be fine.
• OpenGL since version 3.2 has been divided into two specifications: core and compatibility. As the name suggests, compatibility means that all of the removed functions are restored. Core means that they're gone.
• On most platforms, you must specifically ask for an OpenGL core context, via wgl/glXCreateContextAttribs. If you do not, then you will get a compatibility context. MacOSX has a different way of dealing with it, primarily centered around the fact that they don't provide a compatibility implementation. You either get 2.1 or 3.2 core.

## OpenGL and Direct3D (DirectX)

Wikibooks gives a good reference on the comparison.

## GLUT

• GLUT is the utility toolkit that provides Window management for OpenGL applications and their interface with the operating system.
• GLUT started as a non-free library. Nowadays, free/open-source and portable alternatives such as FreeGLUT and OpenGLUT exist.

# Platforms

## Mac OS

Wikibooks. To use GLUT and OpenGL from within Xcode:

1. open Xcode located in "/Developer/Applications/"
2. choose "New Project" from the file menu
3. choose "Command Line Tool" under the Application template for Mac OS X
4. choose type "C++"
5. enter your desired project name and directory
6. Add frameworks: OpenGL and GLUT. Frameworks are stored in "/System/Library/Frameworks/", from there select and add GLUT & OpenGL.
When #including OpenGL & GLUT header files within Xcode, make sure to do so like this:
#include <OpenGL/gl.h>
#include <OpenGl/glu.h>
#include <GLUT/glut.h>

## CentOS

sudo yum -y install mesa-libGL
sudo yum -y install mesa-libGL-devel

# See what versions of mesa-libGl are available for your release
yum search --showduplicates mesa-libGL

# MESA

• Mesa3d. Mesa is an open-source implementation of the OpenGL specification - a system for rendering interactive 3D graphics.
• A variety of device drivers allows Mesa to be used in many different environments ranging from software emulation to complete hardware acceleration for modern GPUs.
• Mesa ties into several other open-source projects: the Direct Rendering Infrastructure (DRI) and X.org to provide OpenGL support to users of X on Linux, FreeBSD and other operating systems.
• Wikipedia. Mesa is a collection of free and open-source libraries that implement several rendering as well as video acceleration APIs related to hardware-accelerated 3D rendering, 3D computer graphics and GPGPU, the most prominent being OpenGL.
• Mesa is hosted at freedesktop.org.
• Additionally to the APIs, Mesa also harbors most of the available free and open-source graphics device drivers.

• Mesa is an open-source implementation of the OpenGL specification. OpenGL is a programming library for writing interactive 3D applications.
• Mesa 9.x supports the OpenGL 3.1 specification.
• Mesa serves as the OpenGL core for the open-source DRI drivers for X.org.

Wikipedia. The Direct Rendering Infrastructure (DRI) is a framework for allowing direct access to graphics hardware under the X Window System in a safe, efficient way. The main use of DRI is to provide hardware acceleration for the Mesa implementation of OpenGL. DRI has also been adapted to provide OpenGL acceleration on a framebuffer console without a display server running.

GLUT (OpenGL Utility Toolkit), freeglut is recommended. GLw (OpenGL widget library). Unless you're using very old Xt/Motif applications with OpenGL, you shouldn't need it.

#### Files

On Linux-based systems you'll want to follow the Linux ABI standard. Basically you'll want the following:

/usr/include/GL/gl.h - the main OpenGL header
/usr/include/GL/glu.h - the OpenGL GLU (utility) header
/usr/include/GL/glx.h - the OpenGL GLX header
/usr/include/GL/glext.h - the OpenGL extensions header
/usr/include/GL/glxext.h - the OpenGL GLX extensions header
/usr/include/GL/osmesa.h - the Mesa off-screen rendering header
/usr/lib/libGL.so - a symlink to libGL.so.1
/usr/lib/libGL.so.1 - a symlink to libGL.so.1.xyz
/usr/lib/libGL.so.xyz - the actual OpenGL/Mesa library. xyz denotes the Mesa version number.

#### Compilation

# Find the dir location.
find /usr -type d -name dri
# Usually, /usr/lib64/dri

# --prefix=usr: Install in /usr/lib and /usr/include.
./configure --prefix=/usr --libdir=/usr/lib64 --with-dri-driverdir=/usr/lib64/dir
sudo make install

#### libGLw.so complains about missing function

# Check what is missing.
ldd -r /usr/lib64/libGLw.so
linux-vdso.so.1 =>  (0x00007fff2a5ff000)
libGL.so.1 => /usr/lib64/libGL.so.1 (0x00007f72a2c27000)
libXt.so.6 => /usr/lib64/libXt.so.6 (0x00007f72a29c1000)
libX11.so.6 => /usr/lib64/libX11.so.6 (0x00007f72a2684000)
libc.so.6 => /lib64/libc.so.6 (0x00007f72a22f0000)
libnvidia-tls.so.346.59 => /usr/lib64/tls/libnvidia-tls.so.346.59 (0x00007f72a20ec000)
libnvidia-glcore.so.346.59 => /usr/lib64/libnvidia-glcore.so.346.59 (0x00007f729f411000)
libXext.so.6 => /usr/lib64/libXext.so.6 (0x00007f729f1ff000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f729effa000)
libSM.so.6 => /usr/lib64/libSM.so.6 (0x00007f729edf2000)
libICE.so.6 => /usr/lib64/libICE.so.6 (0x00007f729ebd6000)
libxcb.so.1 => /usr/lib64/libxcb.so.1 (0x00007f729e9b7000)
/lib64/ld-linux-x86-64.so.2 (0x000000332f200000)
libm.so.6 => /lib64/libm.so.6 (0x00007f729e733000)
libuuid.so.1 => /lib64/libuuid.so.1 (0x00007f729e52f000)
libXau.so.6 => /usr/lib64/libXau.so.6 (0x00007f729e32b000)
undefined symbol: xmPrimitiveClassRec	(/usr/lib64/libGLw.so)
undefined symbol: _XmStrings	(/usr/lib64/libGLw.so)

# Find what provides the missing piece.
for i in $(ls /usr/lib64/*.so); do echo "=========" echo$i
strings \$i | grep -i xmPrimitiveClassRec
done

# Ahh, so it is libXm.so!!!
# ======
# /usr/lib64/libXm.so
# xmPrimitiveClassRec