ruby-glfw 0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (206) hide show
  1. data/README +1 -0
  2. data/README.API +73 -0
  3. data/Rakefile +120 -0
  4. data/examples/boing.rb +519 -0
  5. data/examples/gears.rb +327 -0
  6. data/examples/keytest.rb +117 -0
  7. data/examples/listmodes.rb +20 -0
  8. data/examples/mipmaps.rb +104 -0
  9. data/examples/mipmaps.tga +0 -0
  10. data/examples/particles.rb +837 -0
  11. data/examples/pong3d.rb +741 -0
  12. data/examples/pong3d_field.tga +0 -0
  13. data/examples/pong3d_instr.tga +0 -0
  14. data/examples/pong3d_menu.tga +0 -0
  15. data/examples/pong3d_title.tga +0 -0
  16. data/examples/pong3d_winner1.tga +0 -0
  17. data/examples/pong3d_winner2.tga +0 -0
  18. data/examples/splitview.rb +432 -0
  19. data/examples/triangle.rb +89 -0
  20. data/examples/wave.rb +294 -0
  21. data/ext/glfw/glfw.c +1094 -0
  22. data/ext/glfw/mkrf_conf.rb +70 -0
  23. data/glfw-src/Makefile +220 -0
  24. data/glfw-src/compile.ami +61 -0
  25. data/glfw-src/compile.bat +217 -0
  26. data/glfw-src/compile.sh +607 -0
  27. data/glfw-src/docs/Makefile +57 -0
  28. data/glfw-src/docs/Reference.pdf +0 -0
  29. data/glfw-src/docs/UsersGuide.pdf +0 -0
  30. data/glfw-src/docs/cleanup.bat +22 -0
  31. data/glfw-src/docs/glfwdoc.sty +80 -0
  32. data/glfw-src/docs/glfwrm.tex +3034 -0
  33. data/glfw-src/docs/glfwug.tex +2024 -0
  34. data/glfw-src/docs/readme.txt +80 -0
  35. data/glfw-src/examples/Makefile.amigaos.gcc +70 -0
  36. data/glfw-src/examples/Makefile.amigaos.vbcc +70 -0
  37. data/glfw-src/examples/Makefile.dos.djgpp +71 -0
  38. data/glfw-src/examples/Makefile.macosx.gcc +96 -0
  39. data/glfw-src/examples/Makefile.win32.bcc +75 -0
  40. data/glfw-src/examples/Makefile.win32.cross-mgw +79 -0
  41. data/glfw-src/examples/Makefile.win32.cygwin +79 -0
  42. data/glfw-src/examples/Makefile.win32.lcc +74 -0
  43. data/glfw-src/examples/Makefile.win32.mgw +75 -0
  44. data/glfw-src/examples/Makefile.win32.msvc +74 -0
  45. data/glfw-src/examples/Makefile.win32.ow +74 -0
  46. data/glfw-src/examples/Makefile.win32.pellesc +74 -0
  47. data/glfw-src/examples/Makefile.x11.in +54 -0
  48. data/glfw-src/examples/boing.c +606 -0
  49. data/glfw-src/examples/bundle.sh +46 -0
  50. data/glfw-src/examples/gears.c +382 -0
  51. data/glfw-src/examples/keytest.c +264 -0
  52. data/glfw-src/examples/listmodes.c +48 -0
  53. data/glfw-src/examples/mipmaps.c +126 -0
  54. data/glfw-src/examples/mipmaps.tga +0 -0
  55. data/glfw-src/examples/mtbench.c +301 -0
  56. data/glfw-src/examples/mthello.c +48 -0
  57. data/glfw-src/examples/particles.c +1148 -0
  58. data/glfw-src/examples/pong3d.c +839 -0
  59. data/glfw-src/examples/pong3d_field.tga +0 -0
  60. data/glfw-src/examples/pong3d_instr.tga +0 -0
  61. data/glfw-src/examples/pong3d_menu.tga +0 -0
  62. data/glfw-src/examples/pong3d_title.tga +0 -0
  63. data/glfw-src/examples/pong3d_winner1.tga +0 -0
  64. data/glfw-src/examples/pong3d_winner2.tga +0 -0
  65. data/glfw-src/examples/splitview.c +506 -0
  66. data/glfw-src/examples/triangle.c +108 -0
  67. data/glfw-src/examples/wave.c +397 -0
  68. data/glfw-src/images/opengl.gif +0 -0
  69. data/glfw-src/images/osicert.gif +0 -0
  70. data/glfw-src/include/GL/glfw.h +486 -0
  71. data/glfw-src/lib/amigaos/Makefile.amigaos.gcc +128 -0
  72. data/glfw-src/lib/amigaos/Makefile.amigaos.vbcc +128 -0
  73. data/glfw-src/lib/amigaos/SDI_compiler.h +94 -0
  74. data/glfw-src/lib/amigaos/amigaos_enable.c +51 -0
  75. data/glfw-src/lib/amigaos/amigaos_fullscreen.c +319 -0
  76. data/glfw-src/lib/amigaos/amigaos_glext.c +61 -0
  77. data/glfw-src/lib/amigaos/amigaos_init.c +284 -0
  78. data/glfw-src/lib/amigaos/amigaos_joystick.c +359 -0
  79. data/glfw-src/lib/amigaos/amigaos_thread.c +494 -0
  80. data/glfw-src/lib/amigaos/amigaos_time.c +206 -0
  81. data/glfw-src/lib/amigaos/amigaos_window.c +830 -0
  82. data/glfw-src/lib/amigaos/platform.h +337 -0
  83. data/glfw-src/lib/dos/Makefile.dos.djgpp +146 -0
  84. data/glfw-src/lib/dos/dos_enable.c +51 -0
  85. data/glfw-src/lib/dos/dos_events.c +173 -0
  86. data/glfw-src/lib/dos/dos_fullscreen.c +101 -0
  87. data/glfw-src/lib/dos/dos_glext.c +59 -0
  88. data/glfw-src/lib/dos/dos_init.c +105 -0
  89. data/glfw-src/lib/dos/dos_irq.s +246 -0
  90. data/glfw-src/lib/dos/dos_joystick.c +94 -0
  91. data/glfw-src/lib/dos/dos_keyboard.c +694 -0
  92. data/glfw-src/lib/dos/dos_mouse.c +337 -0
  93. data/glfw-src/lib/dos/dos_thread.c +267 -0
  94. data/glfw-src/lib/dos/dos_time.c +309 -0
  95. data/glfw-src/lib/dos/dos_window.c +563 -0
  96. data/glfw-src/lib/dos/platform.h +341 -0
  97. data/glfw-src/lib/enable.c +295 -0
  98. data/glfw-src/lib/fullscreen.c +95 -0
  99. data/glfw-src/lib/glext.c +201 -0
  100. data/glfw-src/lib/image.c +629 -0
  101. data/glfw-src/lib/init.c +108 -0
  102. data/glfw-src/lib/input.c +280 -0
  103. data/glfw-src/lib/internal.h +210 -0
  104. data/glfw-src/lib/joystick.c +101 -0
  105. data/glfw-src/lib/macosx/Makefile.macosx.gcc +172 -0
  106. data/glfw-src/lib/macosx/Makefile.macosx.gcc.universal +166 -0
  107. data/glfw-src/lib/macosx/libglfw.pc.in +11 -0
  108. data/glfw-src/lib/macosx/macosx_enable.c +42 -0
  109. data/glfw-src/lib/macosx/macosx_fullscreen.c +126 -0
  110. data/glfw-src/lib/macosx/macosx_glext.c +52 -0
  111. data/glfw-src/lib/macosx/macosx_init.c +194 -0
  112. data/glfw-src/lib/macosx/macosx_joystick.c +50 -0
  113. data/glfw-src/lib/macosx/macosx_thread.c +414 -0
  114. data/glfw-src/lib/macosx/macosx_time.c +112 -0
  115. data/glfw-src/lib/macosx/macosx_window.c +1279 -0
  116. data/glfw-src/lib/macosx/platform.h +349 -0
  117. data/glfw-src/lib/stream.c +194 -0
  118. data/glfw-src/lib/tga.c +405 -0
  119. data/glfw-src/lib/thread.c +340 -0
  120. data/glfw-src/lib/time.c +83 -0
  121. data/glfw-src/lib/win32/Makefile.win32.bcc +265 -0
  122. data/glfw-src/lib/win32/Makefile.win32.cross-mgw +274 -0
  123. data/glfw-src/lib/win32/Makefile.win32.cygwin +279 -0
  124. data/glfw-src/lib/win32/Makefile.win32.lcc +246 -0
  125. data/glfw-src/lib/win32/Makefile.win32.mgw +243 -0
  126. data/glfw-src/lib/win32/Makefile.win32.msvc +242 -0
  127. data/glfw-src/lib/win32/Makefile.win32.ow +242 -0
  128. data/glfw-src/lib/win32/Makefile.win32.pellesc +242 -0
  129. data/glfw-src/lib/win32/glfwdll.def +67 -0
  130. data/glfw-src/lib/win32/glfwdll_mgw1.def +67 -0
  131. data/glfw-src/lib/win32/glfwdll_mgw2.def +67 -0
  132. data/glfw-src/lib/win32/glfwdll_pellesc.def +65 -0
  133. data/glfw-src/lib/win32/libglfw.pc.in +11 -0
  134. data/glfw-src/lib/win32/platform.h +474 -0
  135. data/glfw-src/lib/win32/win32_dllmain.c +60 -0
  136. data/glfw-src/lib/win32/win32_enable.c +155 -0
  137. data/glfw-src/lib/win32/win32_fullscreen.c +317 -0
  138. data/glfw-src/lib/win32/win32_glext.c +85 -0
  139. data/glfw-src/lib/win32/win32_init.c +356 -0
  140. data/glfw-src/lib/win32/win32_joystick.c +234 -0
  141. data/glfw-src/lib/win32/win32_thread.c +511 -0
  142. data/glfw-src/lib/win32/win32_time.c +146 -0
  143. data/glfw-src/lib/win32/win32_window.c +1714 -0
  144. data/glfw-src/lib/window.c +727 -0
  145. data/glfw-src/lib/x11/Makefile.x11.in +243 -0
  146. data/glfw-src/lib/x11/platform.h +415 -0
  147. data/glfw-src/lib/x11/x11_enable.c +51 -0
  148. data/glfw-src/lib/x11/x11_fullscreen.c +524 -0
  149. data/glfw-src/lib/x11/x11_glext.c +69 -0
  150. data/glfw-src/lib/x11/x11_init.c +275 -0
  151. data/glfw-src/lib/x11/x11_joystick.c +371 -0
  152. data/glfw-src/lib/x11/x11_keysym2unicode.c +902 -0
  153. data/glfw-src/lib/x11/x11_thread.c +507 -0
  154. data/glfw-src/lib/x11/x11_time.c +154 -0
  155. data/glfw-src/lib/x11/x11_window.c +1746 -0
  156. data/glfw-src/license.txt +21 -0
  157. data/glfw-src/readme.html +927 -0
  158. data/glfw-src/support/d/examples/Makefile +59 -0
  159. data/glfw-src/support/d/examples/boing.d +610 -0
  160. data/glfw-src/support/d/examples/gears.d +379 -0
  161. data/glfw-src/support/d/examples/keytest.d +272 -0
  162. data/glfw-src/support/d/examples/listmodes.d +48 -0
  163. data/glfw-src/support/d/examples/mipmaps.d +126 -0
  164. data/glfw-src/support/d/examples/mtbench.d +304 -0
  165. data/glfw-src/support/d/examples/mthello.d +54 -0
  166. data/glfw-src/support/d/examples/particles.d +1150 -0
  167. data/glfw-src/support/d/examples/pong3d.d +840 -0
  168. data/glfw-src/support/d/examples/splitview.d +486 -0
  169. data/glfw-src/support/d/examples/triangle.d +108 -0
  170. data/glfw-src/support/d/examples/wave.d +400 -0
  171. data/glfw-src/support/d/imports/gl.d +4539 -0
  172. data/glfw-src/support/d/imports/glfw.d +349 -0
  173. data/glfw-src/support/d/imports/glu.d +328 -0
  174. data/glfw-src/support/d/lib/glfwdll.def +64 -0
  175. data/glfw-src/support/d/lib/glu32.def +56 -0
  176. data/glfw-src/support/d/lib/makefile +12 -0
  177. data/glfw-src/support/d/lib/opengl32.def +372 -0
  178. data/glfw-src/support/d/readme.html +83 -0
  179. data/glfw-src/support/delphi/examples/Triangle.dpr +105 -0
  180. data/glfw-src/support/delphi/lib/glfw.pas +437 -0
  181. data/glfw-src/support/delphi/readme.html +97 -0
  182. data/glfw-src/support/lua/examples/gears.lua +383 -0
  183. data/glfw-src/support/lua/examples/test1.lua +68 -0
  184. data/glfw-src/support/lua/readme.html +128 -0
  185. data/glfw-src/support/lua/src/luaglfw.c +1179 -0
  186. data/glfw-src/support/lua/src/luaglfw.h +48 -0
  187. data/glfw-src/support/lua/src/runlua.c +82 -0
  188. data/glfw-src/support/masm/examples/fpc.mac +47 -0
  189. data/glfw-src/support/masm/examples/makeit.bat +66 -0
  190. data/glfw-src/support/masm/examples/triangle.asm +232 -0
  191. data/glfw-src/support/masm/include/glfw.inc +326 -0
  192. data/glfw-src/support/masm/include/glu32.inc +55 -0
  193. data/glfw-src/support/masm/include/opengl32.inc +372 -0
  194. data/glfw-src/support/masm/lib/glfwdll.lib +0 -0
  195. data/glfw-src/support/masm/readme.html +170 -0
  196. data/glfw-src/support/msvc80/GLFW.sln +26 -0
  197. data/glfw-src/support/msvc80/GLFW.vcproj +257 -0
  198. data/glfw-src/support/msvc80/GLFWDLL.vcproj +287 -0
  199. data/glfw-src/support/visualbasic/bindings/glfw.bas +320 -0
  200. data/glfw-src/support/visualbasic/bindings/glu32.bas +284 -0
  201. data/glfw-src/support/visualbasic/bindings/opengl32.bas +999 -0
  202. data/glfw-src/support/visualbasic/examples/Triangle.bas +101 -0
  203. data/glfw-src/support/visualbasic/readme.html +164 -0
  204. data/website/index.html +84 -0
  205. data/website/style.css +110 -0
  206. metadata +301 -0
