-
Notifications
You must be signed in to change notification settings - Fork 70
/
Copy path_3_3_shaders_class.rs
123 lines (104 loc) · 4.61 KB
/
_3_3_shaders_class.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#![allow(non_upper_case_globals)]
extern crate glfw;
use self::glfw::{Context, Key, Action};
extern crate gl;
use self::gl::types::*;
use std::sync::mpsc::Receiver;
use std::ptr;
use std::mem;
use std::os::raw::c_void;
use shader::Shader;
// settings
const SCR_WIDTH: u32 = 800;
const SCR_HEIGHT: u32 = 600;
#[allow(non_snake_case)]
pub fn main_1_3_3() {
// glfw: initialize and configure
// ------------------------------
let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();
glfw.window_hint(glfw::WindowHint::ContextVersion(3, 3));
glfw.window_hint(glfw::WindowHint::OpenGlProfile(glfw::OpenGlProfileHint::Core));
#[cfg(target_os = "macos")]
glfw.window_hint(glfw::WindowHint::OpenGlForwardCompat(true));
// glfw window creation
// --------------------
let (mut window, events) = glfw.create_window(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", glfw::WindowMode::Windowed)
.expect("Failed to create GLFW window");
window.make_current();
window.set_key_polling(true);
window.set_framebuffer_size_polling(true);
// gl: load all OpenGL function pointers
// ---------------------------------------
gl::load_with(|symbol| window.get_proc_address(symbol) as *const _);
let (ourShader, VAO) = unsafe {
let ourShader = Shader::new(
"src/_1_getting_started/shaders/3.3.shader.vs",
"src/_1_getting_started/shaders/3.3.shader.fs"
); // you can name your shader files however you like)
// set up vertex data (and buffer(s)) and configure vertex attributes
// ------------------------------------------------------------------
// HINT: type annotation is crucial since default for float literals is f64
let vertices: [f32; 18] = [
// positions // colors
0.5, -0.5, 0.0, 1.0, 0.0, 0.0, // bottom right
-0.5, -0.5, 0.0, 0.0, 1.0, 0.0, // bottom left
0.0, 0.5, 0.0, 0.0, 0.0, 1.0 // top
];
let (mut VBO, mut VAO) = (0, 0);
gl::GenVertexArrays(1, &mut VAO);
gl::GenBuffers(1, &mut VBO);
// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
gl::BindVertexArray(VAO);
gl::BindBuffer(gl::ARRAY_BUFFER, VBO);
gl::BufferData(gl::ARRAY_BUFFER,
(vertices.len() * mem::size_of::<GLfloat>()) as GLsizeiptr,
&vertices[0] as *const f32 as *const c_void,
gl::STATIC_DRAW);
let stride = 6 * mem::size_of::<GLfloat>() as GLsizei;
// position attribute
gl::VertexAttribPointer(0, 3, gl::FLOAT, gl::FALSE, stride, ptr::null());
gl::EnableVertexAttribArray(0);
// color attribute
gl::VertexAttribPointer(1, 3, gl::FLOAT, gl::FALSE, stride, (3 * mem::size_of::<GLfloat>()) as *const c_void);
gl::EnableVertexAttribArray(1);
// You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
// VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
// gl::BindVertexArray(0);
(ourShader, VAO)
};
// render loop
// -----------
while !window.should_close() {
// events
// -----
process_events(&mut window, &events);
// render
// ------
unsafe {
gl::ClearColor(0.2, 0.3, 0.3, 1.0);
gl::Clear(gl::COLOR_BUFFER_BIT);
// render the triangle
ourShader.useProgram();
gl::BindVertexArray(VAO);
gl::DrawArrays(gl::TRIANGLES, 0, 3);
}
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
// -------------------------------------------------------------------------------
window.swap_buffers();
glfw.poll_events();
}
}
// NOTE: not the same version as in common.rs!
fn process_events(window: &mut glfw::Window, events: &Receiver<(f64, glfw::WindowEvent)>) {
for (_, event) in glfw::flush_messages(events) {
match event {
glfw::WindowEvent::FramebufferSize(width, height) => {
// make sure the viewport matches the new window dimensions; note that width and
// height will be significantly larger than specified on retina displays.
unsafe { gl::Viewport(0, 0, width, height) }
}
glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => window.set_should_close(true),
_ => {}
}
}
}