root/trunk/docs/gl.html

Revision 257, 14.3 kB (checked in by aldacron, 2 years ago)

[Docs]
* added documentation for extension loading
* tweaked the style sheet a bit

  • Property svn:mime-type set to text/html
  • Property svn:mim-type set to text/html
Line 
1 <html lang="en">
2 <head>
3     <title>DerelictGL</title>
4     <link rel="stylesheet" type="text/css" href="styles.css">
5 </head>
6 <body>
7 <hr>
8 <hr>
9 <h2 align="center">DerelictGL</h2>
10 <hr>
11 <hr>
12 <h3>Introduction</h3>
13 DerelictGL is a D binding to the <a href="http://www.opengl.org/">OpenGL</a>
14 library. Currently, DerelictGL exposes all core OpenGL functions up to version 2.1. However,
15 in order to use features available in OpenGL versions greater than 1.1, you must load them
16 separately after creating an OpenGL context. See below.
17
18 <h3>Using</h3>
19 <ol>
20 <li>Always make sure the DerelictGL source modules are available on your import
21 path.</li>
22 <li>In modules that make use of DerelictGL, you will need to import the derelict.opengl.gl
23 module.</li>
24 <li>Before calling any OpenGL functions, you need to make a call to <tt>DerelictGL.load()</tt>.
25 This will load the shared library and all core OpenGL 1.0 and 1.1 functions.</li>
26 </ol>
27
28 <p>
29 The following is a complete program that loads DerelictGL:
30 </p>
31
32 <pre>
33 import derelict.opengl.gl;
34
35 void main()
36 {
37     DerelictGL.load();
38
39     // now you can call OpenGL functions
40 }
41 </pre>
42
43 <div class="note">Return values and parameters of type <tt>GLubyte*</tt>, when
44 intended to represent a string, have been declared in DerelictGL as <tt>char*</tt>
45 instead.</div>
46
47 <p>
48 As with other Derelict packages, DerelictGL will throw an exception if an error
49 occurs while loading the shared library. For more information on Derelict
50 exceptions, see the documentation for
51 <a href="loading.html">Loading/Unloading Shared Libraries</a>.
52 </p><p>
53 Finally, the method <tt>DerelictGL.unload()</tt> is provided for convenience. In normal
54 practice you do not need to call this function, as Derelict will unload the library
55 automatically when the app exits. You generally should only use this function if
56 you need to unload DerelictGL while the application is running.
57 </p>
58
59 <h3>Loading OpenGL Versions 1.2 and Later</h3>
60
61 OpenGL poses a few issues beyond other libraries that Derelict binds to and
62 therefore requires special-case handling. One problem is the variety of graphics
63 cards and OpenGL versions available on end user systems. If you are developing
64 an OpenGL application for general public consumption, there is no way to guarantee
65 which version of the API will be available on any user's system until the
66 application is actually run on that system.
67 </p><p>
68 Another issue is presented by Windows operating systems. The default opengl32.dll
69 on Windows systems prior to Vista only provides exports for OpenGL 1.1. It has
70 not been updated since it was first realeased on Windows 95. Furthermore, this
71 DLL is a (rather poor) software implementation. Vista ships with the software
72 implementation, but also includes an OpenGL DLL that supports up to core OpenGL
73 1.4 and is implemented on top of Direct3D. This DLL provides hardware acceleration,
74 but all of the calls first go through a translation layer to convert them to D3D
75 calls. The system can load the implementation provided by the graphics card
76 driver, but there is no way to know which implementation the application is
77 actually using, or which version a graphics card driver supports, until the
78 context is created.
79 </p><p>
80 Derelict's dynamic loading mechanism helps to work around the first issue. If not
81 for the Windows problem, loading OpenGL version 1.2 and later could be accomplished
82 via the single call to <span class="bold">DerelictGL.load</span>. However, in
83 order to maintain a consistent interface across all platforms, DerelictGL includes
84 some additional methods and constants to load and manage different OpenGL versions.
85 </p><p>
86 <tt>GLVersion</tt><br />
87 This enum defines all OpenGL versions currently loadable by Derelict. At the
88 time of this writing, these are the values GLVersion defines:
89 </p>
90 <ul>
91 <li>GLVersion.VersionNone</li>
92 <li>GLVersion.Version11</li>
93 <li>GLVersion.Version12</li>
94 <li>GLVersion.Version13</li>
95 <li>GLVersion.Version14</li>
96 <li>GLVersion.Version15</li>
97 <li>GLVersion.Version20</li>
98 <li>GLVersion.Version21</li>
99 </ul>
100
101 <p>
102 <tt>void DerelictGL.loadVersions(GLVersion minVersion)</tt><br />
103 This method will attempt to load a specific verision of OpenGL. If any version
104 of OpenGL up to and including the version requested fails to load successfully,
105 then this method throws a <span class="bold">SharedLibProcLoadException</span>.
106 </p>
107 <p>
108 Before attempting to load any functions, two checks are made. The first check is
109 to determine if an OpenGL context has been made current. If not, this method
110 will throw an <span class="bold">Exception/span>. The method next determines
111 if a check has been made internally for the latest available version supported
112 by the driver. If not, that check is made. Only then are the functions loaded.
113 </p><p>
114 When this function returns successfully, a call to
115 <span class="bold">DerelictGL.availableVersion</span> will return either a value
116 greater than or equal to the version you requested to load. If an exception is
117 thrown, you can still check the highest version loaded, which will be lower than
118 that which you requested.
119 </p>
120
121 <p>
122 <tt>GLVersion DerelictGL.availableVersion()</tt><br />
123 When this method is called, it first checks to determine if the available
124 version has already been set. If not, it will query the driver for the highest
125 version supported and <span class="bold">then will attempt to load each supported
126 version</span>. A successful load will result in a return value that indicates
127 the highest loaded version. A failure will result in an
128 <span class="bold">Exception</span> if no context is current, or a
129 <span class="bold">SharedLibProcLoadException</span> if any function failed to
130 load. Successive calls will always return the latest loaded version as long
131 as a context is valid.
132 </p>
133
134 <p>
135 <tt>char[] DerelictGL.versionString(GLVersion glv)</tt><br />
136 Returns the string form of the given version. The format of the string is "Version X.X".
137 </p>
138
139 <p>
140 <tt>bool DerelictGL.hasValidContext()</tt><br />
141 Returns true if a context has been made current. This is used internally before
142 attempting any loads that require an active context, but is also publicly
143 available. You may find this useful if you have an application that manages
144 multiple OpenGL contexts.
145 </p>
146
147 <p>
148 <span class="bold">Examples</span><br />
149 Generally, if you want to load a specific version of OpenGL, you should use
150 <span class="bold">DerelictGL.loadVersions</span>. Otherwise, you can use
151 <span class="bold">DerelictGL.availableVersion</span> to load the latest version
152 available. Following are examples of both:
153 </p>
154 <pre>
155 // Example 1: Requesting a specific version.
156 import derelict.opengl.gl;
157 import derelict.util.exception;
158
159 void main()
160 {
161     // load OpenGL 1.1
162     DerelictGL.load();
163
164     // attempt to load every version up to OpenGL 1.5
165     try
166     {
167         DerelictGL.loadVersions(GLVersion.Version15);
168     }
169     catch(SharedLibProcLoadException slple)
170     {
171         // Here, you can check which is the highest version that actually loaded.
172
173         /* Do Something Here */
174     }
175 }
176 </pre>
177
178 <pre>
179 // Example 2: Loading the highest available version.
180 import derelict.opengl.gl;
181 import derelict.util.exception;
182
183 void main()
184 {
185     // load OpenGL 1.1
186     DerelictGL.load();
187
188     // attempt to load the higest GL version supported by the driver
189     GLVersion glv;
190     try
191     {
192         glv = DerelictGL.getAvailableVersion();
193     }
194     catch(SharedLibProcLoadException slple)
195     {
196         // You might want to abort here if you are worried about a corrupt
197         // shared library. Otherwise, you'll want to determine what was
198         // actually loaded.
199         glv = DerelictGL.getAvailableVersion();
200     }
201
202     switch(glv)
203     {
204         ...
205     }
206
207 }
208 </pre>
209
210 <div class="note">
211 It should be noted that Derelict's <a href="selective.html">selective loading
212 mechanism</a> may be used when loading versions later than 1.2. However, it is
213 not recommended you do so unless there is a very compelling
214 reason.
215 </div>
216
217 <h3>Loading OpenGL Extensions</h3>
218
219 As an added convenience, DerelictGL includes support for the easy detection and
220 loading of several OpenGL extensions. In the <tt>derelict.opengl.extension</tt>
221 package are several subpackages. Each subpackage contains loaders for a group
222 of extensions. For example, loaders for <span class='bold'>GL_EXT</span>
223 extensions are found in <tt>derelict.opengl.extension.ext</tt>, loaders for
224 <span class='bold'>GL_ARB</span> extensions in <tt>derelict.opengl.extension.arb</tt>,
225 loaders for <span class='bold'GL_NV extensions in</span>
226 <tt>derelict.opengl.extension.nv</tt>, and so on.
227
228 <h4>Naming Conventions</h4>
229 It's important to understand the difference between extension
230 <span class='emph'>names</span> and <span class='emph'>name strings</span>.
231 A name string is an extension name prefixed with <span class='bold'>GL_</span>
232 (for core OpenGL extensions), or a platform-specific prefix (such as
233 <span class='bold'>WGL_</span> on Windows and <span class='bold'>GLX_</span> on
234 Linux) for platform-specific extensions. For example, <span class='bold'>ARB_shadow
235 </span> is an extension name and <span class='bold'>GL_ARB_shadow</span> is a
236 name string.
237 <p>
238 In DerelictGL, each supported extension has its own loader. The name of the
239 loader's module is identical to the extension name, minus the prefix. The prefix
240 is the name of the package in which the module can be found. For example, the
241 loader for the extension <span class='bold'>ARB_shadow_objects</span> resides in
242 the module <tt>derelict.opengl.extension.arb.shadow_objects</tt></span>.
243 </p>
244 <div class='note'>
245 The one exception to this rule is the extension
246 <span class='bold'>EXT_422_pixels</span>. In D, module names cannot begin with
247 a number. For this extension, the module is
248 <tt>derelict.opengl.extension.ext.four22_pixels</tt>. However, the name of the
249 loader for this extension follows the convention outlined below.
250 </div>
251
252 <p>
253 The name of each loader is a modified form of the extension name. Essentially,
254 each lowercase word separated by an underscore is capitalized and the underscores
255 removed, resulting in a camel-case name. Here are some examples:
256 </p>
257 <ul>
258 <li>ARB_shadow => ARBShadow</li>
259 <li>NV_float_buffer => NVFloatBuffer</li>
260 <li>EXT_bgra => EXTBgra</li>
261 <li>EXT_422_pixels =>EXT422Pixels</li>
262 <li>ATI_texture_compression_3dc => ATITextureCompression3dc</li>
263 </ul>
264 <p>
265 Take special notice of EXTBgra. It's tempting to write EXTBGRA instead, but in any
266 case where acronyms are part of an extension name, the name of the loader
267 will only capitalize the first letter of the acronym.
268 </p>
269
270 <h4>Loading Extensions</h4>
271
272 On some operating systems, it may be possible to load extensions without first
273 creating an OpenGL context. Unfortunately, on Windows, this is not the case.
274 As such, in order to maintain a consistent interface DerelictGL requires that
275 a valid OpenGL context exist before extensions can be loaded. Any attempt to
276 load extensions when no context has been created will cause an exception to
277 be thrown.
278
279 <p>
280 Once DerelictGL has been loaded and a context created, you can load all extensions
281 used by your application with one method call: <tt>DerelictGL.loadExtensions</tt>.
282 Extensions not used by your application will not be loaded. Internally, DerelictGL
283 uses module constructors to track which extensions need to be loaded. So all you
284 need do is to import the extension loader modules you intend you use. There is
285 no requirement that you import them in the same module in which you load them --
286 you can import them anywhere in your application:
287 </p>
288 <pre>
289 // render.d
290 module myapp.render;
291
292 import derelict.opengl.extension.arb.point_sprite;
293 import derelict.opengl.extension.nv.texture_rectangle;
294
295 ...
296
297 // init.d
298 module myapp.init
299
300 void loadOpenGL()
301 {
302     // load DerelictGL
303     DerelictGL.load();
304    
305     // create the OpenGL context here (via SDL, Win32, or some other API)
306     ...
307    
308     // load all of the extensions you use (in this case ARB_point_sprite and NV_texture_rectangle)
309     DerelictGL.loadExtensions();
310 }
311 </pre>
312 <p>
313 This is a fine compromise between the two techniques often used in the C world:
314 loading each extension individually, or using a third-party library that loads
315 all available extensions.
316 </p><p>
317 The <tt>load</tt> method of each extension loader is publicly exposed, so you
318 can call it directly if you prefer. It's much simpler, however, to use the
319 <tt>loadExtensions</tt> method of DerelictGL instead.
320 </p>
321
322 <h4>Using Extensions</h4>
323
324 Because all extensions used by the application are loaded at once, and because
325 failure to load an extension rarely indicates that an application should terminate,
326 no exceptions are thrown when an extension is not present or fails to load. It
327 would have been possible to use Derelict's selective loading mechanism with
328 extension loading, but the decision was made not to do so simply because it is
329 not an exceptional circumstance for an extension to be unavailable on a user's
330 machine. In fact, it is often expected that some extensions will not be present.
331 Therefore, before attempting to use an extension it is important to check
332 whether or not the extension is available.
333 <p>
334 Alternate code paths are the norm in OpenGL programming. Typically, developers
335 determine a mimimal OpenGL version and/or extension set to support. If the minimum
336 is not available on the user's machine, the application aborts. Many OpenGL
337 applications also support more advanced features if they are available. For example,
338 some advanced lighting technniques can be implemented with GLSL shaders, but
339 when GLSL is unavailable the application can fall back to a different technique
340 using the fixed-function pipeline for a degraded effect. Some applications may
341 provide for three or four different ways of achieving a single effect.
342 </p><p>
343 With this in mind, each extension loader in Derelict exposes the following
344 method: <tt>bool isEnabled()</tt>. You can call this method to determine if
345 an extension is available and take appropriate action if it is not. Here is
346 an example:
347 </p>
348 <pre>
349 import derelict.extension.arb.vertex_shader;
350
351 void doSomethingWithVertexShaderExtension
352 {
353     if(ARBVertexShader.isEnabled())
354     {
355         // use extension here
356     }
357     else
358     {
359         // use fallback, exit program, or whatever you need to do
360     }
361 }
362 </pre>
363
364
365 <h3>Dependencies</h3>
366 <a href="util.html">DerelictUtil</a>
367
368 </body>
369 </html>
Note: See TracBrowser for help on using the browser.