@@ -0,0 +1,2024 @@
1
+ %-------------------------------------------------------------------------
2
+ % GLFW Users Guide
3
+ % API Version: 2.6
4
+ %-------------------------------------------------------------------------
5
+
6
+ % Document class
7
+ \documentclass[a4paper,11pt,oneside]{report}
8
+
9
+ % Document title and API version
10
+ \newcommand{\glfwdoctype}[1][0]{Users Guide}
11
+ \newcommand{\glfwapiver}[1][0]{2.6}
12
+
13
+ % Common document settings and macros
14
+ \input{glfwdoc.sty}
15
+
16
+ % PDF specific document settings
17
+ \hypersetup{pdftitle={GLFW Users Guide}}
18
+ \hypersetup{pdfauthor={Marcus Geelnard}}
19
+ \hypersetup{pdfkeywords={GLFW,OpenGL,guide,manual}}
20
+
21
+
22
+ %-------------------------------------------------------------------------
23
+ % Document body
24
+ %-------------------------------------------------------------------------
25
+
26
+ \begin{document}
27
+
28
+ \pagestyle{plain}
29
+
30
+ % Title page
31
+ \glfwmaketitle
32
+
33
+ % Summary, trademarks and table of contents
34
+ \pagenumbering{roman}
35
+ \setcounter{page}{1}
36
+
37
+ %-------------------------------------------------------------------------
38
+ % Summary and Trademarks
39
+ %-------------------------------------------------------------------------
40
+ \chapter*{Summary}
41
+
42
+ This document is a users guide for the \GLFW\ API that gives a practical
43
+ introduction to using \GLFW . For a more detailed description of the
44
+ \GLFW\ API you should refer to the \textit{GLFW Reference Manual}.
45
+ \vspace{10cm}
46
+
47
+ \large
48
+ Trademarks
49
+
50
+ \small
51
+ OpenGL and IRIX are registered trademarks of Silicon Graphics, Inc.\linebreak
52
+ Microsoft and Windows are registered trademarks of Microsoft Corporation.\linebreak
53
+ Mac OS is a registered trademark of Apple Computer, Inc.\linebreak
54
+ Linux is a registered trademark of Linus Torvalds.\linebreak
55
+ FreeBSD is a registered trademark of Wind River Systems, Inc.\linebreak
56
+ Solaris is a trademark of Sun Microsystems, Inc.\linebreak
57
+ UNIX is a registered trademark of The Open Group.\linebreak
58
+ X Window System is a trademark of The Open Group.\linebreak
59
+ POSIX is a trademark of IEEE.\linebreak
60
+ Truevision, TARGA and TGA are registered trademarks of Truevision, Inc.\linebreak
61
+ IBM is a registered trademark of IBM Corporation.\linebreak
62
+
63
+ All other trademarks mentioned in this document are the property of their respective owners.
64
+ \normalsize
65
+
66
+
67
+ %-------------------------------------------------------------------------
68
+ % Table of contents
69
+ %-------------------------------------------------------------------------
70
+ \tableofcontents
71
+ \pagebreak
72
+
73
+
74
+ % Document chapters starts here...
75
+ \pagenumbering{arabic}
76
+ \setcounter{page}{1}
77
+
78
+ \pagestyle{fancy}
79
+
80
+
81
+ %-------------------------------------------------------------------------
82
+ % Introduction
83
+ %-------------------------------------------------------------------------
84
+ \chapter{Introduction}
85
+ \thispagestyle{fancy}
86
+ \GLFW\ is a portable API (Application Program Interface) that handles
87
+ operating system specific tasks related to \OpenGL\ programming. While
88
+ \OpenGL\ in general is portable, easy to use and often results in tidy and
89
+ compact code, the operating system specific mechanisms that are required
90
+ to set up and manage an \OpenGL\ window are quite the opposite. \GLFW\ tries
91
+ to remedy this by providing the following functionality:
92
+
93
+ \begin{itemize}
94
+ \item Opening and managing an \OpenGL\ window.
95
+ \item Keyboard, mouse and joystick input.
96
+ \item A high precision timer.
97
+ \item Multi threading support.
98
+ \item Support for querying and using \OpenGL\ extensions.
99
+ \item Image file loading support.
100
+ \end{itemize}
101
+ \vspace{18pt}
102
+
103
+ All this functionality is implemented as a set of easy-to-use functions,
104
+ which makes it possible to write an \OpenGL\ application framework in just a
105
+ few lines of code. The \GLFW\ API is completely operating system and
106
+ platform independent, which makes it very simple to port \GLFW\ based \OpenGL\
107
+ applications to a variety of platforms.
108
+
109
+ Currently supported platforms are:
110
+ \begin{itemize}
111
+ \item Microsoft Windows\textsuperscript{\textregistered} 95/98/ME/NT/2000/XP/.NET Server.
112
+ \item Unix\textsuperscript{\textregistered} or Unix�-like systems running the
113
+ X Window System\texttrademark, e.g. Linux\textsuperscript{\textregistered},
114
+ IRIX\textsuperscript{\textregistered}, FreeBSD\textsuperscript{\textregistered},
115
+ Solaris\texttrademark, QNX\textsuperscript{\textregistered} and
116
+ Mac OS\textsuperscript{\textregistered} X.
117
+ \item Mac OS\textsuperscript{\textregistered} X (Carbon)\footnote{Support for joysticks missing at the time of writing.}
118
+ \end{itemize}
119
+
120
+
121
+ %-------------------------------------------------------------------------
122
+ % Getting Started
123
+ %-------------------------------------------------------------------------
124
+ \chapter{Getting Started}
125
+ \thispagestyle{fancy}
126
+ In this chapter you will learn how to write a simple \OpenGL\ application
127
+ using \GLFW . We start by initializing \GLFW , then we open a window and
128
+ read some user keyboard input.
129
+
130
+
131
+ %-------------------------------------------------------------------------
132
+ \section{Initializing GLFW}
133
+ Before using any of the \GLFW\ functions, it is necessary to call
134
+ \textbf{glfwInit}. It initializes internal working variables that are used
135
+ by other \GLFW\ functions. The C syntax is:
136
+
137
+ \begin{lstlisting}
138
+ int glfwInit( void )
139
+ \end{lstlisting}
140
+
141
+ \textbf{glfwInit} returns GL\_TRUE if initialization succeeded, or
142
+ GL\_FALSE if it failed.
143
+
144
+ When your application is done using \GLFW , typically at the very end of
145
+ the program, you should call \textbf{glfwTerminate}, which makes a clean
146
+ up and places \GLFW\ in a non-initialized state (i.e. it is necessary to
147
+ call \textbf{glfwInit} again before using any \GLFW\ functions). The C
148
+ syntax is:
149
+
150
+ \begin{lstlisting}
151
+ void glfwTerminate( void )
152
+ \end{lstlisting}
153
+
154
+ Among other things, \textbf{glfwTerminate} closes the \OpenGL\ window
155
+ unless it was closed manually, and kills any running threads that were
156
+ created using \GLFW .
157
+
158
+
159
+ %-------------------------------------------------------------------------
160
+ \section{Opening An OpenGL Window}
161
+ Opening an \OpenGL\ window is done with the function
162
+ \textbf{glfwOpenWindow}. The function takes nine arguments, which are used
163
+ to describe the following properties of the window to open:
164
+
165
+ \begin{itemize}
166
+ \item Window dimensions (width and height) in pixels.
167
+ \item Color and alpha buffer depth.
168
+ \item Depth buffer (Z-buffer) depth.
169
+ \item Stencil buffer depth.
170
+ \item Fullscreen or windowed mode.
171
+ \end{itemize}
172
+
173
+ The C language syntax for \textbf{glfwOpenWindow} is:
174
+ \begin{lstlisting}
175
+ int glfwOpenWindow( int width, int height,
176
+ int redbits, int greenbits, int bluebits,
177
+ int alphabits, int depthbits, int stencilbits,
178
+ int mode )
179
+ \end{lstlisting}
180
+
181
+ \textbf{glfwOpenWindow} returns GL\_TRUE if the window was opened
182
+ correctly, or GL\_FALSE if \GLFW\ failed to open the window.
183
+
184
+ \GLFW\ tries to open a window that best matches the requested parameters.
185
+ Some parameters may be omitted by setting them to zero, which will result
186
+ in \GLFW\ either using a default value, or the related functionality to be
187
+ disabled. For instance, if \textit{width} and \textit{height} are both
188
+ zero, \GLFW\ will use a window resolution of 640x480. If
189
+ \textit{depthbits} is zero, the opened window may not have a depth buffer.
190
+
191
+ The \textit{mode} argument is used to specify if the window is to be a
192
+ s.c. fullscreen window, or a regular window.
193
+
194
+ If \textit{mode} is GLFW\_FULLSCREEN, the window will cover the entire
195
+ screen and no window borders will be visible. If possible, the video mode
196
+ will be changed to the mode that closest matches the \textit{width},
197
+ \textit{height}, \textit{redbits}, \textit{greenbits}, \textit{bluebits}
198
+ and \textit{alphabits} arguments. Furthermore, the mouse pointer will be
199
+ hidden, and screensavers are prohibited. This is usually the best mode for
200
+ games and demos.
201
+
202
+ If \textit{mode} is GLFW\_WINDOW, the window will be opened as a normal
203
+ window on the desktop. The mouse pointer will not be hidden, and
204
+ screensavers are allowed to be activated.
205
+
206
+ To close the window, you can either use \textbf{glfwTerminate}, as
207
+ described earlier, or you can use the more explicit approach by calling
208
+ \textbf{glfwCloseWindow}, which has the C syntax:
209
+
210
+ \begin{lstlisting}
211
+ void glfwCloseWindow( void )
212
+ \end{lstlisting}
213
+
214
+
215
+ %-------------------------------------------------------------------------
216
+ \section{Using Keyboard Input}
217
+ \GLFW\ provides several means for receiving user input, which will be
218
+ discussed in more detail in chapter \ref{par:inputhandling}. One of the
219
+ simplest ways of checking for keyboard input is to use the function
220
+ \textbf{glfwGetKey}:
221
+
222
+ \begin{lstlisting}
223
+ int glfwGetKey( int key )
224
+ \end{lstlisting}
225
+
226
+ It queries the current status of individual keyboard keys. The argument
227
+ \textit{key} specifies which key to check, and it can be either an
228
+ uppercase printable ISO 8859-1 (Latin 1) character (e.g. `A', `3' or `.'),
229
+ or a special key identifier (see the \textit{GLFW Reference Manual} for a
230
+ list of special key identifiers). \textbf{glfwGetKey} returns GLFW\_PRESS
231
+ (or 1) if the key is currently held down, or GLFW\_RELEASE (or 0) if the
232
+ key is not being held down. For example:
233
+
234
+ \begin{lstlisting}
235
+ A_pressed = glfwGetKey( 'A' );
236
+ esc_pressed = glfwGetKey( GLFW_KEY_ESC );
237
+ \end{lstlisting}
238
+
239
+ In order for \textbf{glfwGetKey} to have any effect, you need to poll for
240
+ input events on a regular basis. This can be done in one of two ways:
241
+
242
+ \begin{enumerate}
243
+ \item Implicitly by calling \textbf{glfwSwapBuffers} often.
244
+ \item Explicitly by calling \textbf{glfwPollEvents} often.
245
+ \end{enumerate}
246
+
247
+ In general you do not have to care about this, since you will normally
248
+ call \textbf{glfwSwapBuffers} to swap front and back rendering buffers
249
+ every animation frame anyway. If, however, this is not the case, you
250
+ should call \textbf{glfwPollEvents} in the order of 10-100 times per
251
+ second in order for \GLFW\ to maintain an up to date input state.
252
+
253
+
254
+ %-------------------------------------------------------------------------
255
+ \section{Putting It Together: A Minimal GLFW Application}
256
+ Now that you know how to initialize \GLFW , open a window and poll for
257
+ keyboard input, let us exemplify this with a simple \OpenGL\ program. In
258
+ the following example some error-checking has been omitted for the sake of
259
+ brevity:
260
+
261
+ \begin{lstlisting}
262
+ #include <GL/glfw.h>
263
+
264
+ int main( void )
265
+ {
266
+ int running = GL_TRUE;
267
+
268
+ // Initialize GLFW
269
+ glfwInit();
270
+
271
+ // Open an OpenGL window
272
+ if( !glfwOpenWindow( 300,300, 0,0,0,0,0,0, GLFW_WINDOW ) )
273
+ {
274
+ glfwTerminate();
275
+ return 0;
276
+ }
277
+
278
+ // Main loop
279
+ while( running )
280
+ {
281
+ // OpenGL rendering goes here...
282
+ glClear( GL_COLOR_BUFFER_BIT );
283
+
284
+ // Swap front and back rendering buffers
285
+ glfwSwapBuffers();
286
+
287
+ // Check if ESC key was pressed or window was closed
288
+ running = !glfwGetKey( GLFW_KEY_ESC ) &&
289
+ glfwGetWindowParam( GLFW_OPENED );
290
+ }
291
+
292
+ // Close window and terminate GLFW
293
+ glfwTerminate();
294
+
295
+ // Exit program
296
+ return 0;
297
+ }
298
+ \end{lstlisting}
299
+
300
+ The program opens a 300x300 window and runs in a loop until the escape key
301
+ is pressed, or the window was closed. All the \OpenGL\ ``rendering'' that
302
+ is done in this example is to clear the window.
303
+
304
+
305
+ %-------------------------------------------------------------------------
306
+ % Window Operations
307
+ %-------------------------------------------------------------------------
308
+ \chapter{Window Operations}
309
+ \thispagestyle{fancy}
310
+ In this chapter, you will learn more about window related \GLFW\
311
+ functionality, including: setting and getting window properties, buffer
312
+ swap control and video mode querying.
313
+
314
+
315
+ %-------------------------------------------------------------------------
316
+ \section{Setting Window Properties}
317
+ In the previous chapter the \textbf{glfwOpenWindow} function was
318
+ described, which specifies the sizes of the color, alpha, depth and
319
+ stencil buffers. It is also possible to request an accumulator buffer,
320
+ auxiliary buffers and stereo rendering by using the
321
+ \textbf{glfwOpenWindowHint} function:
322
+
323
+ \begin{lstlisting}
324
+ void glfwOpenWindowHint( int target, int hint )
325
+ \end{lstlisting}
326
+
327
+ The \textit{target} argument can be one of the constants listed in table~
328
+ \ref{tab:winhints}, and \textit{hint} is the value to assign to the
329
+ specified target.
330
+
331
+ %-------------------------------------------------------------------------
332
+ \begin{table}[p]
333
+ \begin{center}
334
+ \begin{tabular}{|l|l|p{7.0cm}|} \hline \raggedright
335
+ \textbf{Name} & \textbf{Default} & \textbf{Description} \\ \hline
336
+ GLFW\_REFRESH\_RATE & 0 & Vertical monitor refresh rate in Hz (only used for fullscreen windows). Zero means system default.\\ \hline
337
+ GLFW\_ACCUM\_RED\_BITS & 0 & Number of bits for the red channel of the accumulator buffer.\\ \hline
338
+ GLFW\_ACCUM\_GREEN\_BITS & 0 & Number of bits for the green channel of the accumulator buffer.\\ \hline
339
+ GLFW\_ACCUM\_BLUE\_BITS & 0 & Number of bits for the blue channel of the accumulator buffer.\\ \hline
340
+ GLFW\_ACCUM\_ALPHA\_BITS & 0 & Number of bits for the alpha channel of the accumulator buffer.\\ \hline
341
+ GLFW\_AUX\_BUFFERS & 0 & Number of auxiliary buffers.\\ \hline
342
+ GLFW\_STEREO & GL\_FALSE & Specify if stereo rendering should be supported (can be GL\_TRUE or GL\_FALSE).\\ \hline
343
+ GLFW\_WINDOW\_NO\_RESIZE & GL\_FALSE & Specify whether the window can be resized (not used for fullscreen windows).\\ \hline
344
+ GLFW\_FSAA\_SAMPLES & 0 & Number of samples to use for the multisampling buffer. Zero disables multisampling.\\ \hline
345
+ \end{tabular}
346
+ \end{center}
347
+ \caption{Targets for \textbf{glfwOpenWindowHint}}
348
+ \label{tab:winhints}
349
+ \end{table}
350
+ %-------------------------------------------------------------------------
351
+
352
+ For a hint to have any effect, the \textbf{glfwOpenWindowHint} function
353
+ must be called before opening the window with the \textbf{glfwOpenWindow}
354
+ function.
355
+
356
+ To request an accumulator buffer, set the GLFW\_ACCUM\_x\_BITS targets to
357
+ values greater than zero (usually eight or sixteen bits per component).
358
+ To request auxiliary buffers, set the GLFW\_AUX\_BUFFERS target to a value
359
+ greater than zero. To request a stereo rendering capable window, set the
360
+ GLFW\_STEREO target to GL\_TRUE.
361
+
362
+ If you want to enable fullscreen antialiasing, set the GLFW\_FSAA\_SAMPLES
363
+ target to a value greater than zero. If the windowing system is unable to
364
+ fulfil the request, \GLFW\ will degrade gracefully and disable FSAA if necessary.
365
+
366
+ The GLFW\_REFRESH\_RATE target should be used with caution, since it may
367
+ result in suboptimal operation, or even a blank or damaged screen.
368
+
369
+ Besides the parameters that are given with the \textbf{glfwOpenWindow} and
370
+ \textbf{glfwOpenWindowHint} functions, a few more properties of a window
371
+ can be changed after the window has been opened, namely the window title,
372
+ window size, and window position.
373
+
374
+ To change the window title of an open window, use the
375
+ \textbf{glfwSetWindowTitle} function:
376
+
377
+ \begin{lstlisting}
378
+ void glfwSetWindowTitle( const char *title )
379
+ \end{lstlisting}
380
+
381
+ \textit{title} is a null terminated ISO~8859-1 (8-bit Latin~1) string that
382
+ will be used as the window title. It will also be used as the application
383
+ name (for instance in the application list when using \texttt{ALT+TAB}
384
+ under Windows, or as the icon name when the window is iconified under
385
+ the X Window System). The default window name is ``GLFW Window'', which
386
+ will be used unless \textbf{glfwSetWindowTitle} is called after the window
387
+ has been opened.
388
+
389
+ To change the size of a window, call \textbf{glfwSetWindowSize}:
390
+
391
+ \begin{lstlisting}
392
+ void glfwSetWindowSize( int width, int height )
393
+ \end{lstlisting}
394
+
395
+ Where \textit{width} and \textit{height} are the new dimensions of the
396
+ window.
397
+
398
+ To change the position of a window, call \textbf{glfwSetWindowPos}:
399
+
400
+ \begin{lstlisting}
401
+ void glfwSetWindowPos( int x, int y )
402
+ \end{lstlisting}
403
+
404
+ Where \textit{x} and \textit{y} are the new desktop coordinates of the
405
+ window. This function does not have any effect when in fullscreen mode.
406
+
407
+
408
+ %-------------------------------------------------------------------------
409
+ \section{Getting Window Properties}
410
+ When opening a window, the opened window will not necessarily have the
411
+ requested properties, so you should always check the parameters that your
412
+ application relies on (e.g. number of stencil bits) using
413
+ \textbf{glfwGetWindowParam}, which has the C syntax:
414
+
415
+ \begin{lstlisting}
416
+ int glfwGetWindowParam( int param )
417
+ \end{lstlisting}
418
+
419
+ The argument \textit{param} can be one of the tokens listed in table
420
+ \ref{tab:winparams}, and the return value is an integer holding the
421
+ requested value.
422
+
423
+ %-------------------------------------------------------------------------
424
+ \begin{table}[p]
425
+ \begin{center}
426
+ \begin{tabular}{|l|p{9.5cm}|} \hline \raggedright
427
+ \textbf{Name} & \textbf{Description} \\ \hline
428
+ GLFW\_OPENED & GL\_TRUE if window is opened, else GL\_FALSE.\\ \hline
429
+ GLFW\_ACTIVE & GL\_TRUE if window has focus, else GL\_FALSE.\\ \hline
430
+ GLFW\_ICONIFIED & GL\_TRUE if window is iconified, else GL\_FALSE.\\ \hline
431
+ GLFW\_ACCELERATED & GL\_TRUE if window is hardware accelerated, else GL\_FALSE.\\ \hline
432
+ GLFW\_RED\_BITS & Number of bits for the red color component.\\ \hline
433
+ GLFW\_GREEN\_BITS & Number of bits for the green color component.\\ \hline
434
+ GLFW\_BLUE\_BITS & Number of bits for the blue color component.\\ \hline
435
+ GLFW\_ALPHA\_BITS & Number of bits for the alpha buffer.\\ \hline
436
+ GLFW\_DEPTH\_BITS & Number of bits for the depth buffer.\\ \hline
437
+ GLFW\_STENCIL\_BITS & Number of bits for the stencil buffer.\\ \hline
438
+ GLFW\_REFRESH\_RATE & Vertical monitor refresh rate in Hz. Zero indicates an unknown or a default refresh rate.\\ \hline
439
+ GLFW\_ACCUM\_RED\_BITS & Number of bits for the red channel of the accumulator buffer.\\ \hline
440
+ GLFW\_ACCUM\_GREEN\_BITS & Number of bits for the green channel of the accumulator buffer.\\ \hline
441
+ GLFW\_ACCUM\_BLUE\_BITS & Number of bits for the blue channel of the accumulator buffer.\\ \hline
442
+ GLFW\_ACCUM\_ALPHA\_BITS & Number of bits for the alpha channel of the accumulator buffer.\\ \hline
443
+ GLFW\_AUX\_BUFFERS & Number of auxiliary buffers.\\ \hline
444
+ GLFW\_STEREO & GL\_TRUE if stereo rendering is supported, else GL\_FALSE.\\ \hline
445
+ GLFW\_FSAA\_SAMPLES & Number of multisampling buffer samples. Zero indicated multisampling is disabled.\\ \hline
446
+ GLFW\_WINDOW\_NO\_RESIZE & GL\_TRUE if the window cannot be resized, else GL\_FALSE.\\ \hline
447
+ \end{tabular}
448
+ \end{center}
449
+ \caption{Window parameters for \textbf{glfwGetWindowParam}}
450
+ \label{tab:winparams}
451
+ \end{table}
452
+ %-------------------------------------------------------------------------
453
+
454
+ Another useful function is \textbf{glfwSetWindowSizeCallback}, which
455
+ specifies a user function that will be called every time the window size
456
+ has changed. The C syntax is:
457
+
458
+ \begin{lstlisting}
459
+ void glfwSetWindowSizeCallback( GLFWwindowsizefun cbfun )
460
+ \end{lstlisting}
461
+
462
+ The user function \textit{fun} should be of the type:
463
+
464
+ \begin{lstlisting}
465
+ void GLFWCALL fun( int width, int height )
466
+ \end{lstlisting}
467
+
468
+ The first argument passed to the user function is the width of the window,
469
+ and the second argument is the height of the window. Here is an example
470
+ of how to use a window size callback function:
471
+
472
+ \begin{lstlisting}
473
+ int WinWidth, WinHeight;
474
+
475
+ void GLFWCALL WindowResize( int width, int height )
476
+ {
477
+ WinWidth = width;
478
+ WinHeight = height;
479
+ }
480
+
481
+ int main( void )
482
+ {
483
+ ...
484
+ glfwSetWindowSizeCallback( WindowResize );
485
+ ...
486
+ }
487
+ \end{lstlisting}
488
+
489
+ Using a callback function for getting the window size is mostly useful for
490
+ windowed applications, since the window size may be changed at any time by
491
+ the user. It can also be used to determine the actual fullscreen
492
+ resolution.
493
+
494
+ An alternative to using a callback function for getting the window size,
495
+ is to use the function \textbf{glfwGetWindowSize}:
496
+
497
+ \begin{lstlisting}
498
+ void glfwGetWindowSize( int *width, int *height )
499
+ \end{lstlisting}
500
+
501
+ The \textit{width} and \textit{height} arguments are filled out with the
502
+ current window dimensions.
503
+
504
+
505
+ %-------------------------------------------------------------------------
506
+ \section{Buffer Swapping}
507
+ \GLFW\ windows are always double buffered. That means that you have two
508
+ rendering buffers; a front buffer and a back buffer. The front buffer is
509
+ the buffer that is being displayed, and the back buffer is not displayed.
510
+ \OpenGL\ lets you select which of these two buffers you want to render to
511
+ (with the \textbf{glDrawBuffer} command), but the default (and preferred)
512
+ rendering buffer is the back buffer. This way you will avoid flickering
513
+ and artifacts caused by graphics being only partly drawn at the same time
514
+ as the video raster beam is displaying the graphics on the monitor.
515
+
516
+ When an entire frame has been rendered to the back buffer, it is time to
517
+ swap the back and the front buffers in order to display the rendered
518
+ frame, and begin rendering a new frame. This is done with the command
519
+ \textbf{glfwSwapBuffers}. The C syntax is:
520
+
521
+ \begin{lstlisting}
522
+ void glfwSwapBuffers( void )
523
+ \end{lstlisting}
524
+
525
+ Besides swapping the front and back rendering buffers,
526
+ \textbf{glfwSwapBuffers} also calls \textbf{glfwPollEvents}\footnote{This
527
+ behavior can be disabled by calling \textbf{glfwDisable} with the argument
528
+ GLFW\_AUTO\_POLL\_EVENTS.}. This is to ensure frequent polling of events,
529
+ such as keyboard and mouse input, and window reshaping events.
530
+
531
+ Sometimes it can be useful to select when the buffer swap will occur. With
532
+ the function \textbf{glfwSwapInterval} it is possible to select the
533
+ minimum number of vertical retraces the video raster line should do before
534
+ swapping the buffers:
535
+
536
+ \begin{lstlisting}
537
+ void glfwSwapInterval( int interval )
538
+ \end{lstlisting}
539
+
540
+ If \textit{interval} is zero, the swap will take place immediately when
541
+ \textbf{glfwSwapBuffers} is called, without waiting for a vertical retrace
542
+ (also known as ``vsync off''). Otherwise at least \textit{interval}
543
+ retraces will pass between each buffer swap (also known as ``vsync on'').
544
+ Using a swap interval of zero can be useful for benchmarking purposes,
545
+ when it is not desirable to measure the time it takes to wait for the
546
+ vertical retrace. However, a swap interval of 1 generally gives better
547
+ visual quality.
548
+
549
+ It should be noted that not all \OpenGL\ implementations and hardware
550
+ support this function, in which case \textbf{glfwSwapInterval} will have
551
+ no effect. Sometimes it is only possible to affect the swap interval
552
+ through driver settings (e.g. the display settings under Windows, or as an
553
+ environment variable setting under Unix).
554
+
555
+
556
+ %-------------------------------------------------------------------------
557
+ \section{Querying Video Modes}
558
+ Although \GLFW\ generally does a good job at selecting a suitable video
559
+ mode for you when you open a fullscreen window, it is sometimes useful to
560
+ know exactly which modes are available on a certain system. For example,
561
+ you may want to present the user with a list of video modes to select
562
+ from. To get a list of available video modes, you can use the function
563
+ \textbf{glfwGetVideoModes}:
564
+
565
+ \begin{lstlisting}
566
+ int glfwGetVideoModes( GLFWvidmode *list, int maxcount )
567
+ \end{lstlisting}
568
+
569
+ The argument \textit{list} is a vector of GLFWvidmode structures, and
570
+ \textit{maxcount} is the maximum number of video modes that your vector
571
+ can hold. \textbf{glfwGetVideoModes} will return the actual number of
572
+ video modes detected on the system.
573
+
574
+ The GLFWvidmode structure looks like this:
575
+
576
+ \begin{lstlisting}
577
+ typedef struct {
578
+ int Width, Height; // Video resolution
579
+ int RedBits; // Red bits per pixel
580
+ int GreenBits; // Green bits per pixel
581
+ int BlueBits; // Blue bits per pixel
582
+ } GLFWvidmode;
583
+ \end{lstlisting}
584
+
585
+ Here is an example of retrieving all available video modes:
586
+
587
+ \begin{lstlisting}
588
+ int nummodes;
589
+ GLFWvidmode list[ 200 ];
590
+ nummodes = glfwGetVideoModes( list, 200 );
591
+ \end{lstlisting}
592
+
593
+ The returned list is sorted, first by color depth ($RedBits + GreenBits +
594
+ BlueBits$), and then by resolution ($Width\times Height$), with the
595
+ lowest resolution, fewest bits per pixel mode first.
596
+
597
+ To get the desktop video mode, use the function
598
+ \textbf{glfwGetDesktopMode}:
599
+
600
+ \begin{lstlisting}
601
+ void glfwGetDesktopMode( GLFWvidmode *mode )
602
+ \end{lstlisting}
603
+
604
+ The function returns the resolution and color depth of the user desktop in
605
+ the mode structure. Note that the user desktop mode is independent of the
606
+ current video mode if a \GLFW\ fullscreen window has been opened.
607
+
608
+
609
+ %-------------------------------------------------------------------------
610
+ % Input Handling
611
+ %-------------------------------------------------------------------------
612
+ \chapter{Input Handling}
613
+ \label{par:inputhandling}
614
+ \thispagestyle{fancy}
615
+ In this chapter you will learn how to use keyboard, mouse and joystick
616
+ input, using either polling or callback functions.
617
+
618
+
619
+ %-------------------------------------------------------------------------
620
+ \section{Event Polling}
621
+ The first thing to know about input handling in \GLFW\ is that all
622
+ keyboard and mouse input is collected by checking for input events. This
623
+ has do be done manually by calling either \textbf{glfwPollEvents} or
624
+ \textbf{glfwSwapBuffers} (which implicitly calls \textbf{glfwPollEvents}
625
+ for you). Normally this does not have to be a concern, since
626
+ \textbf{glfwSwapBuffers} is called every frame, which should be often
627
+ enough (about 10-100 times per second for a normal \OpenGL\ application).
628
+ One exception is when rendering is paused, and then the program waits for
629
+ input to begin animation again. In this case \textbf{glfwPollEvents} has
630
+ to be called repeatedly until any new input events arrive.
631
+
632
+ If it is not desirable that \textbf{glfwPollEvents is} called implicitly
633
+ from \textbf{glfwSwapBuffers}, call \textbf{glfwDisable} with the argument
634
+ GLFW\_AUTO\_POLL\_EVENTS.
635
+
636
+ Note that event polling is not needed for joystick input, since all
637
+ relevant joystick state is gathered every time a joystick function is
638
+ called.
639
+
640
+
641
+ %-------------------------------------------------------------------------
642
+ \section{Keyboard Input}
643
+ \GLFW\ gives three options for getting keyboard input:
644
+
645
+ \begin{itemize}
646
+ \item Manually polling the state of individual keys.
647
+ \item Automatically receive new key state for any key, using a callback
648
+ function.
649
+ \item Automatically receive characters, using a callback function.
650
+ \end{itemize}
651
+
652
+ Depending on what the keyboard input will be used for, either of the
653
+ methods may be more suitable. The main difference between the two last
654
+ options is that while characters are affected by modifier keys (such as
655
+ shift), key state is independent of any modifier keys. Also, special keys
656
+ (such as function keys, cursor keys and modifier keys) are not reported to
657
+ the character callback function.
658
+
659
+ %-------------------------------------------------------------------------
660
+ \subsection{Key state}
661
+ To check if a key is held down or not at any given moment, use the
662
+ function \textbf{glfwGetKey}:
663
+
664
+ \begin{lstlisting}
665
+ int glfwGetKey( int key )
666
+ \end{lstlisting}
667
+
668
+ It queries the current status of individual keyboard keys. The argument
669
+ \textit{key} specifies which key to check, and it can be either an
670
+ uppercase ISO~8859-1 character, or a special key identifier.
671
+ \textbf{glfwGetKey} returns GLFW\_PRESS (or 1) if the key is currently
672
+ held down, or GLFW\_RELEASE (or 0) if the key is not being held down.
673
+
674
+ In most situations, it may be useful to know if a key has been pressed and
675
+ released between two calls to \textbf{glfwGetKey} (especially if the
676
+ animation is fairly slow, which may allow the user to press and release a
677
+ key between two calls to \textbf{glfwGetKey}). This can be accomplished by
678
+ enabling sticky keys, which is done by calling \textbf{glfwEnable} with
679
+ the argument GLFW\_STICKY\_KEYS, as in the following example:
680
+
681
+ \begin{lstlisting}
682
+ glfwEnable( GLFW_STICKY_KEYS );
683
+ \end{lstlisting}
684
+
685
+ When sticky keys are enabled, a key will not be released until it is
686
+ checked with \textbf{glfwGetKey}. To disable sticky keys, call
687
+ \textbf{glfwDisable} witht the argument GLFW\_STICKY\_KEYS. Then all keys
688
+ that are not currently held down will be released, and future key releases
689
+ will take place immediately when the user releases the key, without
690
+ waiting for \textbf{glfwGetKey} to check the key. By default sticky keys
691
+ are disabled.
692
+
693
+ Sticky keys are often very useful and should be used in most cases where
694
+ \textbf{glfwGetKey} is used. There is however a danger involved with
695
+ enabling sticky keys, and that is that keys that are pressed by the user
696
+ but are not checked with \textbf{glfwGetKey}, may remain ``pressed'' for a
697
+ very long time. A typical situation where this may be dangerous is in a
698
+ program that consists of two or more sections (e.g. a menu section and a
699
+ game section). If the first section enables sticky keys but does not check
700
+ for keys which the second section checks for, there is a potential of
701
+ recording many key presses in the first section that will be detected in
702
+ the second section. To avoid this problem, always disable sticky keys
703
+ before leaving a section of a program.
704
+
705
+ An alternative to using \textbf{glfwGetKey} is to register a keyboard
706
+ input callback function with \textbf{glfwSetKeyCallback}:
707
+
708
+ \begin{lstlisting}
709
+ void glfwSetKeyCallback( GLFWkeyfun cbfun )
710
+ \end{lstlisting}
711
+
712
+ The argument \textit{fun} is a pointer to a callback function. The
713
+ callback function shall take two integer arguments. The first is the key
714
+ identifier, and the second is the new key state, which can be GLFW\_PRESS
715
+ or GLFW\_RELEASE. To unregister a callback function, call
716
+ \textbf{glfwSetKeyCallback} with \textit{fun} = NULL.
717
+
718
+ A callback function can be useful in some situations. For instance it can
719
+ replace multiple \textbf{glfwGetKey} calls with a switch/case statement.
720
+
721
+ %-------------------------------------------------------------------------
722
+ \subsection{Character input}
723
+ If the keyboard is to be used as a text input device (e.g. in a user
724
+ dialog) rather than as a set of independent buttons, a character callback
725
+ function is more suitable. To register a character callback function, use
726
+ \textbf{glfwSetCharCallback}:
727
+
728
+ \begin{lstlisting}
729
+ void glfwSetCharCallback( GLFWcharfun cbfun )
730
+ \end{lstlisting}
731
+
732
+ The argument \textit{fun} is a pointer to a callback function. The
733
+ callback function shall take two integer arguments. The first is a Unicode
734
+ character code, and the second is GLFW\_PRESS if the key that generated
735
+ the character was pressed, or GLFW\_RELEASE if it was released. To
736
+ unregister a callback function, call \textbf{glfwSetCharCallback} with
737
+ \textit{fun} = NULL.
738
+
739
+ The Unicode character set is an international standard for encoding
740
+ characters. It is much more comprehensive than seven or eight bit
741
+ character sets (e.g. US-ASCII and Latin~1), and includes characters for
742
+ most written languages in the world. It should be noted that Unicode
743
+ character codes 0 to 255 are the same as for ISO~8859-1 (Latin~1), so as
744
+ long as a proper range check is performed on the Unicode character code,
745
+ it can be used just as an eight bit Latin~1 character code (which can be
746
+ useful if full Unicode support is not possible).
747
+
748
+
749
+ %-------------------------------------------------------------------------
750
+ \subsection{Key repeat}
751
+ By default, \GLFW\ does not report key repeats when a key is held down.
752
+ To activate key repeat, call \textbf{glfwEnable} with the argument
753
+ GLFW\_KEY\_REPEAT:
754
+
755
+ \begin{lstlisting}
756
+ glfwEnable( GLFW_KEY_REPEAT );
757
+ \end{lstlisting}
758
+
759
+ This will let a registered key or character callback function receive key
760
+ repeat events when a key is held down.
761
+
762
+
763
+ %-------------------------------------------------------------------------
764
+ \subsection{Special system keys}
765
+ On most systems there are some special system keys that are normally not
766
+ intercepted by an application. For instance, under Windows it is possible
767
+ to switch programs by pressing \texttt{ALT+TAB}, which brings up a list of
768
+ running programs to select from. In certain situations it can be desirable
769
+ to prevent such special system keys from interfering with the program.
770
+ With \GLFW\ it is possible to do by calling \textbf{glfwDisable} with the
771
+ argument GLFW\_SYSTEM\_KEYS:
772
+
773
+ \begin{lstlisting}
774
+ glfwDisable( GLFW_SYSTEM_KEYS );
775
+ \end{lstlisting}
776
+
777
+ By doing so, most system keys will have no effect and will not interfere
778
+ with your program. System keys can be re-enabled by calling
779
+ \textbf{glfwEnable} with the argument GLFW\_SYSTEM\_KEYS. By default,
780
+ system keys are enabled.
781
+
782
+
783
+ %-------------------------------------------------------------------------
784
+ \section{Mouse Input}
785
+ Just like for keyboard input, mouse input can be realized with either
786
+ polling or callback functions.
787
+
788
+
789
+ %-------------------------------------------------------------------------
790
+ \subsection{Mouse position}
791
+ To read the mouse position, you can use the function
792
+ \textbf{glfwGetMousePos}:
793
+
794
+ \begin{lstlisting}
795
+ void glfwGetMousePos( int *x, int *y )
796
+ \end{lstlisting}
797
+
798
+ The arguments \textit{x} and \textit{y} point to integer variables that
799
+ will be updated with the current absolute mouse position. An alternative
800
+ is to use a callback function instead, which can be set with
801
+ \textbf{glfwSetMousePosCallback}:
802
+
803
+ \begin{lstlisting}
804
+ void glfwSetMousePosCallback( GLFWmouseposfun cbfun )
805
+ \end{lstlisting}
806
+
807
+ The function that \textit{fun} points to will be called every time the
808
+ mouse position changes. The first argument to the callback function is
809
+ the mouse x position, and the second argument is the mouse y position.
810
+
811
+
812
+ %-------------------------------------------------------------------------
813
+ \subsection{Mouse buttons}
814
+ To query the state of a mouse button, call \textbf{glfwGetMouseButton}:
815
+
816
+ \begin{lstlisting}
817
+ int glfwGetMouseButton( int button )
818
+ \end{lstlisting}
819
+
820
+ The argument \textit{button} can be one of the following mouse button
821
+ identifiers: GLFW\_MOUSE\_BUTTON\_LEFT, GLFW\_MOUSE\_BUTTON\_RIGHT or
822
+ GLFW\_MOUSE\_BUTTON\_MIDDLE. \textbf{glfwGetMouseButton} will return
823
+ GLFW\_PRESS (which is a non-zero value) if the corresponding mouse
824
+ button is held down, otherwise it will return GLFW\_RELEASE (which is
825
+ equal to zero).
826
+
827
+ Just as it is possible to make keys ``sticky'', it is also possible to
828
+ make mouse buttons appear as held down until the button is checked for
829
+ with \textbf{glfwGetMouseButton}. To enable sticky mouse buttons, call
830
+ \textbf{glfwEnable} with the argument GLFW\_STICKY\_MOUSE\_BUTTONS.
831
+
832
+ When sticky mouse buttons are enabled, a mouse button will not be released
833
+ until it is checked with \textbf{glfwGetMouseButton}. To disable sticky
834
+ mouse buttons, call \textbf{glfwDisable} with the argument
835
+ GLFW\_STICKY\_MOUSE\_BUTTONS. Then all mouse buttons that are not
836
+ currently held down will be released, and future mouse button releases
837
+ will take place immediately when the user releases the mouse button,
838
+ without waiting for \textbf{glfwGetMouseButton} to check for the mouse
839
+ button. By default sticky mouse buttons are disabled.
840
+
841
+ There is also a callback function for mouse button activities, which can
842
+ be set with \textbf{glfwSetMouseButtonCallback}:
843
+
844
+ \begin{lstlisting}
845
+ void glfwSetMouseButtonCallback( GLFWmousebuttonfun fun )
846
+ \end{lstlisting}
847
+
848
+ The argument \textit{fun} specifies a function that will be called
849
+ whenever a mouse button is pressed or released, or NULL to unregister a
850
+ callback function. The first argument to the callback function is a mouse
851
+ button identifier, and the second is either GLFW\_PRESS or GLFW\_RELEASE,
852
+ depending on the new state of the corresponding mouse button.
853
+
854
+
855
+ %-------------------------------------------------------------------------
856
+ \subsection{Mouse wheel}
857
+ Some mice have a mouse wheel, which can be thought of as a third mouse
858
+ axis. To get the position of the mouse wheel, call
859
+ \textbf{glfwGetMouseWheel}:
860
+
861
+ \begin{lstlisting}
862
+ int glfwGetMouseWheel( void )
863
+ \end{lstlisting}
864
+
865
+ The function returns an integer that represents the position of the mouse
866
+ wheel. When the user turns the wheel, the wheel position will increase or
867
+ decrease.
868
+
869
+ It is also possible to register a callback function for mouse wheel events
870
+ with the \textbf{glfwSetMouseWheelCallback} function:
871
+
872
+ \begin{lstlisting}
873
+ void glfwSetMouseWheelCallback( GLFWmousewheelfun fun )
874
+ \end{lstlisting}
875
+
876
+ The argument \textit{fun} specifies a function that will be called
877
+ whenever the mouse wheel is moved, or NULL to unregister a callback
878
+ function. The argument to the callback function is the position of the
879
+ mouse wheel.
880
+
881
+
882
+ %-------------------------------------------------------------------------
883
+ \subsection{Hiding the mouse cursor}
884
+ It is possible to hide the mouse cursor with the function call:
885
+
886
+ \begin{lstlisting}
887
+ glfwDisable( GLFW_MOUSE_CURSOR );
888
+ \end{lstlisting}
889
+
890
+ Hiding the mouse cursor has three effects:
891
+
892
+ \begin{enumerate}
893
+ \item The cursor becomes invisible.
894
+ \item The cursor is guaranteed to be confined to the window.
895
+ \item Mouse coordinates are not limited to the window size.
896
+ \end{enumerate}
897
+
898
+ To show the mouse cursor again, call \textbf{glfwEnable} with the
899
+ argument GLFW\_MOUSE\_CURSOR:
900
+
901
+ \begin{lstlisting}
902
+ glfwEnable( GLFW_MOUSE_CURSOR );
903
+ \end{lstlisting}
904
+
905
+ By default the mouse cursor is hidden if a window is opened in fullscreen
906
+ mode, otherwise it is not hidden.
907
+
908
+
909
+ %-------------------------------------------------------------------------
910
+ \section{Joystick Input}
911
+ \GLFW\ has support for up to sixteen joysticks, and an infinite\footnote{%
912
+ There are of course actual limitations posed by the underlying hardware,
913
+ drivers and operation system.} number of axes and buttons per joystick.
914
+ Unlike keyboard and mouse input, joystick input does not need an opened
915
+ window, and \textbf{glfwPollEvents} or \textbf{glfwSwapBuffers} does not
916
+ have to be called in order for joystick state to be updated.
917
+
918
+
919
+ %-------------------------------------------------------------------------
920
+ \subsection{Joystick capabilities}
921
+ First, it is often necessary to determine if a joystick is connected, and
922
+ what its capabilities are. To get this information the function
923
+ \textbf{glfwGetJoystickParam} can be used:
924
+
925
+ \begin{lstlisting}
926
+ int glfwGetJoystickParam( int joy, int param )
927
+ \end{lstlisting}
928
+
929
+ The \textit{joy} argument specifies which joystick to retrieve the
930
+ parameter from, and it should be GLFW\_JOYSTICK\_\textit{n}, where
931
+ \textit{n} is in the range 1 to 16. The \textit{param} argument specifies
932
+ which parameter to retrieve. To determine if a joystick is connected,
933
+ \textit{param} should be GLFW\_PRESENT, which will cause the function to
934
+ return GL\_TRUE if the joystick is connected, or GL\_FALSE if it is not.
935
+ To determine the number of axes or buttons that are supported by the
936
+ joystick, \textit{param} should be GLFW\_AXES or GLFW\_BUTTONS,
937
+ respectively.
938
+
939
+
940
+ %-------------------------------------------------------------------------
941
+ \subsection{Joystick position}
942
+ To get the current axis positions of the joystick, the
943
+ \textbf{glfwGetJoystickPos} is used:
944
+
945
+ \begin{lstlisting}
946
+ int glfwGetJoystickPos( int joy, float *pos, int numaxes )
947
+ \end{lstlisting}
948
+
949
+ As with \textbf{glfwGetJoystickParam}, the \textit{joy} argument
950
+ specifies which joystick to retrieve information from. The
951
+ \textit{numaxes} argument specifies how many axes to return, and the
952
+ \textit{pos} argument specifies an array in which all the axis positions
953
+ are stored. The function returns the actual number of axes that were
954
+ returned, which could be less than \textit{numaxes} if the joystick does
955
+ not support all the requested axes, or if the joystick is not connected.
956
+
957
+ For instance, to get the position of the first two axes (the X and Y axes)
958
+ of joystick 1, the following code can be used:
959
+
960
+ \begin{lstlisting}
961
+ float position[ 2 ];
962
+
963
+ glfwGetJoystickPos( GLFW_JOYSTICK_1, position, 2 );
964
+ \end{lstlisting}
965
+
966
+ After this call, the first element of the \textit{position} array will
967
+ hold the X axis position of the joystick, and the second element will hold
968
+ the Y axis position. In this example we do not use the information about
969
+ how many axes were really returned.
970
+
971
+ The position of an axis can be in the range -1.0 to 1.0, where positive
972
+ values represent right, forward or up directions, while negative values
973
+ represent left, back or down directions. If a requested axis is not
974
+ supported by the joystick, the corresponding array element will be set
975
+ to zero. The same goes for the situation when the joystick is not
976
+ connected (all axes are treated as unsupported).
977
+
978
+
979
+ %-------------------------------------------------------------------------
980
+ \subsection{Joystick buttons}
981
+ A function similar to the \textbf{glfwGetJoystickPos} function is
982
+ available for querying the state of joystick buttons, namely the
983
+ \textbf{glfwGetJoystickButtons} function:
984
+
985
+ \begin{lstlisting}
986
+ int glfwGetJoystickButtons( int joy, unsigned char *buttons,
987
+ int numbuttons )
988
+ \end{lstlisting}
989
+
990
+ The function works just like the \textbf{glfwGetJoystickAxis} function,
991
+ except that it returns the state of joystick buttons instead of axis
992
+ positions. Each button in the array specified by the \textit{buttons}
993
+ argument can be either GLFW\_PRESS or GLFW\_RELEASE, telling if the
994
+ corresponding button is currently held down or not. Unsupported buttons
995
+ will have the value GLFW\_RELEASE.
996
+
997
+
998
+ %-------------------------------------------------------------------------
999
+ % Timing
1000
+ %-------------------------------------------------------------------------
1001
+ \chapter{Timing}
1002
+ \thispagestyle{fancy}
1003
+
1004
+ %-------------------------------------------------------------------------
1005
+ \section{High Resolution Timer}
1006
+ In most applications, it is useful to know exactly how much time has
1007
+ passed between point $A$ and point $B$ in a program. A typical situation
1008
+ is in a game, where you need to know how much time has passed between two
1009
+ rendered frames in order to calculate the correct movement and physics
1010
+ etc. Another example is when you want to benchmark a certain piece of
1011
+ code.
1012
+
1013
+ \GLFW\ provides a high-resolution timer, which reports a double precision
1014
+ floating point value representing the number of seconds that have passed
1015
+ since \textbf{glfwInit} was called. The timer is accessed with the
1016
+ function \textbf{glfwGetTime}:
1017
+
1018
+ \begin{lstlisting}
1019
+ double glfwGetTime( void )
1020
+ \end{lstlisting}
1021
+
1022
+ The precision of the timer depends on which computer and operating
1023
+ system you are running, but it is almost guaranteed to be better than
1024
+ $10~ms$, and in most cases it is much better than $1~ms$ (on a modern PC
1025
+ you can get resolutions in the order of $1~ns$).
1026
+
1027
+ It is possible to set the value of the high precision timer using the
1028
+ \textbf{glfwSetTime} function:
1029
+
1030
+ \begin{lstlisting}
1031
+ void glfwSetTime( double time )
1032
+ \end{lstlisting}
1033
+
1034
+ The argument \textit{time} is the time, in seconds, that the timer should
1035
+ be set to.
1036
+
1037
+
1038
+ %-------------------------------------------------------------------------
1039
+ \section{Sleep}
1040
+ Sometimes it can be useful to put a program to sleep for a short time. It
1041
+ can be used to reduce the CPU load in various situations. For this
1042
+ purpose, there is a function called \textbf{glfwSleep}, which has the
1043
+ following C syntax:
1044
+
1045
+ \begin{lstlisting}
1046
+ void glfwSleep( double time )
1047
+ \end{lstlisting}
1048
+
1049
+ The function will put the calling thread to sleep for the time specified
1050
+ with the argument \textit{time}, which has the unit seconds. When
1051
+ \textbf{glfwSleep} is called, the calling thread will be put in waiting
1052
+ state, and thus will not consume any CPU time.
1053
+
1054
+ Note that there is generally a minimum sleep time that will be recognized
1055
+ by the operating system, which is usually coupled to the task-switching
1056
+ interval. This minimum time is often in the range $5~-~20 ms$, and it is
1057
+ not possible to make a thread sleep for less than that time. Specifying a
1058
+ very small sleep time may result in \textbf{glfwSleep} returning
1059
+ immediately, without putting the thread to sleep.
1060
+
1061
+
1062
+ %-------------------------------------------------------------------------
1063
+ % Image and Texture Import
1064
+ %-------------------------------------------------------------------------
1065
+ \chapter{Image and Texture Import}
1066
+ \thispagestyle{fancy}
1067
+ In many, if not most, \OpenGL\ applications you want to use pre-generated
1068
+ 2D images for surface textures, light maps, transparency maps etc.
1069
+ Typically these images are stored with a standard image format in a file,
1070
+ which requires the program to decode and load the image(s) from file(s),
1071
+ which can require much work from the programmer.
1072
+
1073
+ To make life easier for \OpenGL\ developers, \GLFW\ has built-in support
1074
+ for loading images from files.
1075
+
1076
+
1077
+ %-------------------------------------------------------------------------
1078
+ \section{Texture Loading}
1079
+ To load a texture from a file, you can use the function
1080
+ \textbf{glfwLoadTexture2D}:
1081
+
1082
+ \begin{lstlisting}
1083
+ int glfwLoadTexture2D( const char *name, int flags )
1084
+ \end{lstlisting}
1085
+
1086
+ This function reads a 2D image from a Truevision Targa format file (.TGA)
1087
+ with the name given by \textit{name}, and uploads it to texture memory.
1088
+ It is similar to the \OpenGL\ function \textbf{glTexImage2D}, except that
1089
+ the image data is read from a file instead of from main memory, and all
1090
+ the pixel format and data storage flags are handled automatically. The
1091
+ \textit{flags} argument can be used to control how the texture is
1092
+ loaded.
1093
+
1094
+ If \textit{flags} is GLFW\_ORIGIN\_UL\_BIT, the origin of the
1095
+ texture will be the upper left corner (otherwise it is the lower left
1096
+ corner). If \textit{flags} is GLFW\_BUILD\_MIPMAPS\_BIT, all mipmap levels
1097
+ will be generated and uploaded to texture memory (otherwise only one
1098
+ mipmap level is loaded). If \textit{flags} is GLFW\_ALPHA\_MAP\_BIT, then
1099
+ any gray scale images will be loaded as alpha maps rather than luminance
1100
+ maps.
1101
+
1102
+ To make combinations of the flags, or them together (e.g. like this:
1103
+ \texttt{GLFW\_ORIGIN\_UL\_BIT | GLFW\_BUILD\_MIPMAPS\_BIT}).
1104
+
1105
+ Here is an example of how to upload a texture from a file to \OpenGL\
1106
+ texture memory, and configure the texture for trilinear interpolation
1107
+ (assuming an \OpenGL\ window has been opened successfully):
1108
+
1109
+ \begin{mysamepage}[10]
1110
+ \begin{lstlisting}
1111
+ // Load texture from file, and build all mipmap levels
1112
+ glfwLoadTexture2D( "mytexture.tga", GLFW_BUILD_MIPMAPS_BIT );
1113
+
1114
+ // Use trilinear interpolation for minification
1115
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
1116
+ GL_LINEAR_MIPMAP_LINEAR );
1117
+
1118
+ // Use bilinear interpolation for magnification
1119
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
1120
+ GL_LINEAR );
1121
+
1122
+ // Enable texturing
1123
+ glEnable( GL_TEXTURE_2D );
1124
+ \end{lstlisting}
1125
+ \end{mysamepage}
1126
+
1127
+ As you can see, \textbf{glfwLoadTexture2D} is very easy to use. Since it
1128
+ can also automatically create mipmaps when required, it is also a very
1129
+ powerful function.
1130
+
1131
+
1132
+ %-------------------------------------------------------------------------
1133
+ \section{Image Loading}
1134
+ In certain cases it may be useful to be able to load an image into client
1135
+ memory (application memory), without directly uploading the image to
1136
+ \OpenGL\ texture memory. For example, one may wish to retain a copy of the
1137
+ texture in local memory for future use. Another example is when the image
1138
+ is not to be used as a texture at all, e.g. if it is to be used as a
1139
+ height map.
1140
+
1141
+ \GLFW\ also offers the possibility to load an image to application memory,
1142
+ using the \textbf{glfwReadImage} function:
1143
+
1144
+ \begin{lstlisting}
1145
+ int glfwReadImage( const char *name, GLFWimage *img, int flags )
1146
+ \end{lstlisting}
1147
+
1148
+ The function reads the image given by the argument \textit{name}, and upon
1149
+ success stores the relevant image information and pixel data in the
1150
+ GLFWimage structure \textit{img}. The GLFWimage structure is defined as:
1151
+
1152
+ \begin{lstlisting}
1153
+ typedef struct {
1154
+ int Width, Height; // Image dimensions
1155
+ int Format; // OpenGL pixel format
1156
+ int BytesPerPixel; // Number of bytes per pixel
1157
+ unsigned char *Data; // Pointer to pixel data
1158
+ } GLFWimage;
1159
+ \end{lstlisting}
1160
+
1161
+ \textit{Data} points to the loaded pixel data. If the function loaded the
1162
+ image successfully, GL\_TRUE is returned, otherwise GL\_FALSE is returned.
1163
+
1164
+ Possible flags for the \textit{flags} argument are GLFW\_ORIGIN\_UL\_BIT,
1165
+ GLFW\_NO\_RESCALE\_BIT and GLFW\_ALPHA\_MAP\_BIT. GLFW\_ORIGIN\_UL\_BIT
1166
+ and GLFW\_ALPHA\_MAP\_BIT work as described for the \textbf{glfwLoadTexture2D}
1167
+ function. If the GLFW\_NO\_RESCALE\_BIT flag is set, the image will not be
1168
+ rescaled to the closest larger $2^m\times 2^n$ resolution, which is
1169
+ otherwise the default action for images with non-power-of-two dimenstions.
1170
+
1171
+ When an image that was loaded with the \textbf{glfwReadImage} function is
1172
+ not used anymore (e.g. when it has been uploaded to texture memory), you
1173
+ should use the function \textbf{glfwFreeImage} to free the allocated
1174
+ memory:
1175
+
1176
+ \begin{lstlisting}
1177
+ void glfwFreeImage( GLFWimage *img )
1178
+ \end{lstlisting}
1179
+
1180
+
1181
+ %-------------------------------------------------------------------------
1182
+ % OpenGL Extension Support
1183
+ %-------------------------------------------------------------------------
1184
+ \chapter{OpenGL Extension Support}
1185
+ \thispagestyle{fancy}
1186
+ One of the benefits of \OpenGL\ is that it is extensible. Independent
1187
+ hardware vendors (IHVs) may include functionality in their \OpenGL\
1188
+ implementations that exceed that of the \OpenGL\ standard.
1189
+
1190
+ An extension is defined by:
1191
+
1192
+ \begin{enumerate}
1193
+ \item An extension name (e.g. GL\_ARB\_multitexture).
1194
+ \item New OpenGL tokens (e.g. GL\_TEXTURE1\_ARB).
1195
+ \item New OpenGL functions (e.g. \textbf{glActiveTextureARB}).
1196
+ \end{enumerate}
1197
+
1198
+ A list of official extensions, together with their definitions, can be
1199
+ found at the \textit{OpenGL Extension Registry}
1200
+ (\url{http://oss.sgi.com/projects/ogl-sample/registry/}).
1201
+
1202
+ To use a certain extension, the following steps must be performed:
1203
+
1204
+ \begin{enumerate}
1205
+ \item A compile time check for the support of the extension.
1206
+ \item A run time check for the support of the extension.
1207
+ \item Fetch function pointers for the extended \OpenGL\ functions (done at
1208
+ run time).
1209
+ \end{enumerate}
1210
+
1211
+ How this is done using \GLFW\ is described in the following sections.
1212
+ Please note that this chapter covers some advanced topics, and is quite
1213
+ specific to the C programming language.
1214
+
1215
+
1216
+ %-------------------------------------------------------------------------
1217
+ \section{Compile Time Check}
1218
+ The compile time check is necessary to perform in order to know if the
1219
+ compiler include files have defined the necessary tokens. It is very easy
1220
+ to do. The include file \texttt{GL/gl.h} will define a constant with the
1221
+ same name as the extension, if all the extension tokens are defined. Here
1222
+ is an example of how to check for the extension GL\_ARB\_multitexture:
1223
+
1224
+ \begin{lstlisting}
1225
+ #ifdef GL_ARB_multitexture
1226
+ // Extension is supported by the include files
1227
+ #else
1228
+ // Extension is not supported by the include files
1229
+ // Update your <GL/gl.h> file!
1230
+ #endif
1231
+ \end{lstlisting}
1232
+
1233
+
1234
+ %-------------------------------------------------------------------------
1235
+ \section{Runtime Check}
1236
+ Even if the compiler include files have defined all the necessary tokens,
1237
+ the target system may not support the extension (perhaps it has a
1238
+ different graphic card with a different \OpenGL\ implementation, or it has
1239
+ an older driver). That is why it is necessary to do a run time check for
1240
+ the extension support as well. This is done with the \GLFW\ function
1241
+ \textbf{glfwExtensionSupported}, which has the C syntax:
1242
+
1243
+ \begin{lstlisting}
1244
+ int glfwExtensionSupported( const char *extension )
1245
+ \end{lstlisting}
1246
+
1247
+ The argument \textit{extension} is a null terminated ISO~8859-1 string
1248
+ with the extension name. \textbf{glfwExtensionSupported} returns GL\_TRUE
1249
+ if the extension is supported, otherwise it returns GL\_FALSE.
1250
+
1251
+ Let us extend the previous example of checking for support of the
1252
+ extension GL\_ARB\_multitexture. This time we add a run time check, and a
1253
+ variable which we set to GL\_TRUE if the extension is supported, or
1254
+ GL\_FALSE if it is not supported.
1255
+
1256
+ \begin{lstlisting}
1257
+ int multitexture_supported;
1258
+
1259
+ #ifdef GL_ARB_multitexture
1260
+ // Check if extension is supported at run time
1261
+ multitexture_supported =
1262
+ glfwExtensionSupported( "GL_ARB_multitexture" );
1263
+ #else
1264
+ // Extension is not supported by the include files
1265
+ // Update your <GL/gl.h> file!
1266
+ multitexture_supported = GL_FALSE;
1267
+ #endif
1268
+ \end{lstlisting}
1269
+
1270
+ Now it is easy to check for the extension within the program, simply do:
1271
+
1272
+ \begin{lstlisting}
1273
+ if( multitexture_supported )
1274
+ {
1275
+ // Use multi texturing
1276
+ }
1277
+ else
1278
+ {
1279
+ // Use some other solution (or fail)
1280
+ }
1281
+ \end{lstlisting}
1282
+
1283
+
1284
+ %-------------------------------------------------------------------------
1285
+ \section{Fetching Function Pointers}
1286
+ Some extensions (not all) require the use of new \OpenGL\ functions, which
1287
+ are not necessarily defined by your link libraries. Thus it is necessary
1288
+ to get the function pointers dynamically at run time. This is done with
1289
+ the \GLFW\ function \textbf{glfwGetProcAddress}:
1290
+
1291
+ \begin{lstlisting}
1292
+ void * glfwGetProcAddress( const char *procname )
1293
+ \end{lstlisting}
1294
+
1295
+ The argument \textit{procname} is a null terminated ISO~8859-1 string
1296
+ holding the name of the \OpenGL\ function. \textbf{glfwGetProcAddress}
1297
+ returns the address to the function if the function is available,
1298
+ otherwise NULL is returned.
1299
+
1300
+ Obviously, fetching the function pointer is trivial. For instance, if we
1301
+ want to obtain the pointer to \textbf{glActiveTextureARB}, we simply call:
1302
+
1303
+ \begin{lstlisting}
1304
+ glActiveTextureARB = glfwGetProcAddress( "glActiveTextureARB" );
1305
+ \end{lstlisting}
1306
+
1307
+ However, there are many possible naming and type definition conflicts
1308
+ involved with such an operation, which may result in compiler warnings or
1309
+ errors. My proposed solution is the following:
1310
+
1311
+ \begin{itemize}
1312
+ \item Do not use the function name for the variable name. Use something
1313
+ similar (perhaps with a prefix or suffix), and then use
1314
+ \texttt{\#define} to map the function name to your variable.
1315
+ \item The standard type definition naming convention for function pointers
1316
+ is \texttt{PFN\textit{xxxx}PROC}, where \texttt{\textit{xxxx}} is
1317
+ the uppercase version of the function name (e.g.
1318
+ \texttt{PFNGLACTIVETEXTUREARBPROC}). Either make sure that a
1319
+ compatible \texttt{gl.h} and/or \texttt{glext.h} file is used by
1320
+ your compiler and rely on it to do the type definitions for you, or
1321
+ use a custom type definition naming convention (e.g.
1322
+ \texttt{\textit{xxxx}\_T} or something) and do the type definitions
1323
+ yourself.
1324
+ \end{itemize}
1325
+
1326
+ Here is an example of how to do it (here we use our own function pointer
1327
+ type defintion):
1328
+
1329
+ \begin{lstlisting}
1330
+ // Type definition of the function pointer
1331
+ typedef void (APIENTRY * GLACTIVETEXTUREARB_T) (GLenum texture);
1332
+
1333
+ // Function pointer
1334
+ GLACTIVETEXTUREARB_T _ActiveTextureARB;
1335
+ #define glActiveTextureARB _ActiveTextureARB
1336
+
1337
+ // Extension availability flag
1338
+ int multitexture_supported;
1339
+
1340
+ #ifdef GL_ARB_multitexture
1341
+ // Check if extension is supported at run time
1342
+ if( glfwExtensionSupported( "GL_ARB_multitexture" ) )
1343
+ {
1344
+ // Get the function pointer
1345
+ glActiveTextureARB = (GLACTIVETEXTUREARB_T)
1346
+ glfwGetProcAddress( "glActiveTextureARB" );
1347
+
1348
+ multitexture_supported = GL_TRUE;
1349
+ }
1350
+ else
1351
+ {
1352
+ multitexture_supported = GL_FALSE;
1353
+ }
1354
+ #else
1355
+ // Extension is not supported by the include files
1356
+ multitexture_supported = GL_FALSE;
1357
+ #endif
1358
+ \end{lstlisting}
1359
+
1360
+ Please note that the code example is not 100\% complete. First of all,
1361
+ the GL\_ARB\_multitexture extension defines many more functions than the
1362
+ single function that the code example defines. Secondly, checking if an
1363
+ extension is supported using \textbf{glfwExtensionSupported} is not enough
1364
+ to ensure that the corresponding functions will be valid. You also need to
1365
+ check if the function pointers returned by \textbf{glfwGetProcAddress} are
1366
+ non-NULL values.
1367
+
1368
+
1369
+ %-------------------------------------------------------------------------
1370
+ \subsection{Function pointer type definitions}
1371
+ To make a function pointer type definition, you need to know the function
1372
+ prototype. This can often be found in the extension definitions (e.g. at
1373
+ the \textit{OpenGL Extension Registry}). All the functions that are
1374
+ defined for an extension are listed with their C prototype definitions
1375
+ under the section \textit{New Procedures and Functions} in the extension
1376
+ definition.
1377
+
1378
+ For instance, if we look at the definition of the
1379
+ GL\_ARB\_texture\_compression extension, we find a list of new functions.
1380
+ One of the functions looks like this:
1381
+
1382
+ \begin{lstlisting}
1383
+ void GetCompressedTexImageARB(enum target, int lod, void *img);
1384
+ \end{lstlisting}
1385
+
1386
+ Like in most official \OpenGL\ documentation, all the \texttt{GL} and
1387
+ \texttt{gl} prefixes have been left out. In other words, the real function
1388
+ prototype would look like this:
1389
+
1390
+ \begin{lstlisting}
1391
+ void glGetCompressedTexImageARB(GLenum target, GLint lod, void *img);
1392
+ \end{lstlisting}
1393
+
1394
+ All we have to do to turn this prototype definition into a function
1395
+ pointer type definition, is to replace the function name with
1396
+ \texttt{(APIENTRY * \textit{xxxx}\_T)}, where \textit{xxxx} is the
1397
+ uppercase version of the name (according to the proposed naming
1398
+ convention). The keyword \texttt{APIENTRY} is needed to be compatible
1399
+ between different platforms. The \GLFW\ include file \texttt{GL/glfw.h}
1400
+ always makes sure that \texttt{APIENTRY} is properly defined, regardless
1401
+ of which platform the program is compiled on.
1402
+
1403
+ In other words, for the function \textbf{glGetCompressedTexImageARB} we
1404
+ get:
1405
+
1406
+ \begin{lstlisting}
1407
+ typedef void (APIENTRY * GLGETCOMPRESSEDTEXIMAGEARB_T)
1408
+ (GLenum target, GLint level, void *img);
1409
+ \end{lstlisting}
1410
+
1411
+
1412
+
1413
+ %-------------------------------------------------------------------------
1414
+ % Multi Threading
1415
+ %-------------------------------------------------------------------------
1416
+ \chapter{Multi Threading}
1417
+ \thispagestyle{fancy}
1418
+ Multi threading may not seem to be related to \OpenGL , and thus it may
1419
+ seem to be out of the scope of \GLFW\ to provide multi threading support.
1420
+ The initial intent of \GLFW\ was to provide the very basic functionality
1421
+ needed to create an \OpenGL\ application, but as \GLFW\ grew to be a
1422
+ platform for portable \OpenGL\ applications, it felt natural to include an
1423
+ operating system independent multi threading layer in \GLFW . Hopefully
1424
+ this will make \GLFW\ more attractive for advanced \OpenGL\ developers, as
1425
+ well as inspire more programmers to use multi threading.
1426
+
1427
+ In this chapter you will learn about multi threading and how you can use
1428
+ \GLFW\ to create multi threaded applications.
1429
+
1430
+
1431
+ %-------------------------------------------------------------------------
1432
+ \section{Why Use Multi Threading?}
1433
+ Multi threading is not a new technology, neither is it an advanced
1434
+ technology. In fact, multi threading could be found as early as 1985 in
1435
+ consumer computers, namely the Amiga, whose operating system implemented
1436
+ preemptive multi threading. During the early and mid 90's, consumer level
1437
+ operating systems emerged for Intel based PCs that supported multi
1438
+ threading. Still, over a decade later, many programmers, especially game
1439
+ programmers, feel reluctant to using threading in their applications.
1440
+ Why?
1441
+
1442
+ There are probably many reasons that one can think of to avoid multi
1443
+ threading, but many of them are based on ignorance and myths. The foremost
1444
+ reason for not using multi threading is probably that it requires a new
1445
+ way of thinking, but once accepted, threaded programming can take your
1446
+ program to new performance levels and solve many problematic timing and
1447
+ synchronization issues.
1448
+
1449
+ In the following sections a few key reasons for using multi threaded
1450
+ programming will be presented.
1451
+
1452
+
1453
+ %-------------------------------------------------------------------------
1454
+ \subsection{Take advantage of multi processor systems}
1455
+ If an application is divided into several threads that can execute
1456
+ concurrently, these threads will automatically execute on separate
1457
+ processors in parallel on an SMP (symmetric multi-processing) system.
1458
+
1459
+ Multi processor platforms are becoming increasingly common, in many
1460
+ different forms. The classic multi processor system is based around several
1461
+ processor chips that execute in parallel. More recent solutions focus on
1462
+ placing several processor cores on a single chip. These cores may be
1463
+ a few identical general purpose processors, or they may be several smaller,
1464
+ specialized cores, such as in the Cell architecture by IBM, which is
1465
+ used in the Playstation~3 game console.
1466
+
1467
+ Another emerging technology known as SMT (symmetric multi threading) is
1468
+ also becoming more and more popular. In short, it takes a single physical
1469
+ processor, and divides it into several logical processors that can execute
1470
+ separate threads. The idea behind this is to better utilize all available
1471
+ CPU resources by running independent pieces of code on the same physical
1472
+ CPU.
1473
+
1474
+ The problem with SMP systems is of course that if an application is not
1475
+ multi threaded, only one of the available processors will actually be
1476
+ used to execute the application. This is probably the most important
1477
+ aspect of multi threading. For SMP systems to be really useful, programs
1478
+ \emph{must} be multi threaded.
1479
+
1480
+
1481
+ %-------------------------------------------------------------------------
1482
+ \subsection{Avoid unnecessary waiting}
1483
+ In many situations, an application is placed in a wait state, waiting for
1484
+ a task to complete. Examples of such situations are: waiting for a file to
1485
+ load from disk, waiting for a vertical retrace (when using a double
1486
+ buffered display, such as a \GLFW\ \OpenGL\ window), waiting for a display
1487
+ to be cleared or data to be sent to the graphic card.
1488
+
1489
+ Some or all of these operations can be done asynchronously, if the
1490
+ conditions are right and the operating system supports it, but a simple
1491
+ and efficient way of avoiding unnecessary waits is to use multi threading.
1492
+ If there are several active threads in an application, a thread that was
1493
+ waiting for CPU time can start running as soon as another thread enters a
1494
+ wait state. This will speed up an application on both single and multi
1495
+ processor systems.
1496
+
1497
+
1498
+ %-------------------------------------------------------------------------
1499
+ \subsection{Improve real time performance}
1500
+ It is a known fact that an application becomes more responsive and
1501
+ exhibits less timing problems if different jobs are assigned to separate
1502
+ threads.
1503
+
1504
+ A typical example is streaming audio: when an audio buffer is empty, it
1505
+ has to be filled with new sound again within a limited amount of time, or
1506
+ strange sound loops or clicks may be the result. If a program is
1507
+ displaying graphics, loading files and playing audio at the same time (a
1508
+ typical game), it is very difficult to guarantee that the program will
1509
+ update the audio buffers in time if everything is performed in a single
1510
+ thread. On the other hand, if the audio buffer is updated from a separate
1511
+ thread, it becomes a very simple task.
1512
+
1513
+
1514
+ %-------------------------------------------------------------------------
1515
+ \section{How To Use Multi Threading}
1516
+ In general, every program runs as a process, which has its own memory
1517
+ space and its own set of resources, such as opened files etc. As a
1518
+ consequence, each process is coupled with a fairly large set of state.
1519
+ When the processor changes the execution from one process to another
1520
+ process, all this state has to be changed too (this is often referred to
1521
+ as a context switch), which can be quite costly.
1522
+
1523
+ Threads are sometimes referred to as ``lightweight processes'', which
1524
+ gives you a clue of what they are. In contrast to a process, a thread is a
1525
+ separate execution path within a process, which shares the same memory
1526
+ area and resources. This means that very little state has to be changed
1527
+ when switching execution between different threads (basically only the
1528
+ stack pointer and the processor registers). It also means that data
1529
+ exchange between threads is very simple, and there is little or no
1530
+ overhead in exchanging data, since program variables and data areas can be
1531
+ shared between threads.
1532
+
1533
+ Writing threaded applications may be very awkward before you get used to
1534
+ it, but there are a few key rules that are fairly simple to follow:
1535
+
1536
+ \begin{enumerate}
1537
+ \item ALWAYS assure exclusive access to data that is shared between threads!
1538
+ \item Make sure that threads are synchronized properly!
1539
+ \item NEVER busy wait!
1540
+ \end{enumerate}
1541
+
1542
+ In the following sections you will learn how to use the functionality of
1543
+ \GLFW\ to create threads and meet these rules, and hopefully you will find
1544
+ that it is not very difficult to write a multi threaded application.
1545
+
1546
+
1547
+ %-------------------------------------------------------------------------
1548
+ \section{Creating Threads}
1549
+ Creating a thread in \GLFW\ is very simple. You just call the function
1550
+ \textbf{glfwCreateThread}:
1551
+
1552
+ \begin{lstlisting}
1553
+ GLFWthread glfwCreateThread( GLFWthreadfun fun, void *arg )
1554
+ \end{lstlisting}
1555
+
1556
+ The argument \textit{fun} is a pointer to a function that will be
1557
+ executed by the new thread, and \textit{arg} is an argument that is passed
1558
+ to the thread. \textbf{glfwCreateThread} returns a positive thread ID
1559
+ number if the thread was created successfully, or a negative number if the
1560
+ thread could not be created.
1561
+
1562
+ When the thread function returns, the thread will die. In most cases, you
1563
+ want to know when the thread has finished. A thread can wait for another
1564
+ thread to die with the command \textbf{glfwWaitThread}:
1565
+
1566
+ \begin{lstlisting}
1567
+ int glfwWaitThread( GLFWthread ID, int waitmode )
1568
+ \end{lstlisting}
1569
+
1570
+ The argument \textit{ID} is the thread handle that was obtained when
1571
+ creating the thread. If \textit{waitmode} is GLFW\_NOWAIT,
1572
+ \textbf{glfwWaitThread} will return immediately with the value GL\_TRUE if
1573
+ the thread died, or GL\_FALSE if it is still alive. This can be useful if
1574
+ you only want to check if the thread is alive. If \textit{waitmode} is
1575
+ GLFW\_WAIT, \textbf{glfwWaitThread} will wait until the specified thread
1576
+ has died. Regardless of what \textit{waitmode} is, \textbf{glfwWaitThread}
1577
+ will return immediately if the thread does not exist (e.g. if the thread
1578
+ has already died or if ID is an invalid thread handle).
1579
+
1580
+ In some situations, you may want to brutally kill a thread without waiting
1581
+ for it to finish. This can be done with \textbf{glfwDestroyThread}:
1582
+
1583
+ \begin{lstlisting}
1584
+ void glfwDestroyThread( GLFWthread ID )
1585
+ \end{lstlisting}
1586
+
1587
+ It should be noted that \textbf{glfwDestroyThread} is a very dangerous
1588
+ operation, which may interrupt a thread in the middle of an important
1589
+ operation, which can result in lost data or deadlocks (when a thread is
1590
+ waiting for a condition to be raised, which can never be raised). In other
1591
+ words, do not use this function unless you really have to do it, and if
1592
+ you really know what you are doing (and what the thread that you are
1593
+ killing is doing)!
1594
+
1595
+ To sum up what we have learned so far, here is an example program which
1596
+ will print ``Hello world!'' (error checking has been left out for
1597
+ brevity):
1598
+
1599
+ \begin{mysamepage}[20]
1600
+ \begin{lstlisting}
1601
+ #include <stdio.h>
1602
+ #include <GL/glfw.h>
1603
+
1604
+ void GLFWCALL HelloFun( void *arg )
1605
+ {
1606
+ printf( "Hello " );
1607
+ }
1608
+
1609
+ int main( void )
1610
+ {
1611
+ GLFWthread thread;
1612
+
1613
+ glfwInit();
1614
+ thread = glfwCreateThread( HelloFun, NULL );
1615
+ glfwWaitThread( thread, GLFW_WAIT );
1616
+ printf( "world!\n" );
1617
+ glfwTerminate();
1618
+
1619
+ return 0;
1620
+ }
1621
+ \end{lstlisting}
1622
+ \end{mysamepage}
1623
+
1624
+ The program starts by initializing \GLFW , as always, and then it goes on
1625
+ by creating a thread that will execute the function \texttt{HelloFun}. The
1626
+ main thread then waits for the created thread to do its work and finish.
1627
+ Finally the main thread prints ``world!'', terminates \GLFW\ and exits.
1628
+ The result is that ``Hello world!'' will be printed in the console window.
1629
+
1630
+ You may have noticed that we have already used a simple form of thread
1631
+ synchronization, by waiting for the child thread to die before we print
1632
+ ``world!''. If we would have placed the wait command after the print
1633
+ command, there would be no way of knowing which word would be printed
1634
+ first (``Hello'' or ``world!''). Our program would then suffer from a race
1635
+ condition, which is a term used to describe a situation where two (or
1636
+ more) threads are competing to complete a task first.
1637
+
1638
+ In section \ref{par:condvar} you will learn how to do advanced thread
1639
+ synchronization using condition variables, which let threads wait for
1640
+ certain conditions before continuing execution.
1641
+
1642
+
1643
+ %-------------------------------------------------------------------------
1644
+ \section{Data Sharing Using Mutex Objects}
1645
+ In many situations you need to protect a certain data area while reading
1646
+ or modifying it, so that other threads do not start changing or reading
1647
+ the data while you are only half way through.
1648
+
1649
+ For instance, consider that you have a vector \textit{vec}, and a variable
1650
+ \textit{N} telling how many elements there are in the vector. What happens
1651
+ if thread $A$ adds an element to the vector at the same time as thread $B$
1652
+ is removing an element from the vector? Figure \ref{fig:nomutex} shows a
1653
+ possible scenario.
1654
+
1655
+ \begin{figure}[p]
1656
+ \begin{center}
1657
+ \begin{tabular}{cc}
1658
+ \textbf{Thread A} & \textbf{Thread B}\\
1659
+ \begin{minipage}{7cm}
1660
+ \lstset{backgroundcolor=\color{codeA}}
1661
+ \vspace{0.5\baselineskip}
1662
+ \begin{lstlisting}
1663
+ N ++;
1664
+ \end{lstlisting}
1665
+ \end{minipage}
1666
+ &
1667
+ \textit{waiting to exectue}
1668
+ \\
1669
+
1670
+ \textit{waiting to exectue}
1671
+ &
1672
+ \begin{minipage}{7cm}
1673
+ \vspace{0.5\baselineskip}
1674
+ \lstset{backgroundcolor=\color{codeB}}
1675
+ \begin{lstlisting}
1676
+ x = vec[ N-1 ];
1677
+ N --;
1678
+ \end{lstlisting}
1679
+ \end{minipage}
1680
+ \\
1681
+
1682
+ \begin{minipage}{7cm}
1683
+ \vspace{0.5\baselineskip}
1684
+ \lstset{backgroundcolor=\color{codeA}}
1685
+ \begin{lstlisting}
1686
+ vec[ N-1 ] = y;
1687
+ \end{lstlisting}
1688
+ \end{minipage}
1689
+ &
1690
+ \textit{waiting to exectue}
1691
+ \end{tabular}
1692
+ \end{center}
1693
+ \caption{Data sharing without mutex protection}
1694
+ \label{fig:nomutex}
1695
+ \end{figure}
1696
+
1697
+ We have created a possible race condition. The result in this case is that
1698
+ thread $B$ reads an invalid element from the vector, and thread $A$
1699
+ overwrites an already existing element, which is not what we wanted.
1700
+
1701
+ The solution is to only let one thread have access to the vector at a
1702
+ time. This is done with mutex objects (mutex stands for \textit{mutual
1703
+ exclusion}). The proper use of mutexes eliminates race conditions. To
1704
+ create a mutex object in \GLFW , you use the function
1705
+ \textbf{glfwCreateMutex}:
1706
+
1707
+ \begin{lstlisting}
1708
+ GLFWmutex glfwCreateMutex( void )
1709
+ \end{lstlisting}
1710
+
1711
+ \textbf{glfwCreateMutex} returns NULL if a mutex object could not be
1712
+ created, otherwise a mutex handle is returned. To destroy a mutex object
1713
+ that is no longer in use, call \textbf{glfwDestroyMutex}:
1714
+
1715
+ \begin{lstlisting}
1716
+ void glfwDestroyMutex( GLFWmutex mutex )
1717
+ \end{lstlisting}
1718
+
1719
+ Mutex objects by themselves do not contain any useful data. They act as a
1720
+ lock to any arbitrary data. Any thread can lock access to the data using
1721
+ the function \textbf{glfwLockMutex}:
1722
+
1723
+ \begin{lstlisting}
1724
+ void glfwLockMutex( GLFWmutex mutex )
1725
+ \end{lstlisting}
1726
+
1727
+ The argument \textit{mutex} is the mutex handle that was obtained when
1728
+ creating the mutex. \textbf{glfwLockMutex} will block the calling thread
1729
+ until the specified mutex is available (which will be immediately, if no
1730
+ other thread has locked it).
1731
+
1732
+ Once a mutex has been locked, no other thread is allowed to lock the
1733
+ mutex. Only one thread at a time can get access to the mutex, and only the
1734
+ thread that has locked the mutex may use or manipulate the data which the
1735
+ mutex protects. To unlock a mutex, the thread calls
1736
+ \textbf{glfwUnlockMutex}:
1737
+
1738
+ \begin{lstlisting}
1739
+ void glfwUnlockMutex( GLFWmutex mutex )
1740
+ \end{lstlisting}
1741
+
1742
+ As soon as \textbf{glfwUnlockMutex} has been called, other threads may
1743
+ lock it again.
1744
+
1745
+ Figure \ref{fig:withmutex} shows the scenario with the two threads
1746
+ trying to access the same vector, but this time they use a mutex object
1747
+ (\textit{vecmutex}).
1748
+
1749
+ \begin{figure}[p]
1750
+ \begin{center}
1751
+ \begin{tabular}{cc}
1752
+ \textbf{Thread A} & \textbf{Thread B}\\
1753
+ \begin{minipage}{7cm}
1754
+ \lstset{backgroundcolor=\color{codeA}}
1755
+ \vspace{0.5\baselineskip}
1756
+ \begin{lstlisting}
1757
+ glfwLockMutex( vecmutex );
1758
+ N ++;
1759
+ \end{lstlisting}
1760
+ \end{minipage}
1761
+ &
1762
+ \textit{waiting to exectue}
1763
+ \\
1764
+
1765
+ \textit{waiting to exectue}
1766
+ &
1767
+ \begin{minipage}{7cm}
1768
+ \vspace{0.5\baselineskip}
1769
+ \lstset{backgroundcolor=\color{codeB}}
1770
+ \begin{lstlisting}
1771
+ glfwLockMutex( vecmutex );
1772
+ \end{lstlisting}
1773
+ \end{minipage}
1774
+ \\
1775
+
1776
+ \begin{minipage}{7cm}
1777
+ \vspace{0.5\baselineskip}
1778
+ \lstset{backgroundcolor=\color{codeA}}
1779
+ \begin{lstlisting}
1780
+ vec[ N-1 ] = y;
1781
+ glfwUnlockMutex( vecmutex );
1782
+ \end{lstlisting}
1783
+ \end{minipage}
1784
+ &
1785
+ \textit{waiting to exectue}
1786
+ \\
1787
+
1788
+ \textit{waiting to exectue}
1789
+ &
1790
+ \begin{minipage}{7cm}
1791
+ \vspace{0.5\baselineskip}
1792
+ \lstset{backgroundcolor=\color{codeB}}
1793
+ \begin{lstlisting}
1794
+ x = vec[ N-1 ];
1795
+ N --;
1796
+ glfwUnlockMutex( vecmutex );
1797
+ \end{lstlisting}
1798
+ \end{minipage}
1799
+ \end{tabular}
1800
+ \end{center}
1801
+ \caption{Data sharing with mutex protection}
1802
+ \label{fig:withmutex}
1803
+ \end{figure}
1804
+
1805
+ In this example, thread $A$ successfully obtains a lock on the mutex and
1806
+ directly starts modifying the vector data. Next, thread $B$ \textit{tries}
1807
+ to get a lock on the mutex, but is placed on hold since thread $A$ has
1808
+ already locked the mutex. Thread $A$ is free to continue its work, and
1809
+ when it is done it unlocks the mutex. \textit{Now} thread $B$ locks the
1810
+ mutex and gains exclusive access to the vector data, performs its work,
1811
+ and finally unlocks the mutex.
1812
+
1813
+ The race condition has been avoided, and the code performs as expected.
1814
+
1815
+
1816
+ %-------------------------------------------------------------------------
1817
+ \section{Thread Synchronization Using Condition Variables}
1818
+ \label{par:condvar}
1819
+ Now you know how to create threads and how to safely exchange data between
1820
+ threads, but there is one important thing left to solve for multi threaded
1821
+ programs: conditional waits. Very often it is necessary for one thread to
1822
+ wait for a condition that will be satisfied by another thread.
1823
+
1824
+ For instance, a thread~$A$ may need to wait for both thread~$B$ and
1825
+ thread~$C$ to finish a certain task before it can continue. For starters,
1826
+ we can create a mutex protecting a variable holding the number of
1827
+ completed threads:
1828
+
1829
+ \begin{lstlisting}
1830
+ GLFWmutex mutex;
1831
+ int threadsdone;
1832
+ \end{lstlisting}
1833
+
1834
+ Now, thread~$B$ and $C$ will lock the mutex and increase the
1835
+ \textit{threadsdone} variable by one when they are done, and then unlock
1836
+ the mutex again. Thread~$A$ can lock the mutex and check if threadsdone
1837
+ is equal to 2.
1838
+
1839
+ If we assume that \textit{mutex} has been created successfully, the code
1840
+ for the three threads ($A$, $B$ and $C$) could be the following:
1841
+
1842
+ \begin{mysamepage}[8]
1843
+ Thread~$A$: Wait for both thread~$B$ and $C$ to finish.
1844
+ \lstset{backgroundcolor=\color{codeA}}
1845
+ \begin{lstlisting}
1846
+ do
1847
+ {
1848
+ glfwLockMutex( mutex );
1849
+ done = (threadsdone == 2);
1850
+ glfwUnlockMutex( mutex );
1851
+ }
1852
+ while( !done );
1853
+ \end{lstlisting}
1854
+ \end{mysamepage}
1855
+
1856
+ \begin{mysamepage}[4]
1857
+ Thread~$B$ and $C$: Tell thread~$A$ that I am done.
1858
+ \lstset{backgroundcolor=\color{codeB}}
1859
+ \begin{lstlisting}
1860
+ glfwLockMutex( mutex );
1861
+ threadsdone ++;
1862
+ glfwUnlockMutex( mutex );
1863
+ \end{lstlisting}
1864
+ \lstset{backgroundcolor=\color{code}}
1865
+ \end{mysamepage}
1866
+
1867
+ The problem is that when thread~$A$ discovers that thread~$B$ and $C$ are
1868
+ not done, it needs to check \textit{threadsdone} over and over again until
1869
+ \textit{threadsdone} is 2. We have created a busy waiting loop!
1870
+
1871
+ The method will work without a doubt, but thread~$A$ will consume a lot of
1872
+ CPU power doing nothing. What we need is a way for thread~$A$ to halt
1873
+ until thread~$B$ or $C$ tells it to re-evaluate the conditions again. This
1874
+ is exactly what condition variables do.
1875
+
1876
+ \GLFW\ supports three condition variable operations: wait, signal and
1877
+ broadcast. One or more threads may wait to be woken up on a condition, and
1878
+ one or more threads may signal or broadcast a condition. The difference
1879
+ between signal and broadcast is that broadcasting a condition wakes up all
1880
+ waiting threads (in an unspecified order, which is decided by task
1881
+ scheduling rules), while signaling a condition only wakes up one waiting
1882
+ thread (again, which one is unspecified).
1883
+
1884
+ An important property of condition variables, which separates them from
1885
+ other signaling objects such as events, is that only \textit{currently
1886
+ waiting} threads are affected by a condition. A condition is ``forgotten''
1887
+ as soon as it has been signaled or broadcasted. That is why a condition
1888
+ variable is always associated with a mutex, which protects additional
1889
+ condition information, such as the ``done'' variable construct described
1890
+ above.
1891
+
1892
+ This may all be confusing at first, but you will see that condition
1893
+ variables are both simple and powerful. They can be used to construct more
1894
+ abstract objects such as semaphores, events or gates (which is why \GLFW\
1895
+ does not support semaphores natively, for instance).
1896
+
1897
+ Before we go on by solving the busy waiting scenario, let us go through
1898
+ the \GLFW\ condition variable functions. Just like for mutexes, you can
1899
+ create and destroy condition variable objects. The functions for doing
1900
+ this are \textbf{glfwCreateCond} and \textbf{glfwDestroyCond}:
1901
+
1902
+ \begin{lstlisting}
1903
+ GLFWcond glfwCreateCond( void )
1904
+ \end{lstlisting}
1905
+
1906
+ \begin{lstlisting}
1907
+ void glfwDestroyCond( GLFWcond cond )
1908
+ \end{lstlisting}
1909
+
1910
+ \textbf{glfwCreateCond} returns NULL if a condition variable object could
1911
+ not be created, otherwise a condition variable handle is returned. To
1912
+ destroy a condition variable that is no longer in use, call
1913
+ \textbf{glfwDestroyCond}.
1914
+
1915
+ To wait for a condition variable, you use \textbf{glfwWaitCond}, which has
1916
+ the C syntax:
1917
+
1918
+ \begin{lstlisting}
1919
+ void glfwWaitCond( GLFWcond cond, GLFWmutex mutex, double timeout )
1920
+ \end{lstlisting}
1921
+
1922
+ When \textbf{glfwWaitCond} is called, the locked mutex specified by
1923
+ \textit{mutex} will be unlocked, and the thread will be placed in a wait
1924
+ state until it receives the condition \textit{cond}. As soon as the
1925
+ waiting thread is woken up, the mutex \textit{mutex} will be locked again.
1926
+ If \textit{timeout} is GLFW\_INFINITY, \textbf{glfwWaitCond} will wait
1927
+ until the condition \textit{cond} is received. If \textit{timemout} is a
1928
+ positive time (in seconds), \textbf{glfwWaitCond} will wait until the
1929
+ condition cond is received or the specified time has passed.
1930
+
1931
+ To signal or broadcast a condition variable, you use the functions
1932
+ \textbf{glfwSignalCond} and \textbf{glfwBroadcastCond}, respectively:
1933
+
1934
+ \begin{lstlisting}
1935
+ void glfwSignalCond( GLFWcond cond )
1936
+ \end{lstlisting}
1937
+
1938
+ \begin{lstlisting}
1939
+ void glfwBroadcastCond( GLFWcond cond )
1940
+ \end{lstlisting}
1941
+
1942
+ \textbf{glfwSignalCond} will wake up one threads that is waiting for the
1943
+ condition \textit{cond}. \textbf{glfwBroadcastCond} will wake up all
1944
+ threads that are waiting for the condition cond.
1945
+
1946
+ Now that we have the tools, let us see what we can do to solve the busy
1947
+ waiting situation. First, we add a condition variable to our data set:
1948
+
1949
+ \begin{lstlisting}
1950
+ GLFWcond cond;
1951
+ GLFWmutex mutex;
1952
+ int threadsdone;
1953
+ \end{lstlisting}
1954
+
1955
+ If we assume that \textit{mutex} and \textit{cond} have been created
1956
+ successfully, the code for the three threads ($A$, $B$ and $C$) could be
1957
+ the following:
1958
+
1959
+ \begin{mysamepage}[12]
1960
+ Thread~$A$: Wait for both thread~$B$ and $C$ to finish.
1961
+ \lstset{backgroundcolor=\color{codeA}}
1962
+ \begin{lstlisting}
1963
+ glfwLockMutex( mutex );
1964
+ do
1965
+ {
1966
+ done = (threadsdone == 2);
1967
+ if( !done )
1968
+ {
1969
+ glfwWaitCond( cond, mutex, GLFW_INFINITY );
1970
+ }
1971
+ }
1972
+ while( !done );
1973
+ glfwUnlockMutex( mutex );
1974
+ \end{lstlisting}
1975
+ \end{mysamepage}
1976
+
1977
+ \begin{mysamepage}[6]
1978
+ Thread~$B$ and $C$: Tell thread~$A$ that I am done.
1979
+ \lstset{backgroundcolor=\color{codeB}}
1980
+ \begin{lstlisting}
1981
+ glfwLockMutex( mutex );
1982
+ threadsdone ++;
1983
+ glfwUnlockMutex( mutex );
1984
+ glfwSignalCond( cond );
1985
+ \end{lstlisting}
1986
+ \lstset{backgroundcolor=\color{code}}
1987
+ \end{mysamepage}
1988
+
1989
+ With the addition of a condition variable, the busy waiting loop turned
1990
+ into a nice condition waiting loop, and thread~$A$ no longer wastes any
1991
+ CPU time. Also note that the mutex locking and unlocking is moved outside
1992
+ of the waiting loop. This is because \textbf{glfwWaitCond} effectively
1993
+ performs the necessary mutex locking and unlocking for us.
1994
+
1995
+
1996
+ %-------------------------------------------------------------------------
1997
+ \section{Calling GLFW Functions From Multiple Threads}
1998
+ The current release of \GLFW\ is not 100\% thread safe. In other words,
1999
+ most \GLFW\ functions may cause conflicts and undefined behaviour if they
2000
+ are called from different threads.
2001
+
2002
+ To avoid conflicts, only the following \GLFW\ API functions should be
2003
+ regarded as thread safe (i.e. they can be called from any thread at any
2004
+ time):
2005
+
2006
+ \begin{enumerate}
2007
+ \item All functions that deal with threads, mutexes and condition
2008
+ variables (e.g. \textbf{glfwCreateThread}, \textbf{glfwLockMutex}
2009
+ etc).
2010
+ \item The timing function \textbf{glfwSleep}.
2011
+ \end{enumerate}
2012
+
2013
+ All other \GLFW\ API function calls should be done from a single thread.
2014
+ This also makes for better future compatibility, since future versions of
2015
+ \GLFW\ may implement per thread window contexts (much in the same way as
2016
+ \OpenGL\ has per thread rendering contexts), for instance.
2017
+
2018
+
2019
+ %-------------------------------------------------------------------------
2020
+ % Index
2021
+ %-------------------------------------------------------------------------
2022
+ % ...
2023
+
2024
+ \end{document}