|   | 40 |  | 
                  
                          |   | 41 | [[Image(OpenGL-pipeline.svg, right)]] | 
                  
                          |   | 42 | Modern OpenGL changed previously fixed rendering pipeline to fully | 
                  
                          |   | 43 | programmable graphics pipeline as shown in Fig.1 | 
                  
                          |   | 44 | Processors that transform input vertex data to the window context at the | 
                  
                          |   | 45 | end are called ''shaders''. The Vertex shader and the Fragment shader | 
                  
                          |   | 46 | are most important in the rendering pipeline. To use rendering pipeline as | 
                  
                          |   | 47 | shown in Fig.1 one has to provide program for them | 
                  
                          |   | 48 | as there is no default because they are essential part of every OpenGL | 
                  
                          |   | 49 | program. Programming shaders is done in GLSL (OpenGL Shading Language) that | 
                  
                          |   | 50 | is similar to C language with some predefined variables and reserved | 
                  
                          |   | 51 | keywords that help describing communication between OS and GPU. Programs | 
                  
                          |   | 52 | (for shaders) written in GLSL are compiled on-the-fly, assembled and | 
                  
                          |   | 53 | transferred to GPU for execution. | 
                  
                          |   | 54 |  | 
                  
                          |   | 55 | OpenGL is designed as a hardware-independent interface between the program | 
                  
                          |   | 56 | code and graphics accelerator. Hardware independence of OpenGL means also | 
                  
                          |   | 57 | that in the language specification there is no support for control of | 
                  
                          |   | 58 | window system events that occur with interactive programming. For such | 
                  
                          |   | 59 | interactive control for each operating system were designed interfaces that | 
                  
                          |   | 60 | connect the machine with the OpenGL system. Due to the specifics of | 
                  
                          |   | 61 | different window systems (Windows, XWindow, MacOS, iOS, Android) it is | 
                  
                          |   | 62 | required that for each system tailored techniques are used to call OpenGL | 
                  
                          |   | 63 | commands in hardware. Portability is thus limited by graphical user | 
                  
                          |   | 64 | interface (GUI) that handles OpenGL context (window). In order to still be | 
                  
                          |   | 65 | able to write ''portable programs'' with otherwise limited functionality | 
                  
                          |   | 66 | of the user interface, GLUT library (OpenGL Utility Toolkit) was created. | 
                  
                          |   | 67 | It compensates all the differences between operating systems and introduces | 
                  
                          |   | 68 | a unified methods of manipulating ''events''. With the GLUT library it | 
                  
                          |   | 69 | is possible to write portable programs that are easy to write and have | 
                  
                          |   | 70 | sufficient capacity for simple user interfaces. | 
                  
                          |   | 71 |  | 
                  
                          |   | 72 | == Legacy OpenGL coding == | 
                  
                          |   | 73 | Basics of the OpenGL language are given in the (core) GL library. More | 
                  
                          |   | 74 | complex primitives can be build by the GLU library (GL Utility) which | 
                  
                          |   | 75 | contain the routines that use GL routines only. GLU routines contain | 
                  
                          |   | 76 | multiple GL commands that are generally applicable and have therefore been | 
                  
                          |   | 77 | implemented to ease OpenGL programming. | 
                  
                          |   | 78 |  | 
                  
                          |   | 79 | To get quickly introduced into OpenGL it is better to start with legacy | 
                  
                          |   | 80 | (short and simple) program that will be later replaced with modern OpenGL | 
                  
                          |   | 81 | after discussion that caused replacement with OpenGL 3.x. Before we can | 
                  
                          |   | 82 | dive in OpenGL we need to revise windowing systems and how they interact | 
                  
                          |   | 83 | with users. | 
                  
                          |   | 84 |  | 
                  
                          |   | 85 | == Events == | 
                  
                          |   | 86 | All window interfaces (GUI) are designed to operate on the principle of | 
                  
                          |   | 87 | ''events''. Events are signals from the Window system to our program. | 
                  
                          |   | 88 | Our program is fully responsible for the content of the window. Windowing | 
                  
                          |   | 89 | system only assigns area (window). The contents of the window area must | 
                  
                          |   | 90 | then be fully controlled. In addition to the window assignment the | 
                  
                          |   | 91 | windowing system to sends messages (events) to our program. The most common | 
                  
                          |   | 92 | messages are: | 
                  
                          |   | 93 |  display:: The command asks for presentation of window contents. There | 
                  
                          |   | 94 |   are several possible occasions when this happens. For example, when | 
                  
                          |   | 95 |   another window reveals part of our window or when window is moved on the | 
                  
                          |   | 96 |   screen. Another example is when window is re-displayed after icon is | 
                  
                          |   | 97 |   being pressed at the taskbar. Interception of such events is mandatory, | 
                  
                          |   | 98 |   because every program must ensure that the contents of the window is | 
                  
                          |   | 99 |   restored window, when such event occurs. | 
                  
                          |   | 100 |  reshape:: Command to our program that occurs when the size and/or | 
                  
                          |   | 101 |   shape of the window changes. In this case the content of the window must | 
                  
                          |   | 102 |   be provided for a new window size. Event occurs, inter alia, when the | 
                  
                          |   | 103 |   mouse resizes the window. Immediately after reshape, display event is | 
                  
                          |   | 104 |   sent. | 
                  
                          |   | 105 |  keyboard:: Commands coming from the keyboard.  | 
                  
                          |   | 106 |  mouse:: Describes the mouse buttons at their change when user pressed | 
                  
                          |   | 107 |   or released one of the buttons. | 
                  
                          |   | 108 |  motion:: This command defines the motion tracking of the moving mouse | 
                  
                          |   | 109 |   with pressed button. | 
                  
                          |   | 110 |  timer:: Program requests message after a certain time in order to | 
                  
                          |   | 111 |   change the contents of the window. The function is suitable for timed | 
                  
                          |   | 112 |   simulation (animation). | 
                  
                          |   | 113 | In addition to these events there exist some other too. In general it is | 
                  
                          |   | 114 | not necessary that all events to a window are implemented in our program. | 
                  
                          |   | 115 | It is our responsibility to decide which | 
                  
                          |   | 116 | events will be used in the application. Usually program must notify | 
                  
                          |   | 117 | windowing system which events will took over and for that window will | 
                  
                          |   | 118 | receive events. | 
                  
                          |   | 119 |  | 
                  
                          |   | 120 | == GLUT == | 
                  
                          |   | 121 | For an abstraction of events (commands from the windowing system) we will | 
                  
                          |   | 122 | use GLUT library (OpenGL Utility Toolkit). Many other GUI libraries are | 
                  
                          |   | 123 | available (native and portable). GLUT falls into the category of simple | 
                  
                          |   | 124 | operating/windowing system independent GUIs for OpenGL. An example of a | 
                  
                          |   | 125 | minimal program that draws a single line is shown in Listing 1 (first.c). | 
                  
                          |   | 126 | \lstinputlisting[caption=Drawing a line with OpenGL and GLUT., | 
                  
                          |   | 127 | label=first.c ]{first.c} Program in C language consists of two parts: the | 
                  
                          |   | 128 | subroutine display and the main program. Program runs from the start in | 
                  
                          |   | 129 | {{{main()}}} and at the end falls into endless loop | 
                  
                          |   | 130 | {{{glutMainLoop}}} that calls registered subroutines when event | 
                  
                          |   | 131 | occurs. Before falling into {{{glutMainLoop}}} we need to prepare drawing | 
                  
                          |   | 132 | context. | 
                  
                          |   | 133 | {{{ | 
                  
                          |   | 134 | #!c | 
                  
                          |   | 135 | #include <GL/glut.h> | 
                  
                          |   | 136 |  | 
                  
                          |   | 137 | void display() | 
                  
                          |   | 138 | { | 
                  
                          |   | 139 |   glClear(GL_COLOR_BUFFER_BIT); | 
                  
                          |   | 140 |   glColor3f(1.0, 0.4, 1.0); | 
                  
                          |   | 141 |   glBegin(GL_LINES); | 
                  
                          |   | 142 |     glVertex2f(0.1, 0.1); | 
                  
                          |   | 143 |     glVertex3f(0.8, 0.8, 1.0); | 
                  
                          |   | 144 |   glEnd(); | 
                  
                          |   | 145 |   glutSwapBuffers(); | 
                  
                          |   | 146 | } | 
                  
                          |   | 147 |  | 
                  
                          |   | 148 | int main(int argc, char *argv[]) | 
                  
                          |   | 149 | { | 
                  
                          |   | 150 |   glutInit(&argc,argv); | 
                  
                          |   | 151 |   glutInitDisplayMode(GLUT_DOUBLE); | 
                  
                          |   | 152 |   glutCreateWindow("first.c GL code"); | 
                  
                          |   | 153 |   glutDisplayFunc(display); | 
                  
                          |   | 154 |   glutMainLoop(); | 
                  
                          |   | 155 |   return 0; | 
                  
                          |   | 156 | }   | 
                  
                          |   | 157 | }}} | 
                  
                          |   | 158 | {{{ | 
                  
                          |   | 159 | #!python | 
                  
                          |   | 160 | from OpenGL.GLUT import * | 
                  
                          |   | 161 | from OpenGL.GL import * | 
                  
                          |   | 162 | import sys | 
                  
                          |   | 163 |  | 
                  
                          |   | 164 | def display(): | 
                  
                          |   | 165 |     glClear(GL_COLOR_BUFFER_BIT) | 
                  
                          |   | 166 |     glColor3f(1.0, 0.4, 1.0) | 
                  
                          |   | 167 |     glBegin(GL_LINES) | 
                  
                          |   | 168 |     glVertex2f(0.1, 0.1) | 
                  
                          |   | 169 |     glVertex3f(0.8, 0.8, 1.0) | 
                  
                          |   | 170 |     glEnd() | 
                  
                          |   | 171 |     glutSwapBuffers() | 
                  
                          |   | 172 |  | 
                  
                          |   | 173 | if __name__ == "__main__": | 
                  
                          |   | 174 |     glutInit(sys.argv) | 
                  
                          |   | 175 |     glutInitDisplayMode(GLUT_DOUBLE) | 
                  
                          |   | 176 |     glutCreateWindow("first.py GL code") | 
                  
                          |   | 177 |     glutDisplayFunc(display) | 
                  
                          |   | 178 |     glutMainLoop() | 
                  
                          |   | 179 | }}} | 
                  
                          |   | 180 |  | 
                  
                          |   | 181 | Structure of the program is usually very similar for | 
                  
                          |   | 182 | all languages. Confer Listing 2 (first.py) rewritten in Python. All GLUT | 
                  
                          |   | 183 | programs include commands in the following order: | 
                  
                          |   | 184 |  | 
                  
                          |   | 185 |  *Include definitions of constants and functions for OpenGL and GLUT | 
                  
                          |   | 186 |   with the include statement. | 
                  
                          |   | 187 |  * Initialize GLUT and setup other variables that are not directly | 
                  
                          |   | 188 |   related to OpenGL but rather to the object that is being visualized. | 
                  
                          |   | 189 |  * Set window parameters such as initial position, size, type, bit plane | 
                  
                          |   | 190 |   memory. | 
                  
                          |   | 191 |  * Create the window and name it. | 
                  
                          |   | 192 |  * Setup the features of the OpenGL machine. These are usually commands | 
                  
                          |   | 193 |   {{{glEnable}}} for setup of lighting, materials, lists, and non-default | 
                  
                          |   | 194 |   behavior of OpenGL machine. | 
                  
                          |   | 195 |  * Register call-back routines which will be called at events. Mandatory | 
                  
                          |   | 196 |   registration is just for {{{glutDisplayFunc(display)}}}. The rest are | 
                  
                          |   | 197 |   optional. | 
                  
                          |   | 198 |  * The last command in {{{main" is a call to "glutMainLoop}}}, from which | 
                  
                          |   | 199 |   the program returns when the window is closed. At the same time the | 
                  
                          |   | 200 |   {{{main}}} program ends. | 
                  
                          |   | 201 |  | 
                  
                          |   | 202 |  | 
                  
                          |   | 203 | The command {{{glutInit}}} initializes GLUT library routines. It is followed by | 
                  
                          |   | 204 | a request for window creation of a certain type. The constant {{{GLUT_DOUBLE}}} | 
                  
                          |   | 205 | and the default {{{GLUT_RGB}}} suggests that we want a double-buffered window | 
                  
                          |   | 206 | with a RGB space. Variable {{{window}}} keeps reference of window returned by | 
                  
                          |   | 207 | {{{glutCreateWindow}}} and at the same time instructs the OS to set the window | 
                  
                          |   | 208 | title. We have to tell to the window system which events the program will | 
                  
                          |   | 209 | intercept. For example given, this is only {{{display}}} of the contents of the | 
                  
                          |   | 210 | window. Call of the subroutine {{{glutDisplayFunc}}} instructs the | 
                  
                          |   | 211 | {{{glutMainLoop}}} that whenever requests from OS for window redisplay occurs | 
                  
                          |   | 212 | subroutine {{{display}}} should be called. Routines for handling events are | 
                  
                          |   | 213 | usually called ``call-back'' routines as it reside in program as standalone | 
                  
                          |   | 214 | code snippets that are called auto-magically at certain events from the | 
                  
                          |   | 215 | windowing system. When some event occurs is up to the windowing system that | 
                  
                          |   | 216 | follows user interaction. The main point to emphasize here is that | 
                  
                          |   | 217 | registered call-back routines do get additional information on the kind of | 
                  
                          |   | 218 | event. For example of keyboard event we can get also mouse (x,y) | 
                  
                          |   | 219 | coordinates besides the key pressed. | 
                  
                          |   | 220 |  | 
                  
                          |   | 221 |  | 
                  
                          |   | 222 | We have seen that the subroutine {{{display}}} includes commands responsible | 
                  
                          |   | 223 | for drawing in the window. All routines or functions there are OpenGL and | 
                  
                          |   | 224 | have prefix {{{gl}}} to the name. Prefix is necessary to distinguish them and | 
                  
                          |   | 225 | prevent name clash with other libraries. To understand the language one can | 
                  
                          |   | 226 | interpret function names without prefixes and suffixes as the OpenGL is | 
                  
                          |   | 227 | designed so, that the types of the arguments for all programming languages | 
                  
                          |   | 228 | are similar. Subroutine {{{display}}} is therefore responsible for drawing the | 
                  
                          |   | 229 | contents of the window. The {{{glClear}}} command clears the entire area of the | 
                  
                          |   | 230 | window. When clearing we need to define precisely what we want to clear by | 
                  
                          |   | 231 | argument given. In our case, this is {{{GL_COLOR_BUFFER_BIT}}}, which means | 
                  
                          |   | 232 | clearing of all pixels in the color buffer. | 
                  
                          |   | 233 |  | 
                  
                          |   | 234 | The {{{glColor}}} command to sets the current color of graphic elements that | 
                  
                          |   | 235 | will be drawn in subsequent commands. As an argument RGB color components | 
                  
                          |   | 236 | are passed. Usually commands with multiple arguments are provide for | 
                  
                          |   | 237 | different data types (integer, float, double) and some command can have | 
                  
                          |   | 238 | different number of arguments for the same command. To distinguish them | 
                  
                          |   | 239 | suffix is added. For the {{{glColor3f}}} suffix {{{3f}}} therefore means that the | 
                  
                          |   | 240 | subroutine has three arguments of type float. Choice of the arguments type | 
                  
                          |   | 241 | depends on application requirements. Programmer can freely choose data type | 
                  
                          |   | 242 | that suits most without the need of data type conversion. In our example we | 
                  
                          |   | 243 | have two variants for vertex command with different number of arguments of | 
                  
                          |   | 244 | the same type. {{{glVertex2f}}} means that we are specifying just two | 
                  
                          |   | 245 | coordinates while the third is by default z=0. Types of the arguments | 
                  
                          |   | 246 | specified as the suffix letter are as follows: | 
                  
                          |   | 247 |  f:: float in C language and {{{real*4}}} in Fortran. | 
                  
                          |   | 248 |  d:: double for C and {{{real*8}}} in Fortran. | 
                  
                          |   | 249 |  i:: integer (4 bytes). | 
                  
                          |   | 250 |  s:: short integer in C and {{{integer*2}}} in Fortran. | 
                  
                          |   | 251 | Besides fixed number of arguments there are also functions that take as an | 
                  
                          |   | 252 | argument vector (as a pointer to memory). For these the suffix contains | 
                  
                          |   | 253 | letter {{{v}}} at the end. Below are some interpretations of suffixes: | 
                  
                          |   | 254 |  3f:: Three arguments of {{{real}}}s follow as arguments. | 
                  
                          |   | 255 |  3i:: Three arguments of {{{integer}}}s follow as arguments. | 
                  
                          |   | 256 |  3fv:: One argument as a vector that contains three {{{float}}}s | 
                  
                          |   | 257 |   follows. | 
                  
                          |   | 258 | Variety of different arguments for the same command can be in {{{glVertex}}} | 
                  
                          |   | 259 | command where we can find | 
                  
                          |   | 260 | {{{ | 
                  
                          |   | 261 | #!c | 
                  
                          |   | 262 |   glVertex2d,  glVertex2f,  glVertex2i, glVertex2s,  glVertex3d,  glVertex3f, | 
                  
                          |   | 263 |   glVertex3i,  glVertex3s,  glVertex4d, glVertex4f,  glVertex4i,  glVertex4s, | 
                  
                          |   | 264 |   glVertex2dv, glVertex2fv, glVertex2iv,glVertex2sv, glVertex3dv, glVertex3fv, | 
                  
                          |   | 265 |   glVertex3iv, glVertex3sv, glVertex4dv,glVertex4fv, glVertex4iv, glVertex4sv. | 
                  
                          |   | 266 | }}} | 
                  
                          |   | 267 | Large number of routines for the same function is performance and language | 
                  
                          |   | 268 | related in order to waive the default conversion and thus provide a more | 
                  
                          |   | 269 | comprehensive and faster code. For languages with name mangling like C++ | 
                  
                          |   | 270 | one can find simpler OpenGL wrapped functions (eg. just {{{glVertex}}}) that | 
                  
                          |   | 271 | don't affects performance. But as many languages does not have name | 
                  
                          |   | 272 | mangling built into compiler such practise is not widespread. Besides | 
                  
                          |   | 273 | specifying single vertex each time one can use {{{glVertexPointer}}} and points | 
                  
                          |   | 274 | to memory where number of vertices of specified type exist. This can save | 
                  
                          |   | 275 | us of some looping, but as this is essentially copying of system memory | 
                  
                          |   | 276 | into OpenGL hardware engine, the performance is not really improved. | 
                  
                          |   | 277 |  | 
                  
                          |   | 278 | Drawing of graphic primitives in OpenGL occurs between two commands | 
                  
                          |   | 279 | {{{glBegin(primitive type)}}} and {{{glEnd()}}}. Primitive type given as argument | 
                  
                          |   | 280 | at the beginning specifies how subsequent vertices will be used for | 
                  
                          |   | 281 | primitive generation. Instead of giving primitive type as number several | 
                  
                          |   | 282 | predefined constant are provided within {{{include}}} directive to ease | 
                  
                          |   | 283 | readability and portability of the OpenGL programs. Before providing vertex | 
                  
                          |   | 284 | position one can change OpenGL engine primitive state such as current | 
                  
                          |   | 285 | drawing {{{glColor3f" or "glNormal}}} that is per vertex property. | 
                  
                          |   | 286 |  | 
                  
                          |   | 287 | The last command in the {{{display}}} subroutine is {{{glutSwapBuffers()}}}. For | 
                  
                          |   | 288 | applications in which the contents of the display changes frequently, it is | 
                  
                          |   | 289 | most appropriate to use windows dual graphics buffers, which is setup by | 
                  
                          |   | 290 | using the {{{GLUT_DOUBLE}}} at window initialization. The advantage of such | 
                  
                          |   | 291 | drawing strategy is in the fact that while one buffer is used for current | 
                  
                          |   | 292 | drawing the other is shown. Drawing thus occurs in the background and when | 
                  
                          |   | 293 | buffer is ready for display we simply flip the buffers. In particular it | 
                  
                          |   | 294 | should be noted that such behaviour is system dependent and once upon a | 
                  
                          |   | 295 | time when the {{{GLUT_SINGLE" (without double buffers) with the "glFlush()}}} | 
                  
                          |   | 296 | at the end was used instead. Nowadays {{{GLUT_DOUBLE}}} is usually used, which | 
                  
                          |   | 297 | is most helpful with high frame-rate applications such as animation. | 
                  
                          |   | 298 | Only simple primitives are used within OpenGL. Reason for that is mainly | 
                  
                          |   | 299 | due to the requirement of performance and possible hardware acceleration. | 
                  
                          |   | 300 | There are three types of simple primitives: points, lines, and triangles. | 
                  
                          |   | 301 | Higher level primitives (like quadrilaterals) can be assembled from simple | 
                  
                          |   | 302 | ones. Curves can be approximated by lines. Large surfaces can be tessellated | 
                  
                          |   | 303 | with triangles. For complex surfaces (like NURBS) GLU library can be used | 
                  
                          |   | 304 | to calculate vertices. The following line primitives are possible: | 
                  
                          |   | 305 |  GL_LINES:: Pairs of vertices in a vertex stream create line | 
                  
                          |   | 306 |   segments. | 
                  
                          |   | 307 |  GL_LINE_STRIP:: Vertex stream builds connected lines | 
                  
                          |   | 308 |   (polyline).  | 
                  
                          |   | 309 |  GL_LINE_LOOP:: Same as polyline above except that last | 
                  
                          |   | 310 |   vertex is connected by a line to the first. | 
                  
                          |   | 311 | Every surface can be assembled with triangles. | 
                  
                          |   | 312 |  GL_TRIANGLES:: For each triangle three vertices are required | 
                  
                          |   | 313 |   from vertex stream. | 
                  
                          |   | 314 |  GL_TRIANGLE_STRIP:: Strip of triangles. For first triangle | 
                  
                          |   | 315 |   three vertices are needed. For every additional vertex new triangle is | 
                  
                          |   | 316 |   created by using last two vertices. | 
                  
                          |   | 317 |  GL_TRIANGLE_FAN:: Triangles are added to the first one by | 
                  
                          |   | 318 |   using first and last vertex to create a triangle fan. | 
                  
                          |   | 319 | == Modern OpenGL == | 
                  
                          |   | 320 | Immediate mode programming with {{{glBegin" and "glEnd}}} was removed from | 
                  
                          |   | 321 | OpenGL 3.x as such transmission of vertex streams and its attributes | 
                  
                          |   | 322 | (colors, normals, ...) from system memory to GPU is considered as a major | 
                  
                          |   | 323 | performance drawback. Display lists were previously used to save stream of | 
                  
                          |   | 324 | OpenGL calls that also included vertex data and was just replayed at | 
                  
                          |   | 325 | redraw. But this is inherently sequential operation that blocked parallel | 
                  
                          |   | 326 | vertex processing. Requirement to store vertex arrays to GPU directly as an | 
                  
                          |   | 327 | ''object'' can solve problem described. Storing vertex arrays into GPU | 
                  
                          |   | 328 | also means that manipulation on them to build the model should be inside | 
                  
                          |   | 329 | the GPU. Legacy OpenGL included many ``modelling'' utilities for | 
                  
                          |   | 330 | transforming world coordinates into viewport. Transformations of coordinate | 
                  
                          |   | 331 | systems in 3D space allowed manipulate model stack easily with | 
                  
                          |   | 332 | {{{glPushMatrix" and "glPopMatrix}}} commands. But similarly to | 
                  
                          |   | 333 | {{{glBegin"/"glEnd}}} such manipulations are not used outside GPU anymore. | 
                  
                          |   | 334 | Instead all operations on vertex data is transferred to ''vertex shader''.  | 
                  
                          |   | 335 | There operations on data can be performed with standard vector | 
                  
                          |   | 336 | math in homogeneous coordinates. | 
                  
                          |   | 337 |  | 
                  
                          |   | 338 |  |