Created
August 5, 2021 12:54
-
-
Save newvertex/ac6eda7713b803418645b85e38950308 to your computer and use it in GitHub Desktop.
Basic triangle in Rust lang with GLFW and OpenGL
This file contains hidden or 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
use std::convert::TryInto; | |
use glfw; | |
use glfw::Context; | |
use gl; | |
const WIDTH: u32 = 480; | |
const HEIGHT: u32 = 320; | |
const TITLE: &str = "Hello From OpenGL World!"; | |
fn main() { | |
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)); | |
glfw.window_hint(glfw::WindowHint::OpenGlForwardCompat(true)); | |
glfw.window_hint(glfw::WindowHint::Resizable(false)); | |
let (mut window, events) = glfw.create_window(WIDTH, HEIGHT, TITLE, glfw::WindowMode::Windowed).unwrap(); | |
let (screen_width, screen_height) = window.get_framebuffer_size(); | |
window.make_current(); | |
window.set_key_polling(true); | |
gl::load_with(|ptr| window.get_proc_address(ptr) as *const _); | |
unsafe { | |
gl::Viewport(0, 0, screen_width, screen_height); | |
clear_color(Color(0.4, 0.4, 0.4, 1.0)); | |
} | |
// ------------------------------------------- | |
const VERT_SHADER: &str = "#version 330 core | |
layout (location = 0) in vec3 position; | |
void main() | |
{ | |
gl_Position = vec4(position, 1.0); | |
// gl_Position = vec4(position.xyz, 1.0); | |
// gl_Position = vec4(position.x, position.y, position.z, 1.0); | |
}"; | |
const FRAG_SHADER: &str = "#version 330 core | |
out vec4 Color; | |
void main() | |
{ | |
Color = vec4(0.9, 0.5, 0.2, 1.0); | |
}"; | |
let vertex_shader = unsafe { gl::CreateShader(gl::VERTEX_SHADER) }; | |
unsafe { | |
gl::ShaderSource(vertex_shader, 1, &VERT_SHADER.as_bytes().as_ptr().cast(), &VERT_SHADER.len().try_into().unwrap()); | |
gl::CompileShader(vertex_shader); | |
let mut success = 0; | |
gl::GetShaderiv(vertex_shader, gl::COMPILE_STATUS, &mut success); | |
if success == 0 { | |
let mut log_len = 0_i32; | |
// gl::GetShaderiv(vertex_shader, gl::INFO_LOG_LENGTH, &mut log_len); | |
// let mut v: Vec<u8> = Vec::with_capacity(log_len as usize); | |
// gl::GetShaderInfoLog(vertex_shader, log_len, &mut log_len, v.as_mut_ptr().cast()); | |
let mut v: Vec<u8> = Vec::with_capacity(1024); | |
gl::GetShaderInfoLog(vertex_shader, 1024, &mut log_len, v.as_mut_ptr().cast()); | |
v.set_len(log_len.try_into().unwrap()); | |
panic!("Vertex Shader Compile Error: {}", String::from_utf8_lossy(&v)); | |
} | |
} | |
let fragment_shader = unsafe { gl::CreateShader(gl::FRAGMENT_SHADER) }; | |
unsafe { | |
gl::ShaderSource(fragment_shader, 1, &FRAG_SHADER.as_bytes().as_ptr().cast(), &FRAG_SHADER.len().try_into().unwrap()); | |
gl::CompileShader(fragment_shader); | |
let mut success = 0; | |
gl::GetShaderiv(fragment_shader, gl::COMPILE_STATUS, &mut success); | |
if success == 0 { | |
let mut v: Vec<u8> = Vec::with_capacity(1024); | |
let mut log_len = 0_i32; | |
gl::GetShaderInfoLog(fragment_shader, 1024, &mut log_len, v.as_mut_ptr().cast()); | |
v.set_len(log_len.try_into().unwrap()); | |
panic!("Fragment Shader Compile Error: {}", String::from_utf8_lossy(&v)); | |
} | |
} | |
let shader_program = unsafe { gl::CreateProgram() }; | |
unsafe { | |
gl::AttachShader(shader_program, vertex_shader); | |
gl::AttachShader(shader_program, fragment_shader); | |
gl::LinkProgram(shader_program); | |
let mut success = 0; | |
gl::GetProgramiv(shader_program, gl::LINK_STATUS, &mut success); | |
if success == 0 { | |
let mut v: Vec<u8> = Vec::with_capacity(1024); | |
let mut log_len = 0_i32; | |
gl::GetProgramInfoLog(shader_program, 1024, &mut log_len, v.as_mut_ptr().cast()); | |
v.set_len(log_len.try_into().unwrap()); | |
panic!("Program Link Error: {}", String::from_utf8_lossy(&v)); | |
} | |
gl::DetachShader(shader_program, vertex_shader); | |
gl::DetachShader(shader_program, fragment_shader); | |
gl::DeleteShader(vertex_shader); | |
gl::DeleteShader(fragment_shader); | |
} | |
let vertecies = [ | |
-0.5f32, -0.5, 0.0, | |
0.5, -0.5, 0.0, | |
0.0, 0.5, 0.0, | |
]; | |
let mut vao = 0; | |
unsafe { gl::GenVertexArrays(1, &mut vao) }; | |
let mut vbo = 0; | |
unsafe { gl::GenBuffers(1, &mut vbo) }; | |
unsafe { | |
gl::BindVertexArray(vao); | |
gl::BindBuffer(gl::ARRAY_BUFFER, vbo); | |
gl::BufferData(gl::ARRAY_BUFFER, std::mem::size_of_val(&vertecies) as isize, vertecies.as_ptr().cast(), gl::STATIC_DRAW); | |
gl::VertexAttribPointer(0, 3, gl::FLOAT, gl::FALSE, 3 * std::mem::size_of::<f32>() as i32, 0 as *const _); | |
gl::EnableVertexAttribArray(0); | |
gl::BindBuffer(gl::ARRAY_BUFFER, 0); | |
gl::BindVertexArray(0); | |
} | |
// ------------------------------------------- | |
println!("OpenGL version: {}", gl_get_string(gl::VERSION)); | |
println!("GLSL version: {}", gl_get_string(gl::SHADING_LANGUAGE_VERSION)); | |
while !window.should_close() { | |
glfw.poll_events(); | |
for (_, event) in glfw::flush_messages(&events) { | |
glfw_handle_event(&mut window, event); | |
} | |
clear_color(Color(0.3, 0.4, 0.6, 1.0)); | |
unsafe { | |
gl::Clear(gl::COLOR_BUFFER_BIT); | |
} | |
unsafe { | |
gl::UseProgram(shader_program); | |
gl::BindVertexArray(vao); | |
gl::DrawArrays(gl::TRIANGLES, 0, 3); | |
gl::BindVertexArray(0); | |
} | |
window.swap_buffers(); | |
} | |
} | |
pub struct Color(f32, f32, f32, f32); | |
pub fn clear_color(c: Color) { | |
unsafe { gl::ClearColor(c.0, c.1, c.2, c.3) } | |
} | |
pub fn gl_get_string<'a>(name: gl::types::GLenum) -> &'a str { | |
let v = unsafe { gl::GetString(name) }; | |
let v: &std::ffi::CStr = unsafe { std::ffi::CStr::from_ptr(v as *const i8) }; | |
v.to_str().unwrap() | |
} | |
fn glfw_handle_event(window: &mut glfw::Window, event: glfw::WindowEvent) { | |
use glfw::WindowEvent as Event; | |
use glfw::Key; | |
use glfw::Action; | |
match event { | |
Event::Key(Key::Escape, _, Action::Press, _) => { | |
window.set_should_close(true); | |
}, | |
_ => {}, | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment