139 lines
4.1 KiB
Rust
139 lines
4.1 KiB
Rust
extern crate gl;
|
|
extern crate sdl2;
|
|
|
|
pub mod render_gl;
|
|
|
|
fn main() {
|
|
let sdl = sdl2::init().unwrap();
|
|
let video_subsystem = sdl.video().unwrap();
|
|
|
|
let gl_attr = video_subsystem.gl_attr();
|
|
|
|
gl_attr.set_context_profile(sdl2::video::GLProfile::Core);
|
|
gl_attr.set_context_version(4, 1);
|
|
|
|
let window = video_subsystem
|
|
.window("Game", 900, 700)
|
|
.opengl()
|
|
.resizable()
|
|
.build()
|
|
.unwrap();
|
|
|
|
let _gl_context = window.gl_create_context().unwrap();
|
|
let gl = gl::Gl::load_with(|s| {
|
|
video_subsystem.gl_get_proc_address(s) as *const std::os::raw::c_void
|
|
});
|
|
|
|
// set up shader program
|
|
|
|
use std::ffi::CString;
|
|
let vert_shader = render_gl::Shader::from_vert_source(
|
|
&gl,
|
|
&CString::new(include_str!("triangle.vert")).unwrap(),
|
|
).unwrap();
|
|
|
|
let frag_shader = render_gl::Shader::from_frag_source(
|
|
&gl,
|
|
&CString::new(include_str!("triangle.frag")).unwrap(),
|
|
).unwrap();
|
|
|
|
let shader_program =
|
|
render_gl::Program::from_shaders(&gl, &[vert_shader, frag_shader]).unwrap();
|
|
|
|
// set up vertex buffer object
|
|
|
|
let vertices: Vec<f32> = vec![
|
|
// 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: gl::types::GLuint = 0;
|
|
unsafe {
|
|
gl.GenBuffers(1, &mut vbo);
|
|
}
|
|
|
|
unsafe {
|
|
gl.BindBuffer(gl::ARRAY_BUFFER, vbo);
|
|
gl.BufferData(
|
|
gl::ARRAY_BUFFER, // target
|
|
(vertices.len() * std::mem::size_of::<f32>()) as gl::types::GLsizeiptr, // size of data in bytes
|
|
vertices.as_ptr() as *const gl::types::GLvoid, // pointer to data
|
|
gl::STATIC_DRAW, // usage
|
|
);
|
|
gl.BindBuffer(gl::ARRAY_BUFFER, 0);
|
|
}
|
|
|
|
// set up vertex array object
|
|
|
|
let mut vao: gl::types::GLuint = 0;
|
|
unsafe {
|
|
gl.GenVertexArrays(1, &mut vao);
|
|
}
|
|
|
|
unsafe {
|
|
gl.BindVertexArray(vao);
|
|
gl.BindBuffer(gl::ARRAY_BUFFER, vbo);
|
|
|
|
gl.EnableVertexAttribArray(0); // this is "layout (location = 0)" in vertex shader
|
|
gl.VertexAttribPointer(
|
|
0, // index of the generic vertex attribute ("layout (location = 0)")
|
|
3, // the number of components per generic vertex attribute
|
|
gl::FLOAT, // data type
|
|
gl::FALSE, // normalized (int-to-float conversion)
|
|
(6 * std::mem::size_of::<f32>()) as gl::types::GLint, // stride (byte offset between consecutive attributes)
|
|
std::ptr::null() // offset of the first component
|
|
);
|
|
gl.EnableVertexAttribArray(1); // this is "layout (location = 0)" in vertex shader
|
|
gl.VertexAttribPointer(
|
|
1, // index of the generic vertex attribute ("layout (location = 0)")
|
|
3, // the number of components per generic vertex attribute
|
|
gl::FLOAT, // data type
|
|
gl::FALSE, // normalized (int-to-float conversion)
|
|
(6 * std::mem::size_of::<f32>()) as gl::types::GLint, // stride (byte offset between consecutive attributes)
|
|
(3 * std::mem::size_of::<f32>()) as *const gl::types::GLvoid // offset of the first component
|
|
);
|
|
|
|
gl.BindBuffer(gl::ARRAY_BUFFER, 0);
|
|
gl.BindVertexArray(0);
|
|
}
|
|
|
|
// set up shared state for window
|
|
|
|
unsafe {
|
|
gl.Viewport(0, 0, 900, 700);
|
|
gl.ClearColor(0.3, 0.3, 0.5, 1.0);
|
|
}
|
|
|
|
// main loop
|
|
|
|
let mut event_pump = sdl.event_pump().unwrap();
|
|
'main: loop {
|
|
for event in event_pump.poll_iter() {
|
|
match event {
|
|
sdl2::event::Event::Quit { .. } => break 'main,
|
|
_ => {}
|
|
}
|
|
}
|
|
|
|
unsafe {
|
|
gl.Clear(gl::COLOR_BUFFER_BIT);
|
|
}
|
|
|
|
// draw triangle
|
|
|
|
shader_program.set_used();
|
|
unsafe {
|
|
gl.BindVertexArray(vao);
|
|
gl.DrawArrays(
|
|
gl::TRIANGLES, // mode
|
|
0, // starting index in the enabled arrays
|
|
3, // number of indices to be rendered
|
|
);
|
|
}
|
|
|
|
window.gl_swap_window();
|
|
}
|
|
}
|