ãŸããç§ã¯Rustã3Dã°ã©ãã£ãã¯ã¹ã®å°é家ã§ã¯ãããŸãããããã®èšäºãæžãéçšã§ãããã®ããšãæ£ããç 究ããŠããã®ã§ãé倧ãªãšã©ãŒãè±èœããããããããŸããããç§ã¯ããããæã£ãŠãããªãä¿®æ£ã§ããŠããããã§ãã³ã¡ã³ãã§ç€ºããŠãã ããã
èšäºã®æåŸã«ãããã·ã³
è¡ãæŽçãã
ããŠãæªå€¢ã®ãããªæäœãã®é¢æ°è¡ãhaqreuã® Bresenhamã¢ã«ãŽãªãºã ã®éåžžã®å®è£ ã«æžãæããããšããå§ããŸãããã 第äžã«ãé«éã§ã第äºã«æšæºç ã第äžã«ãRust ã³ãŒããšC ++ã³ãŒããæ¯èŒã§ããŸã ã
pub fn line(&mut self, mut x0: i32, mut y0: i32, mut x1: i32, mut y1: i32, color: u32) { let mut steep = false; if (x0-x1).abs() < (y0-y1).abs() { mem::swap(&mut x0, &mut y0); mem::swap(&mut x1, &mut y1); steep = true; } if x0>x1 { mem::swap(&mut x0, &mut x1); mem::swap(&mut y0, &mut y1); } let dx = x1-x0; let dy = y1-y0; let derror2 = dy.abs()*2; let mut error2 = 0; let mut y = y0; for x in x0..x1+1 { if steep { self.set(y, x, color); } else { self.set(x, y, color); } error2 += derror2; if error2 > dx { y += if y1>y0 { 1 } else { -1 }; error2 -= dx*2; } } }
ã芧ã®ãšãããéãã¯æå°éã§ãããå ã®è¡ã«å¯Ÿããè¡æ°ã¯å€æŽãããŠããŸããã ãã®æ®µéã§ã¯ç¹ã«å°é£ã¯ãããŸããã§ããã
ãã¹ãããã
ã©ã€ã³ã®å®è£ ãçµãã£ãåŸããã¹ãã§éåžžã«åœ¹ç«ã£ãã³ãŒããåé€ããªãããšã«ããŸãããããã«ããããã¹ãã©ã€ã³ã3ã€æç»ãããŸããã
let mut canvas = canvas::Canvas::new(100, 100); canvas.line(13, 20, 80, 40, WHITE); canvas.line(20, 13, 40, 80, RED); canvas.line(80, 40, 13, 20, BLUE);
å ã®èšäºã®èè ãã©ã®ãããªçµéšãæã£ãŠãããã¯ããããŸãããããããã®3ã€ã®åŒã³åºãã¯ãã©ã€ã³ã®å®è£ æã«çºçããå¯èœæ§ã®ããã»ãŒãã¹ãŠã®ãšã©ãŒãã«ããŒããŠããããšãããããŸããã ãããŠããã¡ãããç§ã¯èš±å¯ããŸããã
æªäœ¿çšã®é¢æ°ã«ã³ãŒããåé€ãããšãRustãã³ã³ãã€ã«ãããã³ã«èŠåã衚瀺ãããŸãïŒã³ã³ãã€ã©ãŒã¯ãã¹ãŠã®æªäœ¿çšã®é¢æ°ãŸãã¯å€æ°ãèªããŸãïŒã ãã¡ãããäžã®ããã·ã¥
_test_line()
ã§å§ãŸãååãé¢æ°ã«äžããããšã§èŠåãæå¶ããããšãã§ããŸãããã©ããããããèãã§ãã ãããŠãæœåšçã«æçšã§ãããçŸåšã¯äžå¿ èŠãªã³ãŒããäžè¬çãªã³ã¡ã³ãã«ä¿åããããã«ãç§ã®æèŠã§ã¯ãããã°ã©ãã³ã°ã®æªã調åã§ãã ããã¹ããŒããªãœãªã¥ãŒã·ã§ã³ã¯ããã¹ããäœæããããšã§ãïŒ ãããã£ãŠãæ å ±ã«ã€ããŠã¯ããã®èšèªã§æåã®ãã¹ããè¡ãããã«ãRustã®ãã¹ãæ©èœã«é¢ãã察å¿ããèšäºãåç §ããŠãã ããã
ããã¯åºæ¬çãªæ¹æ³ã§è¡ãããŸãã é¢æ°ã®çœ²åã®äžã«
#[test]
è¡ãæžãã ãã§ååã§ãã ããã¯åœŒå¥³ããã¹ãã«å€ããŸãã Rustã¯æªäœ¿çšã®é¢æ°ãªã©ã®èŠåé¢æ°ã衚瀺ããŸããã
cargo test
ãå®è¡ãããšããããžã§ã¯ãå ã®ãã¹ãŠã®é¢æ°ã®å®è¡ã«é¢ããçµ±èšãCargoã«è¡šç€ºãããŸãã
Running target/debug/rust_project-2d87cd565073580b running 1 test test test_line ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
èå³æ·±ãããšã«ããããžã§ã¯ãã®å ¥åãã€ã³ãããã¹ããšããŠããŒã¯ãããé¢æ°ã§ãããšããäºå®ã«åºã¥ããŠãæªäœ¿çšã®ãã¹ãŠã®é¢æ°ãšå€æ°ã«å¯ŸããŠwarning'iã衚瀺ãããŸãã å°æ¥çã«ã¯ãããã¯ãããžã§ã¯ãæ©èœã®ãã¹ãç¯å²ã®æ±ºå®ã«åœ¹ç«ã¡ãŸãã ãã¹ãã§ã¯å®éã«ã¯äœããã¹ããããŸããããæç»çµæã®ãŠã£ã³ããŠã衚瀺ãããŠããã«æ¶ããã®ã¯æããã§ãã è¯ãæ¹æ³ã§ã¯ãCanvasã眮ââãæããã¢ãã¯ãªããžã§ã¯ããå¿ èŠã§ããããã«ããã
set(x, y, color);
é¢æ°ã®åŒã³åºãã·ãŒã±ã³ã¹ã確èªã§ããŸã
set(x, y, color);
ã»ãããžã®ã³ã³ãã©ã€ã¢ã³ã¹ã ãã®åŸãèªååäœãã¹ãã«ãªããŸãã ãããŸã§ã®éã察å¿ããã³ã³ãã€ã©ãŒæ©èœãããããŸããã ãããã®å€æŽåŸã®ãªããžããªã®ã¹ãããã·ã§ããã次ã«ç€ºããŸã ã
ãã¯ã¿ãŒãšèªã¿åããã¡ã€ã«
ããã§ã¯ãã¯ã€ã€ãŒã¬ã³ããªã³ã°ã®å®è£ ãéå§ããŸãã ãã®ãã¹ã«æ²¿ã£ãæåã®é害ã¯ãã¢ãã«ãã¡ã€ã«ïŒ Wavefront .objãã¡ã€ã«åœ¢åŒã§ä¿åãããŠããïŒãèªã¿åãå¿ èŠãããããšã§ãã haqreuã¯åœŒã®èšäºã§ã haqreuã«ãã£ãŠæ瀺ããã2次å ããã³3次å ã®ãã¯ãã«ã®ã¯ã©ã¹ã䜿çšããåŠçåãã®æ¢è£œã®ããŒãµãŒãæäŸããŸã ã ãã®å®è£ ã¯C ++ã§ãããããããããã¹ãŠRustã§æžãçŽãå¿ èŠããããŸãã ãã¯ãã«ããèªç¶ã«å§ããŸãããã å ã®ãã¯ãã«ïŒ2次å ããŒãžã§ã³ïŒã®ã³ãŒãã¹ããããã次ã«ç€ºããŸãã
template <class t> struct Vec2 { union { struct {tu, v;}; struct {tx, y;}; t raw[2]; }; Vec2() : u(0), v(0) {} Vec2(t _u, t _v) : u(_u),v(_v) {} inline Vec2<t> operator +(const Vec2<t> &V) const { return Vec2<t>(u+Vu, v+Vv); } inline Vec2<t> operator -(const Vec2<t> &V) const { return Vec2<t>(uV.u, vV.v); } inline Vec2<t> operator *(float f) const { return Vec2<t>(u*f, v*f); } template <class > friend std::ostream& operator<<(std::ostream& s, Vec2<t>& v); };
C ++ã§ã®ãã¯ã¿ãŒã®å®è£ ã§ã¯ããã³ãã¬ãŒãã䜿çšãããŸãã Rustã§ã¯ããããã®é¡äŒŒç©ã¯Genericsã§ãããããã«ã€ããŠã¯ã察å¿ããèšäºãèªãããšãã§ãã rustbyexample.comã§ã® 䜿çšäŸãåç §ã§ããŸãã äžè¬ã«ããã®ãµã€ãã¯RustãåŠã¶ãšãã«éåžžã«åœ¹ç«ã€ãªãœãŒã¹ã§ãã èšèªã®ããããå¯èœæ§ã«ã€ããŠã詳现ãªã³ã¡ã³ãã®äœ¿çšäŸãšããã©ãŠã¶ãŒãŠã£ã³ããŠã§çŽæ¥ãµã³ãã«ãç·šéããã³å®è¡ããæ©èœããããŸãïŒã³ãŒãã¯ãªã¢ãŒããµãŒããŒã§å®è¡ãããŸãïŒã
åŒæ°ãåããããŒããã¯ãã«ïŒ0ã0ïŒãäœæããã³ã³ã¹ãã©ã¯ã¿ãŒãäœæããããšãããšãå¥ã®åé¡ãçºçããŸããã ç§ãç解ããŠããããã«ãæé»çãªåãã£ã¹ãããªããããããã©ã«ãå€ã§æ§é ãåæåããããšãã§ããªããããã©ã¹ã¿åã·ã¹ãã ãäœæã§ããŸããã åæ§ã®æ©èœã¯traitsãä»ããŠå®è£ ã§ããŸããããã®ããã«ã¯å€ãã®ã³ãŒããèšè¿°ããããæšæºçãªç¹æ§
std::num::Zero
䜿çšããå¿ èŠããããŸããããã¯äžå®å®ã§ãã ç§ã¯äž¡æ¹ã®ãªãã·ã§ã³ãæ°ã«å ¥ããªãã£ãã®ã§ãã³ãŒãã«
new(0, 0)
ãæžãæ¹ãç°¡åã ãšå€æããŸããã
äžè¬åãããã¿ã€ããã¿ã€ããããã³æŒç®åã®ãªãŒããŒããŒãã«ããã·ã§ãŒããŠã³ã«ã¯æ°æéããããŸããã ãã¯ãã«ã®å ã®ã¯ã©ã¹ã®é¡äŒŒç©ãå®è£ ããããã«ãäžè¬åãããåã®æŒç®åãªãŒããŒããŒãïŒããèªäœã¯ç¹æ§ã䜿çšããŠé 眮ãããŠããïŒãè¡ãæ¹æ³ãããã«æãäžããå¿ èŠãããããšã«æ°ã¥ãããšããç§ã¯å¥ã®åŽããè¡ãããšã«ããŸããã C ++ã§ã¯æ°è¡ã®ã³ãŒãã§è¡ãããRustã§ã¯æã ããè€éã§é·ãã³ãŒãã§å®è£ ãããããã§ãã ããããããã¯ãã¢ã«ãŽãªãºã ãç解ãããã®é¡äŒŒç©ãå€§å¹ ã«ç°ãªãã€ããªãã®ãŒãæã€èšèªã§æžãã®ã§ã¯ãªããæåéãC ++ã³ãŒããRustã«ç¿»èš³ããããšããŠãããšããäºå®ã«ãããã®ã§ãã äžè¬ã«ãç§ãç¥ãéãã§ã¯ããã®ããšã«ã€ããŠã®ç§èªèº«ã®å€æã«åŸã£ãŠãã¢ãã«ãã¡ã€ã«ããã®æ å ±ãä¿åããå¿ èŠãããæ©èœã®ã¿ã§ãç¬èªã®ãã¯ã¿ãŒãäœæããããšã«æ±ºããŸããã çµæã¯éåžžã«åçŽãªã¯ã©ã¹ã§ãããã¿ã¹ã¯ã®çŸåšã®æ®µéã§ã¯ããã§ååã§ãã
pub struct Vector3D { pub x: f32, pub y: f32, pub z: f32, } impl Vector3D { pub fn new(x: f32, y: f32, z: f32) -> Vector3D { Vector3D { x: x, y: y, z: z, } } } impl fmt::Display for Vector3D { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "({},{},{})", self.x, self.y, self.z) } }
ããã§ããŒãµãŒã䜿çšã§ããŸãããRustã§ã®ãã¡ã€ã«ã®æäœã«ã€ããŠã¯ãŸã æ€èšããŠããŸããã ãã®åŸãStackOverflowãå©ãã«ãªããããããããã³ãŒãäŸã§çãããããŸããã ããã«åºã¥ããŠã次ã®ã³ãŒããååŸãããŸããã
pub struct Model { pub vertices: Vec<Vector3D>, pub faces : Vec<[i32; 3]>, } impl Model { pub fn new(file_path: &str) -> Model { let path = Path::new(file_path); let file = BufReader::new(File::open(&path).unwrap()); let mut vertices = Vec::new(); let mut faces = Vec::new(); for line in file.lines() { let line = line.unwrap(); if line.starts_with("v ") { let words: Vec<&str> = line.split_whitespace().collect(); vertices.push(Vector3D::new(words[1].parse().unwrap(), words[2].parse().unwrap(), words[3].parse().unwrap())); debug!("readed vertex: {}", vertices.last().unwrap()); } else if line.starts_with("f ") { let mut face: [i32; 3] = [-1, -1, -1]; let words: Vec<&str> = line.split_whitespace().collect(); for i in 0..3 { face[i] = words[i+1].split("/").next().unwrap().parse().unwrap(); face[i] -= 1; debug!("face[{}] = {}", i, face[i]); } faces.push(face); } } Model { vertices: vertices, faces: faces, } } }
圌ã«ã¯ç¹ã«å°é£ã¯ãããŸããã§ããã ãã¡ã€ã«ãèªã¿åããè¡ãåŠçããã ãã§ãã Rastã§ãããäœæããæ¹æ³ã«é¢ããæ å ±ã®æ€çŽ¢ã®ã¿ããã€ã³ã¿ãŒãããäžã®
from_str()
ã¡ãœããã®äŸããããã«
from_str()
ãŸãã
æåããã®ã³ãŒããééããŠã
faces.push(face);
è¡ãæžãã®ãå¿ããŸãã
faces.push(face);
é·ãéãã¬ã³ããŒããã¹ãŠã®é¡ãéããµã€ã¯ã«ã«å ¥ããªãã£ãçç±ãç解ã§ããŸããã§ããã å ¥åããããšã§åé¡ãäœã§ããããèŠã€ããåŸãã³ã³ãã€ã©åºå
warning: variable does not need to be mutable, #[warn(unused_mut)] on by default
èå³æ·±ãè¡ãèŠã€ãããŸãã
warning: variable does not need to be mutable, #[warn(unused_mut)] on by default
å€æ°faceã宣èšããè¡ã«å¯ŸããŠçžå¯Ÿç
warning: variable does not need to be mutable, #[warn(unused_mut)] on by default
ã æªäœ¿çšã®å€æ°ã«é¢ããèŠåããŸã ããããããã®ã§ããã®èŠåã«æ°ä»ããŸããã§ããã ãã®åŸãæªäœ¿çšã®å€æ°ããã¹ãŠã³ã¡ã³ãã¢ãŠãããã®ã§ãèŠåãç®ç«ã¡ãŸãã Rustã§ã¯ãã³ã³ãã€ã©ã®èŠåã¯ãã°ãèŠã€ããã®ã«éåžžã«åœ¹ç«ã¡ãç¡èŠããã¹ãã§ã¯ãããŸããã
ãŸããC ++ã®ãªãªãžãã«ãšã¯ç°ãªããã³ãŒããéåžžã«ã·ã³ãã«ã§ç解ããããããã«èŠããããšã«ã泚æããŠãã ããã åæ§ã«ãPythonãŸãã¯Javaã§äœæããããšãã§ããŸãã ãŸããå ã®è£œåãšæ¯èŒããŠçç£æ§ãé«ãããšãèå³æ·±ãã§ãã ã¬ã³ããªã³ã°å šäœã®éå§ããçµäºãŸã§ã®æºåãã§ããããããã©ãŒãã³ã¹ã枬å®ããäºå®ã§ãã
ã¯ã€ã€ãŒã¬ã³ããŒ
æåŸã«ãããã¯ã¯ã€ã€ãŒã¬ã³ããŒã§ãã ã»ãšãã©ã®äœæ¥ã¯åã®æé ã§è¡ããããããã³ãŒãã¯ç°¡åã§ãã
fn main() { env_logger::init().unwrap(); info!("starting up"); let model = Model::new("african_head.obj"); let mut canvas = canvas::Canvas::new(WIDTH, HEIGHT); debug!("drawing wireframe"); for face in model.faces { debug!("processing face:"); debug!("({}, {}, {})", face[0], face[1], face[2]); for j in 0..3 { let v0 = &model.vertices[face[j] as usize]; let v1 = &model.vertices[face[(j+1)%3] as usize]; let x0 = ((v0.x+1.)*WIDTH as f32/2.) as i32; let y0 = ((v0.y+1.)*HEIGHT as f32/2.) as i32; let x1 = ((v1.x+1.)*WIDTH as f32/2.) as i32; let y1 = ((v1.y+1.)*HEIGHT as f32/2.) as i32; debug!("drawing line ({}, {}) - ({}, {})", x0, y0, x1, y1); canvas.line(x0, y0, x1, y1, WHITE); } } info!("waiting for ESC"); canvas.wait_for_esc(); }
æ§æã®ããããªéãã¯å¥ãšããŠãC ++ãšã¯äž»ã«å€æ°ã®åå€æãç°ãªããŸãã ãŸãããšã©ãŒãæ¢ããŠãããšãã«ã©ãã§ãçªã£èŸŒãã ãã°ã ãããæçµçã«åŸãããç»åã§ãïŒ ãªããžããªå ã®ã³ãŒãã®ã¹ãããã·ã§ãã ïŒïŒ
ããã¯ãã§ã«ããªãè¯ãã§ãããæåã«ãçŸåšã®åœ¢åŒã§ããã°ã©ã ããã£ãŒãããããšããŠãããã·ã³ã®ã¢ãã«ã«ãã£ãŒããããšãåã«è¡šç€ºãããŸããã 第äºã«ãããããã¹ãŠã®çŸããã¯ã²ã©ãé·ãæãããŠããŸãïŒç§ã¯ããã°ã©ã ãç«ã¡äžããã³ãŒããŒã飲ã¿ã«è¡ãããšãã§ããŸãïŒã æåã®åé¡ã¯ãã¿ã€ãã©ã€ã¿ãŒã®ã¢ãã«ã§ã¯ãé ç¹ããŸã£ããç°ãªãã¹ã±ãŒã«ã§èšé²ãããããšã§ãã äžèšã®ã³ãŒãã¯ãé éšã¢ãã«ã®ã¹ã±ãŒã«ã«åãããŠèª¿æŽãããŠããŸãã ãããæ®éçã«ããããã«ã¯ãããªãã¯ãŸã ããã䜿ããªããã°ãªããŸããã 2çªç®ã®åé¡ã¯äœã®ãããããããŸããããèããŠã¿ããšã2ã€ã®ãªãã·ã§ã³ãããããŸãããéå¹ççãªã¢ã«ãŽãªãºã ã䜿çšãããããã®ã¢ã«ãŽãªãºã ã®éå¹ççãªå®è£ ããã®ç¹å®ã®æè¡ã¹ã¿ãã¯ã«èšè¿°ããŸãã ãããã«ãããå¥ã®çåãçããŸããã¢ã«ãŽãªãºã ã®ç¹å®ã®éšåïŒå®è£ ïŒã¯éå¹ççã§ãã
äžè¬ã«ããã§ã«ç解ããŠããããã«ãé床ã®åé¡ããå§ããããšã«ããŸããã
ããã©ãŒãã³ã¹ã枬å®ãã
å ã®ãããžã§ã¯ãã®ããã©ãŒãã³ã¹ãšRustã§ã®å®è£ ãæ¯èŒããèšç»ããŸã ãã£ããããæ©ãã«å®è¡ããããšã«ããŸããã ãã ãããªãªãžãã«ã®åäœåçãšç§ã®å®è£ ã¯å€§ããç°ãªããŸãã ãªãªãžãã«ã¯äžæãããã¡ã«æç»ããæåŸã«ã®ã¿TGAãã¡ã€ã«ãæžã蟌ã¿ãŸãããç§ã®ã¢ããªã±ãŒã·ã§ã³ã¯äžè§åœ¢ãåŠçããããã»ã¹ã§SDLã¬ã³ããªã³ã°ã³ãã³ããå®è¡ããŸãã
解決çã¯ç°¡åã§ã-CanvasãåäœæããŠããã€ã³ã
set(x, y, color)
ãæç»ããæ¹æ³ãå éšé åã«ããŒã¿ãä¿åããã ãã§ãSDLã䜿çšããçŽæ¥æç»ã¯ããã¹ãŠã®èšç®ãå®äºããåŸãããã°ã©ã ã®æåŸã«ãã§ã«è¡ãããŠããããã«ããŸãã ããã«ããã1ç³ã§3矜ã®é³¥ã殺ããŸãã
- ãã¡ã€ã«ã«ã¬ã³ããªã³ã°/ä¿åããåãã€ãŸãæ¬è³ªçã«åãããšãè¡ãå®è£ ã®é床ãæ¯èŒããæ©äŒãåŸãŸãã
- ããã«ãããã¡ãªã³ã°ã®æºåãããŠããŸãã
- èšç®ãæç»ããåé¢ããŸããããã«ãããSDLåŒã³åºãã«ãã£ãŠèª²ããããªãŒããŒããããè©äŸ¡ã§ããŸãã
Canvasããã°ããæžãæããåŸãç·ã®èšç®èªäœãéåžžã«é«éã§ããããšãããããŸããã ãã ããSDLã䜿çšããã¬ã³ããªã³ã°ã¯éåžžã«é«éã§è¡ãããŸããã æé©åã®ç¯å²ããããŸãã Rust-SDL2ã®ç¹æç»æ©èœã¯ãäºæ³ããã»ã©é«éã§ã¯ãªãããšãå€æããŸããã ç»åå šäœããã¯ã¹ãã£ã«ä¿åãããã®ã³ãŒãã§ãã®ãã¯ã¹ãã£ãåºåããããšã§ãåé¡ã解決ããããšãã§ããŸããã
pub fn show(&mut self) { let mut texture = self.renderer.create_texture_streaming(PixelFormatEnum::RGB24, (self.xsize as u32, self.ysize as u32)).unwrap(); texture.with_lock(None, |buffer: &mut [u8], pitch: usize| { for y in (0..self.ysize) { for x in (0..self.xsize) { let offset = y*pitch + x*3; let color = self.canvas[x][self.ysize - y - 1]; buffer[offset + 0] = (color >> (8*2)) as u8; buffer[offset + 1] = (color >> (8*1)) as u8; buffer[offset + 2] = color as u8; } } }).unwrap(); self.renderer.clear(); self.renderer.copy(&texture, None, Some(Rect::new_unwrap(0, 0, self.xsize as u32, self.ysize as u32))); self.renderer.present(); }
äžè¬ã«ãRustã®ããã°ã©ãã³ã°ã®èŠ³ç¹ããCanvasãæžãæããããšã«æ°ãããã®ã¯ãªãã£ãã®ã§ã話ãããšã¯ããŸããããŸããã ãªããžããªã®å¯Ÿå¿ããã¹ãããã·ã§ããã®ãã®æç¹ã®ã³ãŒãã ãããã®å€æŽã®åŸãããã°ã©ã ã¯é£ã³å§ããŸããã æç»ã«ã¯äžç¬ããããŸããã ãã§ã«ããã©ãŒãã³ã¹ã®æž¬å®ã«èå³ããªããªã£ãŠããŸãã ããã°ã©ã ã®å®è¡ã«ãããæéã¯éåžžã«çããããOSã®ã©ã³ãã ãªããã»ã¹ã«èµ·å ããåçŽãªæž¬å®ãšã©ãŒã¯ããã®æéã2åã«å¢ããããéã«æžããããšãã§ããŸãã ã©ãã«ãããŠãããšæŠãããã«ãããã°ã©ã ã®æ¬äœïŒ.objãã¡ã€ã«ã®èªã¿åããš2次å æ圱ã®èšç®ïŒã100åå®è¡ãããµã€ã¯ã«ã§å²ã¿ãŸããã ããã§ãäœãã枬å®ããããšãã§ããŸããã haqreuã® C ++å®è£ ã§ãåãããšãè¡ããŸãã ã
å®éãRustå®è£ ã®çªå·ã¯æ¬¡ã®ãšããã§ãã
cepreu@cepreu-P5K:~//rust-3d-renderer-70de52d8e8c82854c460a41d1b8d8decb0c2e5c1$ time ./rust_project real 0m0.769s user 0m0.630s sys 0m0.137s
C ++ã§ã®å®è£ çªå·ã¯æ¬¡ã®ãšããã§ãã
cepreu@cepreu-P5K:~//tinyrenderer-f6fecb7ad493264ecd15e230411bfb1cca539a12$ time ./a.out real 0m1.492s user 0m1.483s sys 0m0.008s
åããã°ã©ã ã10åå®è¡ããåŸãæé©ãªæéïŒå®éïŒãéžæããŸããã æã£ãŠããŸããã ç§ã®å®è£ ã§ã¯ãå€éšåŒã³åºããçµæã®æéã«åœ±é¿ãäžããªãããã«ãSDLãžã®ãã¹ãŠã®åç §ãåé€ããããã«ä¿®æ£ãå ããŸããã å®éã«ã¯ããªããžããªã®ã¹ãããã·ã§ããã§èŠãããšãã§ããŸã ã
C ++å®è£ ã«å¯ŸããŠè¡ã£ãå€æŽã¯æ¬¡ã®ãšããã§ãã
int main(int argc, char** argv) { for (int cycle=0; cycle<100; cycle++){ if (2==argc) { model = new Model(argv[1]); } else { model = new Model("obj/african_head.obj"); } TGAImage image(width, height, TGAImage::RGB); for (int i=0; i<model->nfaces(); i++) { std::vector<int> face = model->face(i); for (int j=0; j<3; j++) { Vec3f v0 = model->vert(face[j]); Vec3f v1 = model->vert(face[(j+1)%3]); int x0 = (v0.x+1.)*width/2.; int y0 = (v0.y+1.)*height/2.; int x1 = (v1.x+1.)*width/2.; int y1 = (v1.y+1.)*height/2.; line(x0, y0, x1, y1, image, white); } } delete model; } //image.flip_vertically(); // i want to have the origin at the left bottom corner of the image //image.write_tga_file("output.tga"); return 0; }
ãŸããmodel.cppã®ãããã°åºåãåé€ããŸããã äžè¬ã«ããã¡ãããçµæã¯ç§ãé©ãããŸããã Rustã³ã³ãã€ã©ã¯ãŸã gccã»ã©æé©åããå¿ èŠã¯ãªãããã«æãããŸããããç§ã¯ç¡ç¥ã§ãããããæé©ã§ãªãã³ãŒããç©ã¿äžããŠããŸãã...ãã®ã³ãŒãããªãé«éã«ãªã£ãã®ãç解ã§ããŸããã ãŸãã¯ãRustã¯éåžžã«é«éã§ãã ãŸãã¯ãC ++ã§ã¯ãå®è£ ã«æé©ãªãã®ããããŸããã äžè¬çã«ãããã«ã€ããŠè°è«ããã人ã¯ã³ã¡ã³ããæè¿ããŸãã
ãŸãšã
æåŸã«ãä¿æ°ãç°¡åã«èª¿æŽããããšã§ïŒ ãªããžããªã®ç»åãåç §ïŒããŠã£ã³ããŠã¹ããŒã¹ãæé©ã«å æãããã·ã³ã®ç»åãååŸããŸããã èšäºã®åé ã§ããã芳å¯ããŸããã
ããã€ãã®å°è±¡ïŒ
- Rustã§ã®æžã蟌ã¿ãç°¡åã«ãªããŸããã åæã¯ã³ã³ãã€ã©ãšã®ç¶ç¶çãªéäºã§ããã ä»ãç§ã¯ãã 座ã£ãŠã³ãŒããæžããŠããŸããæã ããããã©ããã£ãŠäœãããã€ã³ã¿ãŒãããã§èŠããŸãã äžè¬ã«ãã»ãšãã©ã®å Žåããã®èšèªã¯ãã§ã«éŠŽæã¿ã®ãããã®ãšããŠèªèãããŠããŸãã ã芧ã®ãšãããããã«ã¯ããã»ã©æéã¯ããããŸããã§ããã
- ã©ã¹ã¿ãèŠåããŠãŸã æºè¶³ããŠããŸãã ä»ã®èšèªã§ã¯ãéåžžã«é«åºŠãªIDEïŒJavaã®IntelliJ IDEAãªã©ïŒã®ã¿ãããªãã«äŒããŠãããšãã³ã³ãã€ã©ãŒã¯Rustã§è¿°ã¹ãŠããŸãã è¯ãã¹ã¿ã€ã«ãç¶æãããšã©ãŒããä¿è·ããŸãã
- Rustã®æ¹ãéãã£ããšããäºå®ã¯è¡æã§ãã ã©ããããã³ã³ãã€ã©ã¯æã£ãã»ã©çã£ãœããããŸããã
æçµ-ãµã€ã¯ã«ã®3çªç®ã®éšåïŒ ç°¡ç¥åãããOpenGLãRustã§æžã-ããŒã3ïŒã©ã¹ã¿ã©ã€ã¶ãŒïŒ