first push, simple setup to use opengl

It's all insired in copy/paste style by: https://github.com/Nercury/rust-and-opengl-lessons
This commit is contained in:
Lapin 2021-07-21 19:39:59 +02:00
commit cf64bec257
24 changed files with 3139 additions and 0 deletions

299
test_opengl/Cargo.lock generated Normal file
View file

@ -0,0 +1,299 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "aho-corasick"
version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
dependencies = [
"memchr",
]
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "cc"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2"
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cmake"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb6210b637171dfba4cda12e579ac6dc73f5165ad56133e5d72ef3131f320855"
dependencies = [
"cc",
]
[[package]]
name = "crc32fast"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "encoding_rs"
version = "0.8.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065"
dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "filetime"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8"
dependencies = [
"cfg-if 1.0.0",
"libc",
"redox_syscall",
"winapi",
]
[[package]]
name = "flate2"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0"
dependencies = [
"cfg-if 1.0.0",
"crc32fast",
"libc",
"miniz_oxide",
]
[[package]]
name = "gl"
version = "0.1.0"
dependencies = [
"gl_generator",
"gl_generator_profiling_struct",
]
[[package]]
name = "gl_generator"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a795170cbd85b5a7baa58d6d7525cae6a03e486859860c220f7ebbbdd379d0a"
dependencies = [
"khronos_api",
"log",
"xml-rs",
]
[[package]]
name = "gl_generator_profiling_struct"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f93e1b0666dae88dda1a2d6fe9fb12f17c0b5551d0621e3d753e2c42fc6c067"
dependencies = [
"gl_generator",
]
[[package]]
name = "khronos_api"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "037ab472c33f67b5fbd3e9163a2645319e5356fcd355efa6d4eb7fff4bbcb554"
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lesson-06-gl-struct"
version = "0.1.0"
dependencies = [
"gl",
"sdl2",
]
[[package]]
name = "libc"
version = "0.2.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
[[package]]
name = "log"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "memchr"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
[[package]]
name = "miniz_oxide"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
dependencies = [
"adler",
"autocfg",
]
[[package]]
name = "redox_syscall"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee"
dependencies = [
"bitflags",
]
[[package]]
name = "regex"
version = "1.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]]
name = "sdl2"
version = "0.34.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "deecbc3fa9460acff5a1e563e05cb5f31bba0aa0c214bb49a43db8159176d54b"
dependencies = [
"bitflags",
"lazy_static",
"libc",
"sdl2-sys",
]
[[package]]
name = "sdl2-sys"
version = "0.34.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41a29aa21f175b5a41a6e26da572d5e5d1ee5660d35f9f9d0913e8a802098f74"
dependencies = [
"cfg-if 0.1.10",
"cmake",
"flate2",
"libc",
"tar",
"unidiff",
"version-compare",
]
[[package]]
name = "tar"
version = "0.4.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d779dc6aeff029314570f666ec83f19df7280bb36ef338442cfa8c604021b80"
dependencies = [
"filetime",
"libc",
"xattr",
]
[[package]]
name = "unidiff"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8a62719acf1933bfdbeb73a657ecd9ecece70b405125267dd549e2e2edc232c"
dependencies = [
"encoding_rs",
"lazy_static",
"regex",
]
[[package]]
name = "version-compare"
version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d63556a25bae6ea31b52e640d7c41d1ab27faba4ccb600013837a3d0b3994ca1"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "xattr"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c"
dependencies = [
"libc",
]
[[package]]
name = "xml-rs"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c1cb601d29fe2c2ac60a2b2e5e293994d87a1f6fa9687a31a15270f909be9c2"
dependencies = [
"bitflags",
]

14
test_opengl/Cargo.toml Normal file
View file

@ -0,0 +1,14 @@
[package]
name = "lesson-06-gl-struct"
version = "0.1.0"
authors = ["Nerijus Arlauskas <nercury@gmail.com>"]
[dependencies]
gl = { path = "../lib/gl" }
[dependencies.sdl2]
version = "0.34.5"
features = ["bundled", "static-link"]
[features]
gl_debug = ["gl/debug"]

138
test_opengl/src/main.rs Normal file
View file

@ -0,0 +1,138 @@
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();
}
}

View file

@ -0,0 +1,162 @@
use gl;
use std;
use std::ffi::{CStr, CString};
pub struct Program {
gl: gl::Gl,
id: gl::types::GLuint,
}
impl Program {
pub fn from_shaders(gl: &gl::Gl, shaders: &[Shader]) -> Result<Program, String> {
let program_id = unsafe { gl.CreateProgram() };
for shader in shaders {
unsafe {
gl.AttachShader(program_id, shader.id());
}
}
unsafe {
gl.LinkProgram(program_id);
}
let mut success: gl::types::GLint = 1;
unsafe {
gl.GetProgramiv(program_id, gl::LINK_STATUS, &mut success);
}
if success == 0 {
let mut len: gl::types::GLint = 0;
unsafe {
gl.GetProgramiv(program_id, gl::INFO_LOG_LENGTH, &mut len);
}
let error = create_whitespace_cstring_with_len(len as usize);
unsafe {
gl.GetProgramInfoLog(
program_id,
len,
std::ptr::null_mut(),
error.as_ptr() as *mut gl::types::GLchar,
);
}
return Err(error.to_string_lossy().into_owned());
}
for shader in shaders {
unsafe {
gl.DetachShader(program_id, shader.id());
}
}
Ok(Program {
gl: gl.clone(),
id: program_id,
})
}
pub fn id(&self) -> gl::types::GLuint {
self.id
}
pub fn set_used(&self) {
unsafe {
self.gl.UseProgram(self.id);
}
}
}
impl Drop for Program {
fn drop(&mut self) {
unsafe {
self.gl.DeleteProgram(self.id);
}
}
}
pub struct Shader {
gl: gl::Gl,
id: gl::types::GLuint,
}
impl Shader {
pub fn from_source(
gl: &gl::Gl,
source: &CStr,
kind: gl::types::GLenum,
) -> Result<Shader, String> {
let id = shader_from_source(gl, source, kind)?;
Ok(Shader { gl: gl.clone(), id })
}
pub fn from_vert_source(gl: &gl::Gl, source: &CStr) -> Result<Shader, String> {
Shader::from_source(gl, source, gl::VERTEX_SHADER)
}
pub fn from_frag_source(gl: &gl::Gl, source: &CStr) -> Result<Shader, String> {
Shader::from_source(gl, source, gl::FRAGMENT_SHADER)
}
pub fn id(&self) -> gl::types::GLuint {
self.id
}
}
impl Drop for Shader {
fn drop(&mut self) {
unsafe {
self.gl.DeleteShader(self.id);
}
}
}
fn shader_from_source(
gl: &gl::Gl,
source: &CStr,
kind: gl::types::GLenum,
) -> Result<gl::types::GLuint, String> {
let id = unsafe { gl.CreateShader(kind) };
unsafe {
gl.ShaderSource(id, 1, &source.as_ptr(), std::ptr::null());
gl.CompileShader(id);
}
let mut success: gl::types::GLint = 1;
unsafe {
gl.GetShaderiv(id, gl::COMPILE_STATUS, &mut success);
}
if success == 0 {
let mut len: gl::types::GLint = 0;
unsafe {
gl.GetShaderiv(id, gl::INFO_LOG_LENGTH, &mut len);
}
let error = create_whitespace_cstring_with_len(len as usize);
unsafe {
gl.GetShaderInfoLog(
id,
len,
std::ptr::null_mut(),
error.as_ptr() as *mut gl::types::GLchar,
);
}
return Err(error.to_string_lossy().into_owned());
}
Ok(id)
}
fn create_whitespace_cstring_with_len(len: usize) -> CString {
// allocate buffer of correct size
let mut buffer: Vec<u8> = Vec::with_capacity(len + 1);
// fill it with len spaces
buffer.extend([b' '].iter().cycle().take(len));
// convert buffer to CString
unsafe { CString::from_vec_unchecked(buffer) }
}

View file

@ -0,0 +1,12 @@
#version 330 core
in VS_OUTPUT {
vec3 Color;
} IN;
out vec4 Color;
void main()
{
Color = vec4(IN.Color, 1.0f);
}

View file

@ -0,0 +1,14 @@
#version 330 core
layout (location = 0) in vec3 Position;
layout (location = 1) in vec3 Color;
out VS_OUTPUT {
vec3 Color;
} OUT;
void main()
{
gl_Position = vec4(Position, 1.0);
OUT.Color = Color;
}