1# gl_generator
2
3[![Version](https://img.shields.io/crates/v/gl_generator.svg)](https://crates.io/crates/gl_generator)
4[![License](https://img.shields.io/crates/l/gl_generator.svg)](https://github.com/brendanzab/gl-rs/blob/master/LICENSE)
5[![Downloads](https://img.shields.io/crates/d/gl_generator.svg)](https://crates.io/crates/gl_generator)
6
7Code generators for creating bindings to the Khronos OpenGL APIs.
8
9## Usage
10
11If you need a specific version of OpenGL, or you need a different API
12(OpenGL ES, EGL, WGL, GLX), or if you need certain extensions, you should use
13the `gl_generator` plugin instead.
14
15See [gfx_gl](https://github.com/gfx-rs/gfx_gl) for an example of using a
16custom gfx-rs loader for a project.
17
18Add this to your `Cargo.toml`:
19
20```toml
21[build-dependencies]
22gl_generator = "0.5.0"
23```
24
25Under the `[package]` section, add:
26
27```toml
28build = "build.rs"
29```
30
31Create a `build.rs` to pull your specific version/API:
32
33```rust
34extern crate gl_generator;
35
36use gl_generator::{Registry, Api, Profile, Fallbacks, GlobalGenerator};
37use std::env;
38use std::fs::File;
39use std::path::Path;
40
41fn main() {
42    let dest = env::var("OUT_DIR").unwrap();
43    let mut file = File::create(&Path::new(&dest).join("bindings.rs")).unwrap();
44
45    Registry::new(Api::Gl, (4, 5), Profile::Core, Fallbacks::All, [])
46        .write_bindings(GlobalGenerator, &mut file)
47        .unwrap();
48}
49```
50
51Then use it like this:
52
53```rust
54mod gl {
55    include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
56}
57
58/// Simple loading example
59fn main() {
60    let window = ...;
61
62    // Assuming `window` is GLFW: initialize, and made current
63    gl::load_with(|s| window.get_proc_address(s));
64}
65```
66
67The `build.rs` file will generate all the OpenGL functions in a file named,
68`bindings.rs` plus all enumerations, and all types in the `types` submodule.
69
70## Generator types
71
72### Global generator
73
74The global generator is the one used by default by the `gl` crate. See above
75for more details.
76
77### Struct generator
78
79The struct generator is a cleaner alternative to the global generator.
80
81The main difference is that you must call `gl::Gl::load_with` instead of
82`gl::load_with`, and this functions returns a struct of type `Gl`. The OpenGL
83functions are not static functions but member functions in this `Gl` struct.
84This is important when the GL functions are associated with the current
85context, as is true on Windows.
86
87The enumerations and types are still static and available in a similar way as
88in the global generator.
89
90### Static generator
91
92The static generator generates plain old bindings. You don't need to load the
93functions.
94
95This generator should only be used only if the platform you are compiling for
96is guaranteed to support the requested API. Otherwise you will get a
97compilation error.
98For example, you can use it for WGL and OpenGL 1.1 on Windows or GLX and
99OpenGL 1.3 on Linux, because Windows and Linux are guaranteed to provide
100implementations for these APIs.
101
102You will need to manually provide the linkage. For example to use WGL or
103OpenGL 1.1 on Windows, you will need to add
104`#[link="OpenGL32.lib"] extern {}` somewhere in your code.
105
106### Custom Generators
107
108The `gl_generator` can be extended with custom generators. This is a niche
109feature useful only in very rare cases. To create a custom generator, implement
110the `gl_generator::Generator` trait. See the source of the
111`gl_generator::generators` module for examples.
112
113Various utility functions are provided in the `generators` module, but the api
114is unstable, so it has been placed behind a feature flag. In access these
115functions, you will need to add the `"unstable_generator_utils"` feature to
116your `Cargo.toml`:
117
118```toml
119[build-dependencies.gl_generator]
120version = "0.4.2"
121features = ["unstable_generator_utils"]
122```
123
124## Extra features
125
126The global and struct generators will attempt to use fallbacks functions when
127they are available. For example, if `glGenFramebuffers` cannot be loaded it will
128also attempt to load `glGenFramebuffersEXT` as a fallback.
129
130## Changelog
131
132### v0.5.0
133
134- Rename `Ns` to `API`, and expose at the top level
135- Remove the need for clients to depend on the `khronos_api` crate by
136  determining the XML source based on the requested `API`
137- Use a `(u8, u8)` instead of a string for the target version number
138- Use a `Profile` enum instead of a string for the profile
139- Remove unused fields from `Registry`
140- Accept types satisfying `AsRef<[&str]>` for extension lists
141- Separate parsing and generation stages in API
142- Hide `registry::{Feature, Filter, Require, Remove, Extension}` types from the
143  public API
144- Move `registry::{Fallbacks, Api, Profile}` types to top level module
145- Remove `GlxOpcode::type` field
146- Make `ty` fields on `Enum` and `Binding` take `Cow<'static, str>`s to reduce
147  allocations
148
149### v0.4.2
150
151- Update crate metadata
152
153### v0.4.1
154
155- Upgrade `khronos_api` to v1.0.0
156
157### v0.4.0
158
159- Upgrade `xml-rs` to v0.2.2
160- Use `raw::c_void` for `GLvoid`
161- Remove `registry::{Group, EnumNs, CmdNs}`
162- Remove `groups` field from `registry::Registry`
163- Remove `is_safe` field from `registry::Cmd`
164- Remove `comment` field from `registry::{Require, Remove, GlxOpcode}`
165- Downgrade `khronos_api` to be a dev-dependency
166