昨日はこのザマでしたが、今日は失敗した原因を特定して水分子画像をアルファ値を考慮して正しく描画出来ました。
(੭ ˃̣̣̥ ω˂̣̣̥)੭ु⁾⁾
コードは以下です。一部このページのライブラリを使っています。
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
extern crate sdl2;
extern crate gl;
extern crate image;
pub mod render_gl;
use std::path::Path;
use std::os::raw::c_void;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::video::GLProfile;
fn main() {
let window_w: u32= 800;
let window_h: u32= 600;
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_version(4, 5);
let window = video_subsystem.window("環境原猫", window_w, window_h)
.opengl()
.resizable() // .fullscreen_desktop()
.build()
.unwrap();
let _ctx = window.gl_create_context().unwrap();
gl::load_with(|name| video_subsystem.gl_get_proc_address(name) as *const _);
debug_assert_eq!(gl_attr.context_profile(), GLProfile::Core);
debug_assert_eq!(gl_attr.context_version(), (4, 5));
// shader program
use std::ffi::CString;
let vert_shader = render_gl::Shader::from_vert_source(&CString::new(include_str!("triangle.vert")).unwrap()).unwrap();
let frag_shader = render_gl::Shader::from_frag_source(&CString::new(include_str!("triangle.frag")).unwrap()).unwrap();
let shader_program = render_gl::Program::from_shaders(&[vert_shader, frag_shader]).unwrap();
// texture
let img = image::open(&Path::new("resources/textures/drop.png")).expect("Failed to load texture");
let format = match img {
image::DynamicImage::ImageLuma8(_) => gl::RED,
image::DynamicImage::ImageLumaA8(_) => gl::RG,
image::DynamicImage::ImageRgb8(_) => gl::RGB,
image::DynamicImage::ImageRgba8(_) => gl::RGBA,
_ => panic!("unknown format.")
};
let mut texture = 0;
unsafe {
gl::GenTextures(1, &mut texture);
gl::BindTexture(gl::TEXTURE_2D, texture);
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::REPEAT as i32);
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::REPEAT as i32);
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as i32);
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST as i32);
let data = img.as_bytes();
gl::TexImage2D(gl::TEXTURE_2D,
0,
format as i32,
img.width() as i32,
img.height() as i32,
0,
format,
gl::UNSIGNED_BYTE,
&data[0] as *const u8 as *const c_void);
gl::GenerateMipmap(gl::TEXTURE_2D);
}
// vertex buffer object
let vertices: Vec<f32> = vec![-0.5, -0.5, 0.0, 0.5, -0.5, 0.0, 0.0, 0.5, 0.0];
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,
(vertices.len() * std::mem::size_of::<f32>()) as gl::types::GLsizeiptr,
vertices.as_ptr() as *const gl::types::GLvoid,
gl::STATIC_DRAW,
);
gl::BindBuffer(gl::ARRAY_BUFFER, 0);
}
// 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); // layout (location = 0)
gl::VertexAttribPointer(
0, // index
3, // number of components
gl::FLOAT, // data type
gl::FALSE, // normalized
(3 * std::mem::size_of::<f32>()) as gl::types::GLint, // stride
std::ptr::null(), // offset
);
gl::BindBuffer(gl::ARRAY_BUFFER, 0);
gl::BindVertexArray(0);
}
// set up
unsafe {
gl::Viewport(0, 0, window_w as i32, window_h as i32);
gl::ClearColor(0.6, 0.0, 0.8, 1.0);
gl::Enable(gl::VERTEX_PROGRAM_POINT_SIZE);
gl::Enable(gl::BLEND);
gl::BlendFuncSeparate(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA, gl::ONE, gl::ONE);
}
let mut event_pump = sdl_context.event_pump().unwrap();
'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);
}
// draw point sprites
shader_program.set_used();
unsafe {
gl::BindVertexArray(vao);
gl::DrawArrays(
gl::POINTS, // mode
0, // starting index
3, // number of indices
);
}
// swap window
window.gl_swap_window();
::std::thread::sleep(::std::time::Duration::new(0, 1_000_000_000u32 / 60));
}
}
次の日