Skip to content

Commit b4e902b

Browse files
committed
more
1 parent 498ee7f commit b4e902b

3 files changed

Lines changed: 83 additions & 15 deletions

File tree

book-src/basics/001-drawing-a-triangle.md

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@ to make it the active VAO. This is a _context wide_ effect, so now all GL
9797
functions in our GL context will do whatever they do with this VAO as the VAO to
9898
work with.
9999

100+
As a note: you can also bind the value 0 at any time, which clears the vertex
101+
array binding. This might sound a little silly, but it can help spot bugs in
102+
some situations. If you have no VAO bound when you try to call VAO affected
103+
functions it'll generate an error, which usually means that you forgot to bind
104+
the VAO that you really did want to affect.
105+
100106
### Generate A Vertex Buffer Object
101107

102108
To actually get some bytes of data to the video card we need a [Vertex Buffer
@@ -119,14 +125,76 @@ unsafe {
119125
}
120126
```
121127

122-
Now that we have a buffer, we can bind it to the binding target that we want. [`glBindBuffer`](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glBindBuffer.xhtml) takes a target name and a buffer. As you can see on that page, there's a whole lot of options, but for now we just want `GL_ARRAY_BUFFER`.
128+
Now that we have a buffer, we can bind it to the binding target that we want.
129+
[`glBindBuffer`](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glBindBuffer.xhtml)
130+
takes a target name and a buffer. As you can see on that page, there's a whole
131+
lot of options, but for now we just want to use the `GL_ARRAY_BUFFER` target.
123132

124133
```rust
125134
unsafe {
126135
glBindBuffer(GL_ARRAY_BUFFER, vbo);
127136
}
128137
```
129138

139+
And, similar to the VAO's binding process, now that our vertex buffer object is
140+
bound to the the `GL_ARRAY_BUFFER` target, all commands using that target will
141+
operate on the buffer that we just made.
142+
143+
(Is this whole binding thing a dumb way to design an API? Yeah, it is. Oh well.)
144+
145+
Now that we have a buffer bound as the `GL_ARRAY_BUFFER`, we can finally use [`glBufferData`](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glBufferData.xhtml) to actually send over some data bytes. We have to specify the binding target we want to buffer to, the `isize` of the number of bytes we want to buffer, the const pointer to the start of the data we're buffering, and the usage hint.
146+
147+
Most of that is self explanatory, except the usage hint. Basically there's
148+
memory that's faster or slower for the GPU to use or the CPU to use. If we hint
149+
to the GPU how we intend to use the data and how often we intend to update it
150+
then it has a chance to make a smarter choice of where to put the data. You can
151+
see all the options on the `glBufferData` spec page. For our first demo we want
152+
`GL_STATIC_DRAW`, since we'll just be sending the data once, and then GL will
153+
draw with it many times.
154+
155+
But what data do we send?
156+
157+
#### Demo Vertex Data
158+
159+
We're going to be sending this data:
160+
161+
```rust
162+
type Vertex = [f32; 3];
163+
const VERTICES: [Vertex; 3] =
164+
[[-0.5, -0.5, 0.0], [0.5, -0.5, 0.0], [0.0, 0.5, 0.0]];
165+
```
166+
167+
It describes a triangle in Normalized Device Context (NDC) coordinates. Each
168+
vertex is an [X, Y, Z] triple, and we have three vertices.
169+
170+
We can also use
171+
[`size_of_val`](https://doc.rust-lang.org/core/mem/fn.size_of_val.html) to get
172+
the byte count, and
173+
[`as_ptr`](https://doc.rust-lang.org/std/primitive.slice.html#method.as_ptr)
174+
followed by
175+
[`cast`](https://doc.rust-lang.org/std/primitive.pointer.html#method.cast) to
176+
get a pointer of the right type. In this case, GL wants a "void pointer", which
177+
isn't a type that exists in Rust, but it's what C calls a "pointer to anything".
178+
Since the buffer function need to be able to accept anything you want to buffer,
179+
it takes a void pointer.
180+
181+
```rust
182+
unsafe {
183+
glBufferData(
184+
GL_ARRAY_BUFFER,
185+
size_of_val(&VERTICES) as isize,
186+
VERTICES.as_ptr().cast(),
187+
GL_STATIC_DRAW,
188+
);
189+
}
190+
```
191+
192+
193+
194+
## Using `glGetError`
195+
196+
TODO
197+
130198
## Vsync
131199

132200
Finally, let's turn on

examples/001-triangle-arrays1.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,16 @@ fn main() {
7979
GL_STATIC_DRAW,
8080
);
8181

82+
glVertexAttribPointer(
83+
0,
84+
3,
85+
GL_FLOAT,
86+
GL_FALSE,
87+
size_of::<Vertex>().try_into().unwrap(),
88+
0 as *const _,
89+
);
90+
glEnableVertexAttribArray(0);
91+
8292
let vertex_shader = glCreateShader(GL_VERTEX_SHADER);
8393
assert_ne!(vertex_shader, 0);
8494
glShaderSource(
@@ -148,16 +158,6 @@ fn main() {
148158
glDeleteShader(vertex_shader);
149159
glDeleteShader(fragment_shader);
150160

151-
glVertexAttribPointer(
152-
0,
153-
3,
154-
GL_FLOAT,
155-
GL_FALSE,
156-
size_of::<Vertex>().try_into().unwrap(),
157-
0 as *const _,
158-
);
159-
glEnableVertexAttribArray(0);
160-
161161
glUseProgram(shader_program);
162162
}
163163

examples/002-triangle-arrays2.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,6 @@ fn main() {
7777
GL_STATIC_DRAW,
7878
);
7979

80-
let shader_program =
81-
ShaderProgram::from_vert_frag(VERT_SHADER, FRAG_SHADER).unwrap();
82-
shader_program.use_program();
83-
8480
unsafe {
8581
glVertexAttribPointer(
8682
0,
@@ -93,6 +89,10 @@ fn main() {
9389
glEnableVertexAttribArray(0);
9490
}
9591

92+
let shader_program =
93+
ShaderProgram::from_vert_frag(VERT_SHADER, FRAG_SHADER).unwrap();
94+
shader_program.use_program();
95+
9696
'main_loop: loop {
9797
// handle events this frame
9898
while let Some(event) = sdl.poll_events().and_then(Result::ok) {

0 commit comments

Comments
 (0)