Created
May 15, 2017 20:35
-
-
Save m-decoster/290347012be4cf8539732b2f389ab2b0 to your computer and use it in GitHub Desktop.
OpenGL + SDL2 Rust example based on https://github.com/brendanzab/gl-rs/blob/master/gl/examples/triangle.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[package] | |
name = "triangle" | |
version = "0.1.0" | |
authors = ["Mathieu De Coster <mth.decoster@gmail.com>"] | |
[dependencies] | |
sdl2 = "0.30" | |
gl = "0.6" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// OpenGL + SDL2 example. Based on | |
// https://github.com/brendanzab/gl-rs/blob/master/gl/examples/triangle.rs | |
// but replacing glutin with SDL2. | |
extern crate sdl2; | |
extern crate gl; | |
use sdl2::video::GLProfile; | |
use sdl2::event::Event; | |
use sdl2::keyboard::Keycode; | |
use gl::types::*; | |
use std::mem; | |
use std::ptr; | |
use std::str; | |
use std::ffi::CString; | |
// Vertex data | |
static VERTEX_DATA: [GLfloat; 6] = [ | |
0.0, 0.5, | |
0.5, -0.5, | |
-0.5, -0.5 | |
]; | |
// Shader sources | |
static VS_SRC: &'static str = include_str!("triangle.vert"); | |
static FS_SRC: &'static str = include_str!("triangle.frag"); | |
fn compile_shader(src: &str, ty: GLenum) -> GLuint { | |
let shader; | |
unsafe { | |
shader = gl::CreateShader(ty); | |
// Attempt to compile the shader | |
let c_str = CString::new(src.as_bytes()).unwrap(); | |
gl::ShaderSource(shader, 1, &c_str.as_ptr(), ptr::null()); | |
gl::CompileShader(shader); | |
// Get the compile status | |
let mut status = gl::FALSE as GLint; | |
gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut status); | |
// Fail on error | |
if status != (gl::TRUE as GLint) { | |
let mut len = 0; | |
gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &mut len); | |
let mut buf = Vec::with_capacity(len as usize); | |
buf.set_len((len as usize) - 1); // subtract 1 to skip the trailing null character | |
gl::GetShaderInfoLog(shader, len, ptr::null_mut(), buf.as_mut_ptr() as *mut GLchar); | |
panic!("{}", str::from_utf8(&buf).ok().expect("ShaderInfoLog not valid utf8")); | |
} | |
} | |
shader | |
} | |
fn link_program(vs: GLuint, fs: GLuint) -> GLuint { unsafe { | |
let program = gl::CreateProgram(); | |
gl::AttachShader(program, vs); | |
gl::AttachShader(program, fs); | |
gl::LinkProgram(program); | |
// Get the link status | |
let mut status = gl::FALSE as GLint; | |
gl::GetProgramiv(program, gl::LINK_STATUS, &mut status); | |
// Fail on error | |
if status != (gl::TRUE as GLint) { | |
let mut len: GLint = 0; | |
gl::GetProgramiv(program, gl::INFO_LOG_LENGTH, &mut len); | |
let mut buf = Vec::with_capacity(len as usize); | |
buf.set_len((len as usize) - 1); // subtract 1 to skip the trailing null character | |
gl::GetProgramInfoLog(program, len, ptr::null_mut(), buf.as_mut_ptr() as *mut GLchar); | |
panic!("{}", str::from_utf8(&buf).ok().expect("ProgramInfoLog not valid utf8")); | |
} | |
program | |
} } | |
fn main() { | |
let sdl_context = sdl2::init().unwrap(); | |
let video_subsystem = sdl_context.video().unwrap(); | |
let gl_attr = video_subsystem.gl_attr(); | |
gl_attr.set_context_profile(GLProfile::Core); | |
gl_attr.set_context_flags().debug().set(); | |
gl_attr.set_context_version(3, 3); | |
let window = video_subsystem | |
.window("rust-sdl2 opengl triangle", 800, 600) | |
.opengl() | |
.resizable() | |
.build() | |
.unwrap(); | |
gl::load_with(|name| video_subsystem.gl_get_proc_address(name) as *const _); | |
let gl_context = window.gl_create_context().unwrap(); | |
window.gl_make_current(&gl_context).unwrap(); | |
// Create GLSL shaders | |
let vs = compile_shader(VS_SRC, gl::VERTEX_SHADER); | |
let fs = compile_shader(FS_SRC, gl::FRAGMENT_SHADER); | |
let program = link_program(vs, fs); | |
let mut vao = 0; | |
let mut vbo = 0; | |
unsafe { | |
// Create Vertex Array Object | |
gl::GenVertexArrays(1, &mut vao); | |
gl::BindVertexArray(vao); | |
// Create a Vertex Buffer Object and copy the vertex data to it | |
gl::GenBuffers(1, &mut vbo); | |
gl::BindBuffer(gl::ARRAY_BUFFER, vbo); | |
gl::BufferData(gl::ARRAY_BUFFER, | |
(VERTEX_DATA.len() * mem::size_of::<GLfloat>()) as GLsizeiptr, | |
mem::transmute(&VERTEX_DATA[0]), | |
gl::STATIC_DRAW); | |
// Use shader program | |
gl::UseProgram(program); | |
gl::BindFragDataLocation(program, 0, | |
CString::new("out_color").unwrap().as_ptr()); | |
// Specify the layout of the vertex data | |
let pos_attr = gl::GetAttribLocation(program, | |
CString::new("position").unwrap().as_ptr()); | |
gl::EnableVertexAttribArray(pos_attr as GLuint); | |
gl::VertexAttribPointer(pos_attr as GLuint, 2, gl::FLOAT, | |
gl::FALSE as GLboolean, 0, ptr::null()); | |
} | |
let mut event_pump = sdl_context.event_pump().unwrap(); | |
unsafe { | |
gl::ClearColor(0.0, 0.0, 0.0, 1.0); | |
} | |
'running: loop { | |
for event in event_pump.poll_iter() { | |
match event { | |
Event::Quit { .. } | | |
Event::KeyDown { keycode: Some(Keycode::Escape), .. } => break 'running, | |
_ => {} | |
} | |
} | |
unsafe { | |
gl::Clear(gl::COLOR_BUFFER_BIT); | |
gl::DrawArrays(gl::TRIANGLES, 0, 3); | |
} | |
window.gl_swap_window(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#version 330 core | |
out vec4 out_color; | |
void main() { | |
out_color = vec4(1.0, 1.0, 1.0, 1.0); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#version 330 core | |
layout(location=0) in vec2 position; | |
void main() { | |
gl_Position = vec4(position, 0.0, 1.0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment