├── .gitignore
├── README.md
├── SDL2.dll
├── pi3d
├── .gitignore
├── Cargo.toml
├── build.rs
├── examples
│ ├── cities
│ │ ├── cities150.txt
│ │ ├── cities200.txt
│ │ ├── cities30.txt
│ │ ├── cities50.txt
│ │ └── cities80.txt
│ ├── ecubes
│ │ ├── License.txt
│ │ ├── README.TXT
│ │ ├── miramar_256_back.png
│ │ ├── miramar_256_bottom.png
│ │ ├── miramar_256_front.png
│ │ ├── miramar_256_left.png
│ │ ├── miramar_256_right.png
│ │ ├── miramar_256_top.png
│ │ ├── sbox_back.jpg
│ │ ├── sbox_bottom.jpg
│ │ ├── sbox_front.jpg
│ │ ├── sbox_left.jpg
│ │ ├── sbox_right.jpg
│ │ └── sbox_top.jpg
│ ├── farris.rs
│ ├── fonts
│ │ ├── NotoSans-Regular.ttf
│ │ ├── NotoSerif-Regular.ttf
│ │ └── Str437.ttf
│ ├── forest_walk.rs
│ ├── game.rs
│ ├── minimal.rs
│ ├── models
│ │ ├── CargoHoldBaked2.mtl
│ │ ├── CargoHoldBaked2.obj
│ │ ├── CargoHold_CollisionBig.obj
│ │ ├── Raspi256x256.png
│ │ ├── biplane.mtl
│ │ ├── biplane.obj
│ │ ├── biplane1.jpg
│ │ ├── earthskybox.mtl
│ │ ├── earthskybox.obj
│ │ ├── iss.mtl
│ │ ├── iss.obj
│ │ ├── leeds_raspberry_jam02c.png
│ │ ├── maps
│ │ │ ├── ChevronsCompleteMap.jpg
│ │ │ ├── MedMon1.png
│ │ │ ├── ashphalt.jpg
│ │ │ ├── barriersCompleteMap.jpg
│ │ │ ├── bluealum.jpg
│ │ │ ├── bluealumCompleteMap.jpg
│ │ │ ├── blueglow.png
│ │ │ ├── bodyCompleteMap.jpg
│ │ │ ├── fx3_Panels.png
│ │ │ ├── panelCompleteMap.png
│ │ │ ├── radar.png
│ │ │ ├── red.png
│ │ │ ├── rodsCompleteMap.png
│ │ │ ├── sbox_512_back.png
│ │ │ ├── sbox_512_bottom.png
│ │ │ ├── sbox_512_front.png
│ │ │ ├── sbox_512_left.png
│ │ │ ├── sbox_512_right.png
│ │ │ ├── sbox_512_top.png
│ │ │ ├── stripsCompleteMap.jpg
│ │ │ ├── walkplate.png
│ │ │ ├── walkwaysCompleteMap.jpg
│ │ │ └── white.png
│ │ ├── pi3d.mtl
│ │ ├── pi3d.obj
│ │ ├── pi3d_old.mtl
│ │ ├── pi3d_old.obj
│ │ ├── rust_pi3d.mtl
│ │ ├── rust_pi3d.obj
│ │ └── sphere.obj
│ ├── picture_frame.rs
│ ├── shader_in_src.rs
│ ├── shaders
│ │ ├── blend_new.fs
│ │ ├── blend_new.vs
│ │ ├── farris_p67.fs
│ │ ├── farris_p67.vs
│ │ ├── farris_p67a.fs
│ │ ├── farris_p67a.vs
│ │ ├── farris_p67b.fs
│ │ ├── farris_p67b.vs
│ │ ├── farris_p67b_ES30.fs
│ │ ├── farris_p67b_ES30.vs
│ │ ├── farris_p6_6term.fs
│ │ ├── farris_p6_6term.vs
│ │ ├── triangle.fs
│ │ ├── triangle.vs
│ │ ├── uv_flat_ES30.fs
│ │ ├── uv_flat_ES30.vs
│ │ ├── uv_light.fs
│ │ ├── uv_light.vs
│ │ ├── uv_pointsprite_ES30.fs
│ │ └── uv_pointsprite_ES30.vs
│ ├── ship_demo.rs
│ ├── textures
│ │ ├── floor_nm.jpg
│ │ ├── grasstile_n.jpg
│ │ ├── hornbeam2.png
│ │ ├── mountains3_512.jpg
│ │ ├── mountainsHgt.png
│ │ ├── pattern.png
│ │ ├── poppy1.jpg
│ │ ├── stars.jpg
│ │ ├── tree1.png
│ │ └── tree2.png
│ └── tsp.rs
└── src
│ ├── buffer.rs
│ ├── camera.rs
│ ├── display.rs
│ ├── lib.rs
│ ├── light.rs
│ ├── shader.rs
│ ├── shaders
│ ├── built_in_shaders.rs
│ └── mod.rs
│ ├── shape.rs
│ ├── shapes
│ ├── cone.rs
│ ├── cuboid.rs
│ ├── cylinder.rs
│ ├── elevation_map.rs
│ ├── environment_cube.rs
│ ├── lathe.rs
│ ├── lines.rs
│ ├── merge_shape.rs
│ ├── mod.rs
│ ├── model_obj.rs
│ ├── plane.rs
│ ├── point_text.rs
│ ├── points.rs
│ ├── sphere.rs
│ ├── string.rs
│ ├── tcone.rs
│ ├── torus.rs
│ └── tube.rs
│ ├── texture.rs
│ └── util
│ ├── font.rs
│ ├── mod.rs
│ ├── offscreen_texture.rs
│ ├── post_process.rs
│ ├── resources.rs
│ ├── vec3.rs
│ └── vec4.rs
├── pyo3_module
├── Cargo.lock
├── Cargo.toml
├── README.md
├── setup.py
├── src
│ ├── core.rs
│ ├── lib.rs
│ ├── shapes.rs
│ └── util.rs
└── test
│ ├── NotoSerif-Regular.ttf
│ ├── floor_nm.jpg
│ ├── hornbeam2.png
│ ├── mountains3_512.jpg
│ ├── mountainsHgt.png
│ ├── pattern.png
│ ├── rpi3d.cpython-37m-arm-linux-gnueabihf.so
│ ├── rust_pi3d.mtl
│ ├── rust_pi3d.obj
│ ├── sbox_back.jpg
│ ├── sbox_bottom.jpg
│ ├── sbox_front.jpg
│ ├── sbox_left.jpg
│ ├── sbox_right.jpg
│ ├── sbox_top.jpg
│ ├── test1.py
│ ├── test2.py
│ └── test3.py
└── rust_pi3d.png
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | /target
3 | **/*.rs.bk
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # rust_pi3d
2 | translation of pi3d from python to rust
3 |
4 |
5 |
6 | Following parts of the tutorial:
7 | http://nercury.github.io/rust/opengl/tutorial/2018/02/08/opengl-in-rust-from-scratch-01-window.html
8 | I have started the process of making a rust version of the python pi3d
9 | module.
10 |
11 | As at commit 12c692f most of the functionality is in place to get demos such
12 | as ForestWalk working.
13 |
14 | *Installation*
15 |
16 | For this to work you need to install rust. Basically follow the instructions
17 | here https://www.rust-lang.org/en-US/install.html It seems to be reasonably
18 | fool proof though I've not tried it on Windows yet.
19 |
20 | You also need to have SDL2 running. On linux it's pretty easy using
21 |
22 | ```sh
23 | patrick@thiscomputer:~/rust/rust_pi3d$ sudo apt-get install libsdl2-dev
24 | ```
25 |
26 | See the tutorial link at the top or the rust sdl2 crate site for what to
27 | do for windows i.e. put the dll in the same folder as the exectuable.
28 | PS I have added the SDL2.dll v2.28.3-win32-x64 but you should
29 | download and install the one appropriate for your windows and machine.
30 |
31 | Then in the terminal navigate to wherever you cloned or extracted this
32 | repo and build the executables using cargo, and run them like this (NB
33 | now cd to the pi3d directory):
34 |
35 | ```sh
36 | patrick@thiscomputer:~/rust/rust_pi3d/pi3d$ cargo build --examples --release
37 | ```
38 | then
39 | ```
40 | patrick@thiscomputer:~/rust/rust_pi3d/pi3d$ target/release/examples/game
41 | patrick@thiscomputer:~/rust/rust_pi3d/pi3d$ target/release/examples/forest_walk
42 | ```
43 | you only have to do the initial build once as this runs the build.rs script
44 | that copies over the examples dependencies. After that you can run examples using.
45 | ```
46 | patrick@thiscomputer:~/rust/rust_pi3d/pi3d$ cargo run --example game --release
47 | ```
48 | and all the source will be checked and recompiled as required.
49 |
50 | Building for release will take longer (maybe) and exclude debugging symbols etc but
51 | run faster (obviously) and will be much smaller. If you want to build for
52 | debug (probably sensible) exclude the `--release`. However if you do this
53 | the required support files in `target/release/textures`, `models`, `ecubes`
54 | and `fonts` will have to be copied into the `target/debug/` directory.
55 |
56 | On the Raspberry Pi the OpenGL used by default SDL2 won't work unless you use
57 | raspi-config and switch the graphics driver to the new experimental one.
58 | It should be possible to compile SDL2 to use the built in Broadcom drivers
59 | but I've not tried that. (Let me know if you do and what the problems are).
60 |
61 | TODO::
62 |
63 | ~~installation, requirements and compile instructions on here!~~
64 |
65 | ~~build script to copy support files (images, models, fonts etc) to target
66 | directory~~
67 |
68 | ~~Fonts and lettering.~~
69 |
70 | error and failure handling. Many functions need to return a Result<..>
71 | wrapper around whatever they are supposed to do.
72 |
73 | ~~Texture blender option (lower alpha to drop pixel)~~
74 |
75 | Find out why last value of array_buffer is always set to zero (i.e.
76 | why a sacrificial extra one needs to be added)
77 |
78 | Mouse buttons
79 |
80 | Offscreen textures, screen capture and post processing
81 |
82 | Lifetimes and controlled deletion of Shaders and Programs.
83 |
84 | More elaborate Camera functions.
85 |
86 | Other Texture types i.e. different internal storage modes supported
87 | by OpenGL
88 |
89 | **As at 16 Dec 19 there are some trials making a python wrapper**
90 |
91 | *see pyo3_module directory*
--------------------------------------------------------------------------------
/SDL2.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/SDL2.dll
--------------------------------------------------------------------------------
/pi3d/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | /target
3 | **/*.rs.bk
4 | Cargo.lock
5 |
--------------------------------------------------------------------------------
/pi3d/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | edition = "2024"
3 | name = "pi3d"
4 | version = "0.2.0"
5 | authors = ["paddywwof "]
6 | build = "build.rs"
7 |
8 | [dependencies]
9 | sdl2 = "^0.32.0"
10 | gl = "^0.10"
11 | ndarray = "0.16"
12 | image = "0.21.3"
13 | rand = "^0.6.5"
14 | rusttype = "0.6"
15 | lazy_static = "^1.4"
16 |
17 | [build-dependencies]
18 | fs_extra = "^1.1"
19 |
20 | [profile.release]
21 | codegen-units = 1
22 | incremental = true
23 |
--------------------------------------------------------------------------------
/pi3d/build.rs:
--------------------------------------------------------------------------------
1 | extern crate fs_extra;
2 |
3 | use std::env;
4 |
5 | fn main() {
6 | let host_triple = env::var("HOST").unwrap();
7 | let targ_triple = env::var("TARGET").unwrap();
8 | let target_dir = if targ_triple == host_triple {
9 | "".to_string()
10 | } else {
11 | format!("{}/", targ_triple)
12 | };
13 | let profile = env::var("PROFILE").unwrap(); //ie debug or release
14 | let out_dir = format!("target/{}{}/examples", target_dir, profile);
15 | println!("this out_dir={:?}", out_dir);
16 | let mut options = fs_extra::dir::CopyOptions::new();
17 | options.overwrite = true;
18 |
19 | let mut from_paths = vec![
20 | "examples/textures",
21 | "examples/shaders",
22 | "examples/models",
23 | "examples/fonts",
24 | "examples/ecubes",
25 | "examples/cities",
26 | ];
27 | if targ_triple.find("windows") != None {
28 | // will need dll for windows
29 | from_paths.push("../SDL2.dll");
30 | }
31 | println!("{:?}", from_paths);
32 | fs_extra::copy_items(&from_paths, &out_dir, &options).unwrap();
33 | }
34 |
--------------------------------------------------------------------------------
/pi3d/examples/cities/cities150.txt:
--------------------------------------------------------------------------------
1 | -392.4,423.1
2 | 85.7,-207.2
3 | -294.4,-78.7
4 | -240.5,-48.5
5 | 21.7,94.8
6 | -379.5,-0.9
7 | -50.9,316.9
8 | -420.5,20.2
9 | -184.3,-37.6
10 | 297.6,-31.3
11 | -131.5,-134.9
12 | -223.1,-30.6
13 | -298.0,211.7
14 | 368.1,118.8
15 | 271.8,-327.7
16 | -98.5,44.1
17 | 439.5,284.9
18 | 2.2,-260.7
19 | 219.7,-209.7
20 | -249.4,294.9
21 | 371.7,405.4
22 | -318.8,-138.1
23 | -160.0,365.9
24 | 87.3,-319.0
25 | -315.9,335.1
26 | -218.2,-362.7
27 | 24.3,285.3
28 | 92.0,166.2
29 | 230.7,212.9
30 | 239.1,336.2
31 | 79.5,221.6
32 | 10.1,407.5
33 | -177.7,219.3
34 | -237.9,318.3
35 | 318.0,176.1
36 | -222.0,-5.1
37 | -365.2,-199.6
38 | 187.2,-265.6
39 | 100.8,-282.3
40 | 37.9,76.7
41 | -249.6,367.6
42 | 104.9,109.7
43 | -237.0,391.1
44 | 397.9,96.7
45 | -402.7,-116.7
46 | -301.6,361.7
47 | 39.4,-78.1
48 | -319.0,18.5
49 | 200.7,173.9
50 | -290.3,54.6
51 | 311.0,-135.3
52 | -324.9,4.1
53 | -28.8,1.1
54 | 417.4,361.9
55 | -58.5,295.2
56 | -336.9,340.3
57 | -447.2,-421.5
58 | -264.5,-189.1
59 | 48.9,293.4
60 | -218.2,166.2
61 | -165.9,120.6
62 | 15.9,164.3
63 | 243.9,446.5
64 | 118.5,256.3
65 | 158.4,223.9
66 | 330.8,-347.9
67 | -72.5,169.3
68 | -417.3,-428.2
69 | -75.0,-55.6
70 | 109.7,418.0
71 | 47.6,115.8
72 | -359.5,37.8
73 | 149.1,18.0
74 | 427.4,-219.9
75 | 59.3,158.7
76 | 433.5,-289.8
77 | 55.3,244.7
78 | 352.0,3.1
79 | -109.6,-124.6
80 | 435.3,325.0
81 | -125.0,149.6
82 | 427.8,99.9
83 | -430.8,32.9
84 | 176.1,393.6
85 | -223.8,401.4
86 | 208.4,113.2
87 | 50.3,310.4
88 | 365.8,-381.0
89 | 148.5,167.7
90 | -48.8,-285.2
91 | 26.4,-273.6
92 | -349.0,312.4
93 | 55.6,312.0
94 | 394.0,-174.7
95 | -339.5,-408.2
96 | -65.5,387.0
97 | 304.8,-360.3
98 | 55.6,-270.2
99 | -336.1,235.7
100 | -21.5,-148.4
101 | 353.2,100.8
102 | -355.0,427.4
103 | -74.7,-382.1
104 | -400.9,-14.4
105 | -156.2,-113.7
106 | -125.9,-178.8
107 | -247.4,-176.2
108 | 25.0,231.7
109 | 28.9,-29.4
110 | 223.4,94.7
111 | -292.1,388.6
112 | -343.1,-296.5
113 | 378.3,-407.0
114 | -408.1,365.6
115 | -444.2,-181.1
116 | -109.7,107.1
117 | -263.7,116.6
118 | 97.6,-418.6
119 | -444.2,-15.6
120 | 104.7,172.0
121 | 263.3,58.3
122 | 133.9,-411.4
123 | -203.8,-223.5
124 | -253.2,360.7
125 | 185.9,275.7
126 | -247.5,411.4
127 | 123.0,421.9
128 | -303.3,-187.0
129 | 194.3,-49.7
130 | -178.1,268.2
131 | -407.2,322.0
132 | -229.2,-51.1
133 | 352.5,421.5
134 | 374.2,18.3
135 | -45.1,-289.0
136 | 415.9,-79.3
137 | 381.9,-343.7
138 | 192.7,382.2
139 | -177.6,142.8
140 | 402.9,-0.2
141 | 438.1,291.2
142 | -193.2,6.7
143 | -146.0,301.3
144 | -382.2,-66.1
145 | 248.5,410.7
146 | -270.5,-99.6
147 | 97.1,171.7
148 | 409.3,-259.0
149 | 432.3,118.2
150 | -415.7,-439.2
151 |
152 |
153 |
--------------------------------------------------------------------------------
/pi3d/examples/cities/cities200.txt:
--------------------------------------------------------------------------------
1 | -390.7,-319.6
2 | 273.8,-224.6
3 | -90.2,-122.6
4 | 6.8,330.5
5 | 35.5,-64.8
6 | 155.5,-17.4
7 | -96.9,-77.3
8 | -201.0,219.4
9 | -40.6,121.9
10 | 319.6,162.5
11 | -242.6,-380.2
12 | -298.1,-61.9
13 | -352.4,202.0
14 | 293.3,307.0
15 | -246.2,354.9
16 | -185.8,31.0
17 | -334.8,202.5
18 | 95.3,0.6
19 | 141.8,-222.7
20 | -261.6,-87.5
21 | -18.9,161.7
22 | -377.3,-91.3
23 | 186.6,-378.0
24 | -61.7,91.0
25 | 327.7,-6.7
26 | 3.5,123.6
27 | 166.2,-317.8
28 | 91.9,-125.4
29 | 107.0,-80.4
30 | 227.9,213.7
31 | 43.5,-111.7
32 | 150.7,-165.1
33 | 348.2,-192.0
34 | -312.5,-313.5
35 | -28.8,-20.3
36 | -217.5,-182.2
37 | -367.8,377.2
38 | -277.5,93.7
39 | 309.9,-94.9
40 | 350.0,288.3
41 | -363.3,-203.7
42 | -190.0,305.9
43 | 139.5,373.9
44 | 51.6,-349.5
45 | 247.4,100.1
46 | 243.6,-265.1
47 | 39.6,49.1
48 | 320.2,-25.6
49 | -77.6,-191.7
50 | 214.3,-211.9
51 | 330.2,-269.4
52 | 187.2,75.4
53 | -241.9,-204.2
54 | 262.5,98.2
55 | -40.9,-203.7
56 | -52.2,-300.6
57 | 94.8,323.8
58 | -317.9,-257.8
59 | -57.2,-234.7
60 | -59.2,318.3
61 | 162.8,121.6
62 | 202.3,-291.3
63 | 47.7,319.7
64 | 283.0,-239.3
65 | 49.9,223.8
66 | -232.8,-175.7
67 | 277.4,30.7
68 | 176.9,-143.4
69 | -342.0,-114.8
70 | -55.3,9.1
71 | 62.1,371.2
72 | -75.2,247.3
73 | -43.1,238.6
74 | -17.3,197.3
75 | -263.1,293.4
76 | 282.6,157.8
77 | 347.3,278.2
78 | -341.6,-212.1
79 | 270.1,-346.6
80 | 231.2,-112.5
81 | 90.8,373.0
82 | 88.0,-9.5
83 | -109.7,30.0
84 | 284.5,-275.9
85 | 305.4,-355.8
86 | -18.0,-98.8
87 | -270.3,-112.0
88 | -197.8,281.3
89 | -360.5,378.3
90 | -335.5,348.7
91 | 41.2,262.8
92 | 103.8,-92.5
93 | -213.3,128.0
94 | 90.6,-227.7
95 | -56.9,-162.7
96 | -360.3,247.9
97 | 368.2,-175.4
98 | 26.8,-242.8
99 | -22.4,-180.5
100 | 325.2,-15.5
101 | -303.4,-103.3
102 | -233.1,54.1
103 | 171.6,-375.4
104 | -195.1,-306.1
105 | -168.5,-172.4
106 | 5.5,-341.8
107 | -127.1,-57.4
108 | -321.2,-266.9
109 | -287.3,339.9
110 | -286.1,113.7
111 | 309.7,162.2
112 | -311.0,-79.2
113 | -38.3,215.9
114 | -180.3,275.5
115 | -198.1,-53.4
116 | 277.9,111.2
117 | 18.1,-192.3
118 | 209.6,142.9
119 | -111.1,208.5
120 | -339.8,-51.0
121 | 233.2,-219.5
122 | 38.6,-179.5
123 | -322.6,268.3
124 | -324.8,-42.9
125 | 295.9,35.9
126 | 223.7,37.3
127 | -49.4,-64.8
128 | -358.0,-272.4
129 | -282.0,165.3
130 | 292.7,5.7
131 | -146.5,-191.1
132 | 213.0,384.9
133 | -371.0,-371.2
134 | -215.2,182.1
135 | 104.9,-391.8
136 | -60.5,-103.7
137 | -114.4,332.9
138 | 152.4,-107.3
139 | 31.3,106.4
140 | 291.8,-268.6
141 | 201.4,300.1
142 | -133.5,-233.3
143 | -332.9,363.1
144 | -107.1,-34.4
145 | -318.0,20.6
146 | 190.0,385.9
147 | 153.2,-124.8
148 | -320.6,345.9
149 | -293.8,-313.1
150 | -335.2,54.3
151 | 33.2,348.6
152 | 284.5,-95.3
153 | 202.2,108.9
154 | -215.2,373.0
155 | 104.8,319.1
156 | 361.0,359.2
157 | 306.6,348.5
158 | 119.1,103.6
159 | -273.7,243.8
160 | -287.4,-247.2
161 | -134.4,213.2
162 | -279.6,339.7
163 | 94.3,-251.0
164 | -391.9,115.7
165 | -165.2,-56.3
166 | -281.9,14.7
167 | 116.0,17.2
168 | 53.5,-349.0
169 | -384.9,377.6
170 | -200.3,-356.1
171 | -305.4,-147.1
172 | -53.0,-152.5
173 | 118.9,-23.0
174 | -316.7,-347.1
175 | 17.6,53.0
176 | -73.3,244.5
177 | -143.9,-49.2
178 | -228.1,78.3
179 | 333.9,50.2
180 | 281.9,340.3
181 | 187.5,-144.7
182 | -258.1,36.3
183 | 96.8,339.6
184 | -274.7,-6.2
185 | 321.6,-144.8
186 | -96.4,-88.6
187 | 125.9,-286.9
188 | 367.2,302.5
189 | -36.5,372.3
190 | -206.3,-28.7
191 | 135.0,-243.3
192 | 87.1,94.6
193 | 47.0,167.6
194 | -121.1,272.4
195 | 390.9,145.1
196 | -322.8,366.8
197 | 79.9,-223.4
198 | 366.4,0.9
199 | -277.2,26.2
200 | 329.5,-226.1
--------------------------------------------------------------------------------
/pi3d/examples/cities/cities30.txt:
--------------------------------------------------------------------------------
1 | -203.9,342.7
2 | 162.3,-101.4
3 | 213.2,-149.7
4 | 296.8,29.9
5 | -113.3,321.2
6 | 382.8,-348.6
7 | -154.7,154.4
8 | 56.0,266.7
9 | 121.4,98.3
10 | -71.1,-39.0
11 | 224.8,-40.4
12 | 49.2,-48.1
13 | -146.9,190.1
14 | 145.4,0.7
15 | 305.6,-424.7
16 | -204.1,-92.6
17 | -199.7,-366.6
18 | 417.6,250.3
19 | -87.8,-0.6
20 | 285.2,216.2
21 | -328.5,422.5
22 | -139.0,-398.6
23 | 67.6,-62.5
24 | 8.2,437.4
25 | 280.4,-448.7
26 | 202.5,-178.4
27 | -55.8,115.5
28 | -424.1,-20.0
29 | -83.2,-81.1
30 | -327.6,76.2
31 |
32 |
--------------------------------------------------------------------------------
/pi3d/examples/cities/cities50.txt:
--------------------------------------------------------------------------------
1 | -235.6,254.6
2 | -286.8,-420.9
3 | -125.3,47.5
4 | 23.4,97.1
5 | -361.2,-432.5
6 | -343.5,221.2
7 | -238.0,-322.2
8 | 308.5,-93.6
9 | -254.3,-92.4
10 | -242.8,-291.7
11 | -281.7,108.6
12 | -204.7,-366.7
13 | -115.2,298.2
14 | -365.9,208.2
15 | 443.6,111.1
16 | 405.6,-192.0
17 | -111.0,-195.3
18 | -33.2,-140.4
19 | 215.1,-84.9
20 | -243.4,410.9
21 | -407.6,-159.4
22 | 392.7,346.0
23 | 429.0,-170.4
24 | 217.6,310.0
25 | 204.5,294.6
26 | -224.8,-86.4
27 | 198.1,-397.2
28 | -249.5,198.5
29 | -10.1,274.2
30 | 428.4,-138.0
31 | -265.9,110.0
32 | -147.4,-264.3
33 | -439.2,293.7
34 | 121.6,187.6
35 | 372.9,-209.9
36 | -331.9,-110.5
37 | -269.2,112.8
38 | 408.7,308.7
39 | -32.9,-197.7
40 | -231.4,-423.3
41 | -90.8,-209.8
42 | -358.4,-151.0
43 | -26.1,-5.3
44 | -80.6,121.2
45 | -52.6,-113.9
46 | 82.7,190.9
47 | -397.1,125.4
48 | -182.0,151.1
49 | -10.7,393.9
50 | 377.7,-85.8
51 |
52 |
--------------------------------------------------------------------------------
/pi3d/examples/cities/cities80.txt:
--------------------------------------------------------------------------------
1 | 295.00,198.00
2 | 153.00,-365.00
3 | 169.00,306.00
4 | 26.00,59.00
5 | 94.00,-49.00
6 | -142.00,-95.00
7 | 335.00,154.00
8 | -168.00,78.00
9 | -113.00,-149.00
10 | 256.00,173.00
11 | -231.00,128.00
12 | 164.00,335.00
13 | 252.00,-250.00
14 | -248.00,-340.00
15 | -87.00,-18.00
16 | -159.00,-236.00
17 | 361.00,-196.00
18 | -65.00,162.00
19 | -326.00,167.00
20 | -129.00,-210.00
21 | -172.00,364.00
22 | 28.00,-229.00
23 | -270.00,37.00
24 | -144.00,361.00
25 | -262.00,-281.00
26 | 321.00,-232.00
27 | 381.00,230.00
28 | -56.00,94.00
29 | 187.00,164.00
30 | 353.00,-99.00
31 | 251.30,-247.70
32 | -284.00,201.70
33 | -25.70,24.60
34 | -121.00,170.70
35 | 76.70,-102.70
36 | -133.30,-143.60
37 | -140.00,123.50
38 | 28.50,-25.00
39 | -332.00,-58.90
40 | 178.20,283.10
41 | -211.10,-60.40
42 | -171.80,-239.80
43 | -189.50,-116.80
44 | 190.30,237.50
45 | 93.50,171.60
46 | -359.20,-101.30
47 | -289.40,-73.30
48 | -274.20,-254.00
49 | 86.80,142.90
50 | -318.70,31.80
51 | 126.90,292.50
52 | 115.00,-56.70
53 | 40.50,254.60
54 | 1.40,321.20
55 | 13.10,-21.20
56 | 13.70,365.60
57 | 277.10,-216.90
58 | 35.30,-44.50
59 | 162.70,38.00
60 | 76.10,12.70
61 | -112.30,-84.40
62 | 265.00,78.60
63 | -115.30,-81.30
64 | -338.20,75.80
65 | 132.60,154.90
66 | -235.10,18.70
67 | 60.80,-276.00
68 | 168.60,303.50
69 | 87.60,242.40
70 | 92.60,-211.60
71 | 99.90,281.70
72 | 226.70,-97.20
73 | -182.40,199.20
74 | -193.80,41.10
75 | 162.70,361.90
76 | 223.60,-200.00
77 | 68.80,171.70
78 | 145.10,-255.60
79 | -150.40,177.20
80 | 97.70,-213.20
81 |
82 |
--------------------------------------------------------------------------------
/pi3d/examples/ecubes/License.txt:
--------------------------------------------------------------------------------
1 | Sincere thank you to Jockum Skoglund aka 'hipshot' who created these fantastic environment cubes; Miramar, Grimmnight, interstellar, stormydays and violentday under the following licence: "Modify however you like, just cred me for my work, maybe link to my page".
2 |
3 | The textures are available here: http://www.zfight.com/misc/images/textures/envmaps/
4 |
5 | and
6 |
7 | http://www.zfight.com/misc/files/textures/
8 |
--------------------------------------------------------------------------------
/pi3d/examples/ecubes/README.TXT:
--------------------------------------------------------------------------------
1 | THIS SKY WAS UPDATED AT THE 27TH
2 | THE ORIG HAD SOME ERRORS
3 |
4 | MIRAMAR
5 | high res 1024^2 environment map
6 | ships as TGA.
7 |
8 |
9 | By Jockum Skoglund aka hipshot
10 | hipshot@zfight.com
11 | www.zfight.com
12 | Stockholm, 2005 08 25
13 |
14 |
15 | Modify however you like, just cred me for my work, maybe link to my page.
16 |
--------------------------------------------------------------------------------
/pi3d/examples/ecubes/miramar_256_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/ecubes/miramar_256_back.png
--------------------------------------------------------------------------------
/pi3d/examples/ecubes/miramar_256_bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/ecubes/miramar_256_bottom.png
--------------------------------------------------------------------------------
/pi3d/examples/ecubes/miramar_256_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/ecubes/miramar_256_front.png
--------------------------------------------------------------------------------
/pi3d/examples/ecubes/miramar_256_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/ecubes/miramar_256_left.png
--------------------------------------------------------------------------------
/pi3d/examples/ecubes/miramar_256_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/ecubes/miramar_256_right.png
--------------------------------------------------------------------------------
/pi3d/examples/ecubes/miramar_256_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/ecubes/miramar_256_top.png
--------------------------------------------------------------------------------
/pi3d/examples/ecubes/sbox_back.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/ecubes/sbox_back.jpg
--------------------------------------------------------------------------------
/pi3d/examples/ecubes/sbox_bottom.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/ecubes/sbox_bottom.jpg
--------------------------------------------------------------------------------
/pi3d/examples/ecubes/sbox_front.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/ecubes/sbox_front.jpg
--------------------------------------------------------------------------------
/pi3d/examples/ecubes/sbox_left.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/ecubes/sbox_left.jpg
--------------------------------------------------------------------------------
/pi3d/examples/ecubes/sbox_right.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/ecubes/sbox_right.jpg
--------------------------------------------------------------------------------
/pi3d/examples/ecubes/sbox_top.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/ecubes/sbox_top.jpg
--------------------------------------------------------------------------------
/pi3d/examples/farris.rs:
--------------------------------------------------------------------------------
1 | extern crate pi3d;
2 | extern crate sdl2;
3 | use sdl2::keyboard::Keycode;
4 |
5 | const W: f32 = 1200.0;
6 | const H: f32 = 720.0;
7 | const UNIF_OFFSET: usize = 11; // first unused row of unif
8 | const PARAMS: &[[f32; 3]; 8] = &[
9 | [1.0, 4.0, -0.2],
10 | [0.2, -5.0, -2.0],
11 | [
12 | 0.1, 0.2, //L-n1,m1,ar1,ai1,n2,m2,ar2,ai2
13 | 1.0,
14 | ],
15 | [4.0, -0.2, 0.2],
16 | [-5.0, -2.0, 0.1],
17 | [
18 | 0.2, //L-n3,m3,ar3,ai3 R-n1,m1,ar1,ai1
19 | 1.0, 0.0,
20 | ],
21 | [0.0, 0.0, 0.0],
22 | [0.0, 0.0, 0.0],
23 | ]; //R-n2,n2,m2,ar2,ai2,n3,m3,ar3,ai3
24 |
25 | fn reset_params(obj: &mut pi3d::shape::Shape) {
26 | for i in 0..PARAMS.len() {
27 | for j in 0..3 {
28 | obj.unif[[UNIF_OFFSET + i, j]] = PARAMS[i][j];
29 | }
30 | }
31 | }
32 |
33 | fn main() {
34 | // setup display
35 | let mut display = pi3d::display::create("Farris page 67", W, H, "GL", 2, 1).unwrap();
36 | display.set_background(&[0.1, 0.1, 0.2, 1.0]);
37 | display.set_mouse_relative(true);
38 | display.set_target_fps(1000.0);
39 |
40 | // shaders
41 | let shader = pi3d::shader::Program::from_res("shaders/farris_p67b").unwrap();
42 | let textsh = pi3d::shader::Program::from_res("uv_pointsprite").unwrap();
43 | //let shader = pi3d::shader::Program::from_res("shaders/farris_p67b_ES30").unwrap();
44 | //let textsh = pi3d::shader::Program::from_res("shaders/uv_pointsprite_ES30").unwrap();
45 |
46 | // cameras
47 | let mut camera = pi3d::camera::create(&display);
48 | let mut camera2d = pi3d::camera::create(&display);
49 | camera2d.set_3d(false);
50 |
51 | // textures
52 | let tex = pi3d::texture::create_from_file("textures/poppy1.jpg");
53 |
54 | // cube
55 | let mut cube =
56 | pi3d::shapes::cuboid::create(camera.reference(), 10.0, 10.0, 10.0, 1.0, 1.0, 1.0);
57 | cube.set_draw_details(&shader, &vec![tex.id], 1.0, 0.0, 0.1, 0.1, 0.0);
58 | cube.position_z(50.0);
59 | cube.buf[0].unib[[3, 0]] = 0.05;
60 |
61 | // plane
62 | let mut plane = pi3d::shapes::plane::create(camera2d.reference(), W, H);
63 | plane.set_draw_details(&shader, &vec![tex.id], 1.0, 0.0, 0.1, 0.1, 0.0);
64 | plane.position_z(9900.0);
65 | plane.buf[0].unib[[3, 0]] = 0.05;
66 |
67 | reset_params(&mut cube);
68 | reset_params(&mut plane);
69 |
70 | // fps counter
71 | let font = pi3d::util::font::create("fonts/NotoSans-Regular.ttf", "", "", 64.0);
72 | let mut fps_text = pi3d::shapes::point_text::create(camera2d.reference(), &font, 20, 24.0);
73 | fps_text.set_shader(&textsh);
74 | let fps_blk = fps_text.add_text_block(
75 | &font,
76 | &[-W * 0.5 + 20.0, -H * 0.5 + 20.0, 0.1],
77 | 19,
78 | "00.0 FPS",
79 | );
80 |
81 | let mut x: f32 = 0.0;
82 | let mut y: f32 = 0.0;
83 | let mut z: f32 = -0.1;
84 | let mut df: f32 = 0.01; // for/aft
85 | let mut ds: f32 = 0.0; // side/side
86 | let mut rot: f32 = 0.0;
87 | let mut tilt: f32 = 0.0;
88 | let mut fr_num: u32 = 0;
89 | let mut param_point: usize = 0;
90 |
91 | while display.loop_running() {
92 | fr_num += 1;
93 | if fr_num > 2000 {
94 | // this changes which parameter to alter
95 | fr_num = 0;
96 | param_point += 1;
97 | if param_point >= (17) {
98 | param_point = 0;
99 | }
100 | }
101 | cube.draw();
102 | plane.draw();
103 | if x.abs() > 300.0 { // draw tiled maps
104 | //TODO some kind of navigation
105 | }
106 | if z.abs() > 300.0 {
107 | //TODO
108 | }
109 | fps_text.set_text(&font, fps_blk, &format!("{:5.1} FPS", display.fps()));
110 | fps_text.draw();
111 |
112 | if display.keys_pressed.contains(&Keycode::Escape) {
113 | break;
114 | }
115 | if display.mouse_moved {
116 | tilt = display.mouse_y as f32 * -0.004;
117 | rot = display.mouse_x as f32 * -0.004;
118 | }
119 |
120 | if display.keys_pressed.contains(&Keycode::W) {
121 | df = 0.2
122 | }
123 | if display.keys_pressed.contains(&Keycode::S) {
124 | df = -0.15;
125 | }
126 | if display.keys_pressed.contains(&Keycode::A) {
127 | ds = 0.15;
128 | }
129 | if display.keys_pressed.contains(&Keycode::D) {
130 | ds = -0.15;
131 | }
132 | if display.keys_pressed.contains(&Keycode::R) {
133 | reset_params(&mut cube);
134 | reset_params(&mut plane);
135 | }
136 | let cd = camera.get_direction();
137 | let dx = cd[0] * df - cd[2] * ds;
138 | x += dx;
139 | y += cd[1] * df;
140 | let dz = cd[2] * df + cd[0] * ds;
141 | z += dz;
142 | camera.reset();
143 | camera.rotate(&[tilt, rot, 0.0]);
144 | if ds != 0.0 || df != 0.0 {
145 | camera.position(&[x, y, z]);
146 | let param_r = param_point / 3;
147 | let param_c = param_point - (param_r * 3);
148 | cube.unif[[param_r + UNIF_OFFSET, param_c]] += dx * 0.1;
149 | plane.unif[[param_r + UNIF_OFFSET, param_c]] += dx * 0.1;
150 | let o_param_point = (param_point + 8) % 16; // modulus keep in range
151 | let param_r = o_param_point / 3;
152 | let param_c = o_param_point - (param_r * 3);
153 | cube.unif[[param_r + UNIF_OFFSET, param_c]] += dz * 0.1;
154 | plane.unif[[param_r + UNIF_OFFSET, param_c]] += dz * 0.1;
155 | //println!("{},{},{}", param_r, param_c, plane.unif[[param_r + UNIF_OFFSET, param_c]])
156 | }
157 | //cube.unif[[16, 1]] = fr_num as f32 * 0.001571;
158 | //plane.unif[[16, 1]] = fr_num as f32 * 0.001571;
159 | df = 0.0;
160 | ds = 0.0;
161 |
162 | /* // TODO world wrapping
163 | if x.abs() >= halfsize {
164 | x -= x.signum() * mapsize;
165 | }
166 | if z.abs() >= halfsize {
167 | z -= z.signum() * mapsize;
168 | }*/
169 | }
170 | }
171 |
--------------------------------------------------------------------------------
/pi3d/examples/fonts/NotoSans-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/fonts/NotoSans-Regular.ttf
--------------------------------------------------------------------------------
/pi3d/examples/fonts/NotoSerif-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/fonts/NotoSerif-Regular.ttf
--------------------------------------------------------------------------------
/pi3d/examples/fonts/Str437.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/fonts/Str437.ttf
--------------------------------------------------------------------------------
/pi3d/examples/game.rs:
--------------------------------------------------------------------------------
1 | extern crate pi3d;
2 | extern crate rand;
3 | extern crate sdl2;
4 | use sdl2::keyboard::Keycode;
5 |
6 | const W: f32 = 960.0;
7 | const H: f32 = 720.0;
8 |
9 | fn main() {
10 | let mut display = pi3d::display::create("experimental game window", W, H, "GL", 2, 1).unwrap();
11 | display.set_background(&[0.1, 0.1, 0.2, 1.0]);
12 | display.set_mouse_relative(true);
13 | display.set_target_fps(30.0);
14 | let shader_program = pi3d::shader::Program::from_res("uv_reflect").unwrap();
15 | let flatsh = pi3d::shader::Program::from_res("uv_flat").unwrap();
16 | let textsh = pi3d::shader::Program::from_res("uv_pointsprite").unwrap();
17 | let mut camera = pi3d::camera::create(&display);
18 | let mut camera2d = pi3d::camera::create(&display);
19 | camera2d.set_3d(false);
20 |
21 | let tex = pi3d::texture::create_from_file("textures/pattern.png");
22 | let maptex = pi3d::texture::create_from_file("textures/mountains3_512.jpg");
23 | let mapnorm = pi3d::texture::create_from_file("textures/grasstile_n.jpg");
24 | let stars = pi3d::texture::create_from_file("textures/stars.jpg");
25 | let font = pi3d::util::font::create("fonts/NotoSans-Regular.ttf", "", "ęĻ", 64.0);
26 | let mut mystring = pi3d::shapes::string::create(
27 | camera2d.reference(),
28 | &font,
29 | "\"The quick brown
30 | fox `jumps`
31 | over thę Ļazy
32 | dog\"",
33 | 0.0,
34 | );
35 | mystring.set_shader(&flatsh);
36 | mystring.position_z(2.0);
37 |
38 | let mut candlestick = pi3d::shapes::lathe::create(
39 | camera.reference(),
40 | vec![
41 | [0.0, 2.0],
42 | [0.1, 1.8],
43 | [0.1, 1.2],
44 | [0.5, 1.0],
45 | [0.6, 0.6],
46 | [0.2, 0.5],
47 | [0.2, 0.2],
48 | [1.0, 0.1],
49 | [1.2, -0.3],
50 | [0.0, -2.0],
51 | ],
52 | 144,
53 | 0.0,
54 | 1.0,
55 | );
56 | candlestick.set_draw_details(
57 | &shader_program,
58 | &vec![tex.id, mapnorm.id, stars.id],
59 | 1.0,
60 | 0.1,
61 | 1.0,
62 | 1.0,
63 | 1.0,
64 | );
65 | candlestick.position(&[-2.0, 30.0, 15.0]);
66 | candlestick.set_material(&[1.0, 0.0, 0.0]);
67 |
68 | let sphere =
69 | pi3d::shapes::sphere::create(camera.reference(), 1.5, 16, 32, 0.3, false).reference();
70 | sphere.borrow_mut().set_textures(&vec![tex.id, mapnorm.id]);
71 | sphere.borrow_mut().set_shader(&shader_program);
72 |
73 | let mut cube2 = pi3d::shapes::cuboid::create(camera.reference(), 3.0, 2.0, 1.0, 1.0, 1.0, 1.0);
74 | cube2.set_draw_details(
75 | &shader_program,
76 | &vec![tex.id, mapnorm.id, stars.id],
77 | 2.0,
78 | 0.1,
79 | 2.0,
80 | 3.0,
81 | 1.0,
82 | );
83 | cube2.set_light(
84 | 0,
85 | &[1.5, 1.5, 4.0],
86 | &[10.0, 10.0, 10.0],
87 | &[0.05, 0.1, 0.05],
88 | true,
89 | );
90 | cube2.add_child(sphere.clone());
91 |
92 | let mut junk = pi3d::shapes::merge_shape::create(camera.reference());
93 | pi3d::shapes::merge_shape::add_shapes(
94 | &mut junk,
95 | vec![&cube2, &cube2, &candlestick],
96 | vec![[2.0, 1.0, 1.0], [-1.0, -1.0, 1.0], [0.0, 0.0, -0.5]],
97 | vec![[0.0, 1.0, 0.0], [1.0, 1.0, 0.0], [0.0, 0.0, 0.0]],
98 | vec![[1.0, 1.0, 1.0], [0.5, 2.0, 2.0], [2.2, 2.2, 2.2]],
99 | vec![0, 0, 1],
100 | );
101 | junk.buf[1].set_material(&[1.0, 1.0, 0.0, 1.0]);
102 | junk.position(&[1.0, 30.0, 7.5]);
103 |
104 | let mut map = pi3d::shapes::elevation_map::new(
105 | camera.reference(),
106 | "textures/mountainsHgt.png",
107 | 400.0,
108 | 400.0,
109 | 50.0,
110 | 64,
111 | 64,
112 | 1.0,
113 | "nothing",
114 | );
115 | map.shape.set_draw_details(
116 | &shader_program,
117 | &vec![maptex.id, mapnorm.id, stars.id],
118 | 128.0,
119 | 0.0,
120 | 1.0,
121 | 1.0,
122 | 2.0,
123 | );
124 |
125 | let (mut iss, _texlist) = pi3d::shapes::model_obj::create(camera.reference(), "models/iss.obj");
126 | iss.set_shader(&shader_program);
127 | iss.set_normal_shine(&vec![mapnorm.id, stars.id], 16.0, 0.1, 1.0, 1.0, 0.1, true);
128 | iss.position(&[20.0, 50.0, 10.0]);
129 | iss.scale(&[40.0, 40.0, 40.0]);
130 |
131 | let mut clust = pi3d::shapes::merge_shape::create(camera.reference());
132 | pi3d::shapes::merge_shape::cluster(
133 | &mut clust, &cube2, &map, -20.0, -100.0, 200.0, 150.0, 0.5, 2.5, 200,
134 | );
135 |
136 | let (mut ecube, _tex_list) = pi3d::shapes::environment_cube::create(
137 | camera.reference(),
138 | 500.0,
139 | "ecubes/miramar_256",
140 | "png",
141 | );
142 | ecube.set_shader(&flatsh);
143 |
144 | // fps counter
145 | let mut fps_text = pi3d::shapes::point_text::create(camera2d.reference(), &font, 20, 24.0);
146 | fps_text.set_shader(&textsh);
147 | let fps_blk = fps_text.add_text_block(
148 | &font,
149 | &[-W * 0.5 + 20.0, -H * 0.5 + 20.0, 0.1],
150 | 19,
151 | "00.0 FPS",
152 | );
153 |
154 | let mut t: f32 = 0.0;
155 | let mut x: f32 = 0.0;
156 | let mut y: f32 = 0.0;
157 | let mut z: f32 = -0.1;
158 | let mut ds: f32 = 0.01;
159 | let mut rot: f32 = 0.0;
160 | let mut tilt: f32 = 0.0;
161 |
162 | while display.loop_running() {
163 | t += 0.02;
164 |
165 | sphere.borrow_mut().rotate_inc_y(0.01);
166 | sphere.borrow_mut().rotate_inc_z(0.031);
167 | sphere.borrow_mut().position(&[
168 | (t * 0.087 % 2.2 - 1.1).abs(),
169 | (t * 0.12 % 5.98 - 2.99).abs() + 4.0,
170 | 2.5,
171 | ]);
172 |
173 | cube2.rotate_inc_z(0.009);
174 | cube2.position_x(((t + 0.7) * 0.047 % 5.2 - 2.6).abs() - 1.01);
175 | cube2.position_y((t * 0.092 % 3.48 - 1.74).abs() + 30.7);
176 |
177 | candlestick.rotate_inc_x(0.05);
178 |
179 | junk.rotate_inc_y(0.1);
180 |
181 | iss.rotate_inc_y(0.01);
182 | iss.rotate_inc_x(0.007);
183 |
184 | for i in 0..clust.buf[0].array_buffer.shape()[0] {
185 | clust.buf[0].array_buffer[[i, 1]] *= 0.9995 + 0.001 * rand::random::();
186 | }
187 | clust.buf[0].re_init();
188 |
189 | ecube.draw();
190 | cube2.draw();
191 | candlestick.draw();
192 | junk.draw();
193 | map.shape.draw();
194 | iss.draw();
195 | clust.draw();
196 | mystring.draw();
197 | fps_text.set_text(&font, fps_blk, &format!("{:5.1} FPS", display.fps()));
198 | fps_text.draw();
199 |
200 | if display.keys_pressed.contains(&Keycode::Escape) {
201 | break;
202 | }
203 | if display.keys_down.contains(&Keycode::A) {
204 | cube2.offset(&[t % 3.0, 0.0, 0.0]);
205 | }
206 | if display.mouse_moved {
207 | tilt = (display.mouse_y as f32 - 300.0) * -0.004;
208 | rot = (display.mouse_x as f32 - 400.0) * -0.004;
209 | }
210 | if display.keys_pressed.contains(&Keycode::L) {
211 | candlestick.buf[0].set_line_width(2.0, true, false);
212 | }
213 | if display.keys_pressed.contains(&Keycode::F) {
214 | candlestick.buf[0].set_line_width(0.0, true, false);
215 | }
216 | if display.keys_pressed.contains(&Keycode::P) {
217 | candlestick.buf[0].set_point_size(3.0);
218 | }
219 | if display.keys_pressed.contains(&Keycode::W) {
220 | ds = 1.25;
221 | }
222 | if display.keys_pressed.contains(&Keycode::S) {
223 | ds = -0.25;
224 | }
225 | let cd = camera.get_direction();
226 | x += cd[0] * ds;
227 | y += cd[1] * ds;
228 | z += cd[2] * ds;
229 | camera.reset();
230 | camera.rotate(&[tilt, rot, 0.0]);
231 | if ds != 0.0 {
232 | let (newy, _mapnorm) = map.calc_height(x, z);
233 | y = newy + 5.0;
234 | camera.position(&[x, y, z]);
235 | }
236 | ds = 0.0;
237 | if display.was_resized() {
238 | camera.set_lens_from_display(&display);
239 | camera2d.set_lens_from_display(&display);
240 | fps_text.set_position(
241 | &font,
242 | fps_blk,
243 | &[
244 | -display.width * 0.5 + 20.0,
245 | -display.height * 0.5 + 20.0,
246 | 0.1,
247 | ],
248 | );
249 | }
250 | }
251 | }
252 |
--------------------------------------------------------------------------------
/pi3d/examples/minimal.rs:
--------------------------------------------------------------------------------
1 | extern crate pi3d;
2 |
3 | const W: f32 = 900.0; // these are overwritten by fullscreen option
4 | const H: f32 = 700.0;
5 |
6 | fn main() {
7 | // initially set up display, shader, camera, texture and shapes
8 | let mut display =
9 | pi3d::display::create("minimal example ESC to quit", W, H, "GL", 2, 1).unwrap();
10 | display.set_target_fps(5.0); // nothing happens so no point running faster
11 | let shader = pi3d::shader::Program::from_res("uv_flat").unwrap();
12 | let mut camera = pi3d::camera::create(&display);
13 | camera.set_3d(false); // make it a 2D shader
14 | let tex = pi3d::texture::create_from_file("textures/pattern.png");
15 | let mut plane = pi3d::shapes::plane::create(
16 | camera.reference(),
17 | display.height * 0.7,
18 | display.height * 0.7,
19 | );
20 | plane.set_draw_details(&shader, &vec![tex.id], 1.0, 0.0, 1.0, 1.0, 0.0);
21 |
22 | // draw in a loop
23 | while display.loop_running() {
24 | // default sdl2 check for ESC or click cross
25 | plane.draw();
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/pi3d/examples/models/CargoHoldBaked2.mtl:
--------------------------------------------------------------------------------
1 | #
2 | # Wavefront material file
3 | # Converted by Meshlab Group
4 | #
5 |
6 | newmtl ashphalt
7 | Ka 0.200000 0.200000 0.200000
8 | Kd 1.000000 1.000000 1.000000
9 | Ks 1.000000 1.000000 1.000000
10 | Tr 1.000000
11 | illum 2
12 | Ns 0.000000
13 | map_Kd maps/ashphalt.jpg
14 |
15 | newmtl ashphalt_[barriers]
16 | Ka 0.200000 0.200000 0.200000
17 | Kd 1.000000 1.000000 1.000000
18 | Ks 1.000000 1.000000 1.000000
19 | Tr 1.000000
20 | illum 0
21 | Ns 0.000000
22 | map_Kd maps/barriersCompleteMap.jpg
23 | newmtl walkplate
24 | Ka 0.200000 0.200000 0.200000
25 | Kd 1.000000 1.000000 1.000000
26 | Ks 1.000000 1.000000 1.000000
27 | Tr 1.000000
28 | illum 2
29 | Ns 0.000000
30 | map_Kd maps/walkplate.png
31 |
32 | newmtl orig_ashphaltShaded_[strips]
33 | Ka 0.200000 0.200000 0.200000
34 | Kd 1.000000 1.000000 1.000000
35 | Ks 0.200000 0.200000 0.200000
36 | Tr 1.000000
37 | illum 2
38 | Ns 0.000000
39 | map_Kd maps/stripsCompleteMap.jpg
40 | newmtl blueglow
41 | Ka 0.200000 0.200000 0.200000
42 | Kd 1.000000 1.000000 1.000000
43 | Ks 1.000000 1.000000 1.000000
44 | Tr 1.000000
45 | illum 0
46 | Ns 0.000000
47 | map_Kd maps/blueglow.png
48 |
49 | newmtl whiteLight
50 | Ka 0.200000 0.200000 0.200000
51 | Kd 1.000000 1.000000 1.000000
52 | Ks 1.000000 1.000000 1.000000
53 | Tr 1.000000
54 | illum 0
55 | Ns 0.000000
56 | map_Kd maps/white.png
57 |
58 | newmtl red
59 | Ka 0.200000 0.200000 0.200000
60 | Kd 1.000000 1.000000 1.000000
61 | Ks 1.000000 1.000000 1.000000
62 | Tr 1.000000
63 | illum 0
64 | Ns 0.000000
65 | map_Kd maps/red.png
66 |
67 | newmtl chevrons_[Line68]
68 | Ka 0.200000 0.200000 0.200000
69 | Kd 1.000000 1.000000 1.000000
70 | Ks 1.000000 1.000000 1.000000
71 | Tr 1.000000
72 | illum 0
73 | Ns 0.000000
74 | map_Kd maps/ChevronsCompleteMap.jpg
75 | newmtl panels
76 | Ka 0.200000 0.200000 0.200000
77 | Kd 1.000000 1.000000 1.000000
78 | Ks 1.000000 1.000000 1.000000
79 | Tr 1.000000
80 | illum 2
81 | Ns 0.000000
82 | map_Kd maps/fx3_Panels.png
83 |
84 | newmtl walkplate_[walkways]
85 | Ka 0.200000 0.200000 0.200000
86 | Kd 1.000000 1.000000 1.000000
87 | Ks 1.000000 1.000000 1.000000
88 | Tr 1.000000
89 | illum 0
90 | Ns 0.000000
91 | map_Kd maps/walkwaysCompleteMap.jpg
92 |
93 | newmtl panels_[body]
94 | Ka 0.200000 0.200000 0.200000
95 | Kd 1.000000 1.000000 1.000000
96 | Ks 1.000000 1.000000 1.000000
97 | Tr 1.000000
98 | illum 0
99 | Ns 0.000000
100 | map_Kd maps/bodyCompleteMap.jpg
101 |
102 |
103 | newmtl orig_bluealum_[bluealum]
104 | Ka 0.200000 0.200000 0.200000
105 | Kd 1.000000 1.000000 1.000000
106 | Ks 1.000000 1.000000 1.000000
107 | Tr 1.000000
108 | illum 0
109 | Ns 0.000000
110 | map_Kd maps/bluealumCompleteMap.jpg
111 |
112 | newmtl medmon
113 | Ka 0.200000 0.200000 0.200000
114 | Kd 1.000000 1.000000 1.000000
115 | Ks 1.000000 1.000000 1.000000
116 | Tr 1.000000
117 | illum 0
118 | Ns 0.000000
119 | map_Kd maps/MedMon1.png
120 |
121 | newmtl radar
122 | Ka 0.200000 0.200000 0.200000
123 | Kd 1.000000 1.000000 1.000000
124 | Ks 1.000000 1.000000 1.000000
125 | Ke 1.5 1.5 1.5
126 | Tr 1.000000
127 | illum 0
128 | anim 0.0833333 0.0
129 | Ns 0.000000
130 | map_Kd maps/radar.png
131 |
132 | newmtl white_[rods]
133 | Ka 0.200000 0.200000 0.200000
134 | Kd 1.000000 1.000000 1.000000
135 | Ks 1.000000 1.000000 1.000000
136 | Tr 1.000000
137 | illum 0
138 | Ns 0.000000
139 | map_Kd maps/rodsCompleteMap.png
140 |
141 | newmtl orig_panels_[panel]
142 | Ka 0.200000 0.200000 0.200000
143 | Kd 1.000000 1.000000 1.000000
144 | Ks 1.000000 1.000000 1.000000
145 | Tr 1.000000
146 | illum 0
147 | Ns 0.000000
148 | map_Kd maps/panelCompleteMap.png
149 |
--------------------------------------------------------------------------------
/pi3d/examples/models/Raspi256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/models/Raspi256x256.png
--------------------------------------------------------------------------------
/pi3d/examples/models/biplane.mtl:
--------------------------------------------------------------------------------
1 | # Blender MTL File: 'biplane.blend'
2 | # Material Count: 1
3 | newmtl Material.001_biplane1.jpg
4 | Ns 96.078431
5 | Ka 0.000000 0.000000 0.000000
6 | Kd 0.640000 0.640000 0.640000
7 | Ks 0.500000 0.500000 0.500000
8 | Ni 1.000000
9 | d 1.000000
10 | illum 2
11 | map_Kd biplane1.jpg
12 |
13 |
14 |
--------------------------------------------------------------------------------
/pi3d/examples/models/biplane1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/models/biplane1.jpg
--------------------------------------------------------------------------------
/pi3d/examples/models/earthskybox.mtl:
--------------------------------------------------------------------------------
1 | #
2 | # Wavefront material file
3 | # Converted by Meshlab Group
4 | #
5 |
6 | newmtl material_0
7 | Ka 0.200000 0.200000 0.200000
8 | Kd 1.000000 1.000000 1.000000
9 | Ks 1.000000 1.000000 1.000000
10 | Ke 1.1 1.1 1.1
11 | Tr 1.000000
12 | illum 1
13 | Ns 0.000000
14 | map_Kd maps/sbox_left512.png
15 |
16 | newmtl material_1
17 | Ka 0.200000 0.200000 0.200000
18 | Kd 1.000000 1.000000 1.000000
19 | Ks 1.000000 1.000000 1.000000
20 | Ke 1.1 1.1 1.1
21 | Tr 1.000000
22 | illum 1
23 | Ns 0.000000
24 | map_Kd maps/sbox_front512.png
25 |
26 | newmtl material_2
27 | Ka 0.200000 0.200000 0.200000
28 | Kd 1.000000 1.000000 1.000000
29 | Ks 1.000000 1.000000 1.000000
30 | Ke 1.1 1.1 1.1
31 | Tr 1.000000
32 | illum 1
33 | Ns 0.000000
34 | map_Kd maps/sbox_back512.png
35 |
36 | newmtl material_3
37 | Ka 0.200000 0.200000 0.200000
38 | Kd 1.000000 1.000000 1.000000
39 | Ks 1.000000 1.000000 1.000000
40 | Ke 1.1 1.1 1.1
41 | Tr 1.000000
42 | illum 1
43 | Ns 0.000000
44 | map_Kd maps/sbox_right512.png
45 |
46 | newmtl material_4
47 | Ka 0.200000 0.200000 0.200000
48 | Kd 1.000000 1.000000 1.000000
49 | Ks 1.000000 1.000000 1.000000
50 | Ke 1.1 1.1 1.1
51 | Tr 1.000000
52 | illum 1
53 | Ns 0.000000
54 | map_Kd maps/sbox_top512.png
55 |
56 | newmtl material_5
57 | Ka 0.200000 0.200000 0.200000
58 | Kd 1.000000 1.000000 1.000000
59 | Ks 1.000000 1.000000 1.000000
60 | Ke 1.1 1.1 1.1
61 | Tr 1.000000
62 | illum 1
63 | Ns 0.000000
64 | map_Kd maps/sbox_bottom512.png
65 |
66 |
--------------------------------------------------------------------------------
/pi3d/examples/models/earthskybox.obj:
--------------------------------------------------------------------------------
1 | ####
2 | #
3 | # OBJ File Generated by Meshlab
4 | #
5 | ####
6 | # Object earthskybox.obj
7 | #
8 | # Vertices: 24
9 | # Faces: 12
10 | #
11 | ####
12 | mtllib earthskybox.mtl
13 |
14 | v -500.499969 -500.500000 -500.499969
15 | v 500.500031 -500.500000 -500.499969
16 | v -500.499969 500.500000 -500.499969
17 | v 500.500031 500.500000 -500.499969
18 | v 500.500031 -500.500000 500.500031
19 | v 500.500031 -500.500000 -500.499969
20 | v 500.500031 500.500000 500.500031
21 | v 500.500031 500.500000 -500.499969
22 | v -500.499969 -500.500000 500.500031
23 | v -500.499969 -500.500000 -500.499969
24 | v -500.499969 500.500000 500.500031
25 | v -500.499969 500.500000 -500.499969
26 | v -500.499969 -500.500000 500.500031
27 | v 500.500031 -500.500000 500.500031
28 | v -500.499969 500.500000 500.500031
29 | v 500.500031 500.500000 500.500031
30 | v -500.499969 500.500000 500.500031
31 | v 500.500031 500.500000 500.500031
32 | v -500.499969 500.500000 -500.499969
33 | v 500.500031 500.500000 -500.499969
34 | v -500.499969 -500.500000 500.500031
35 | v 500.500031 -500.500000 500.500031
36 | v -500.499969 -500.500000 -500.499969
37 | v 500.500031 -500.500000 -500.499969
38 | # 24 vertices, 0 vertices normals
39 |
40 |
41 | usemtl material_0
42 | vt 0.000500 0.000500
43 | vt 0.999500 0.000500
44 | vt 0.000500 0.999500
45 | f 1/1 2/2 3/3
46 | vt 0.999500 0.999500
47 | f 4/4 3/3 2/2
48 |
49 | usemtl material_1
50 | f 6/1 5/2 8/3
51 | f 7/4 8/3 5/2
52 |
53 | usemtl material_2
54 | f 9/1 10/2 11/3
55 | f 12/4 11/3 10/2
56 |
57 | usemtl material_3
58 | f 14/1 13/2 16/3
59 | f 15/4 16/3 13/2
60 |
61 | usemtl material_4
62 | vt 0.999500 0.000500
63 | vt 0.000500 0.000500
64 | f 18/5 17/4 20/6
65 | vt 0.000500 0.999500
66 | f 19/7 20/6 17/4
67 |
68 | usemtl material_5
69 | vt 0.000499 0.000500
70 | vt 0.999500 0.000499
71 | vt 0.000500 0.999500
72 | f 23/8 21/9 24/10
73 | f 22/4 24/10 21/9
74 | # 12 faces, 10 coords texture
75 |
76 | # End of File
77 |
--------------------------------------------------------------------------------
/pi3d/examples/models/iss.mtl:
--------------------------------------------------------------------------------
1 | # Blender MTL File: 'None'
2 | # Material Count: 27
3 |
4 | newmtl anisotropic1SG
5 | Ns 94.117647
6 | Ka 1.000000 1.000000 1.000000
7 | Kd 0.320000 0.320000 0.320000
8 | Ks 0.500000 0.500000 0.500000
9 | Ke 0.000000 0.000000 0.000000
10 | Ni 1.000000
11 | d 1.000000
12 | illum 2
13 | map_Kd Raspi256x256.png
14 |
15 | newmtl anisotropic1SG_leeds_raspberry_jam02c.png
16 | Ns 94.117647
17 | Ka 1.000000 1.000000 1.000000
18 | Kd 0.320000 0.320000 0.320000
19 | Ks 0.500000 0.500000 0.500000
20 | Ke 0.000000 0.000000 0.000000
21 | Ni 1.000000
22 | d 1.000000
23 | illum 2
24 | map_Kd leeds_raspberry_jam02c.png
25 |
26 | newmtl apollohorns_blin
27 | Ns 94.117647
28 | Ka 1.000000 1.000000 1.000000
29 | Kd 0.320000 0.320000 0.320000
30 | Ks 0.500000 0.500000 0.500000
31 | Ke 0.000000 0.000000 0.000000
32 | Ni 1.000000
33 | d 1.000000
34 | illum 2
35 | map_Kd Raspi256x256.png
36 |
37 | newmtl apollohorns_blin_leeds_raspberry_jam02c.png
38 | Ns 94.117647
39 | Ka 1.000000 1.000000 1.000000
40 | Kd 0.320000 0.320000 0.320000
41 | Ks 0.500000 0.500000 0.500000
42 | Ke 0.000000 0.000000 0.000000
43 | Ni 1.000000
44 | d 1.000000
45 | illum 2
46 | map_Kd leeds_raspberry_jam02c.png
47 |
48 | newmtl bendedtruss_blin
49 | Ns 94.117647
50 | Ka 1.000000 1.000000 1.000000
51 | Kd 0.320000 0.320000 0.320000
52 | Ks 0.500000 0.500000 0.500000
53 | Ke 0.000000 0.000000 0.000000
54 | Ni 1.000000
55 | d 1.000000
56 | illum 2
57 | map_Kd leeds_raspberry_jam02c.png
58 |
59 | newmtl blinn1SG
60 | Ns 94.117647
61 | Ka 1.000000 1.000000 1.000000
62 | Kd 0.320000 0.320000 0.320000
63 | Ks 0.500000 0.500000 0.500000
64 | Ke 0.000000 0.000000 0.000000
65 | Ni 1.000000
66 | d 1.000000
67 | illum 2
68 | map_Kd Raspi256x256.png
69 |
70 | newmtl blinn1SG_leeds_raspberry_jam02c.png
71 | Ns 94.117647
72 | Ka 1.000000 1.000000 1.000000
73 | Kd 0.320000 0.320000 0.320000
74 | Ks 0.500000 0.500000 0.500000
75 | Ke 0.000000 0.000000 0.000000
76 | Ni 1.000000
77 | d 1.000000
78 | illum 2
79 | map_Kd leeds_raspberry_jam02c.png
80 |
81 | newmtl blinn3SG
82 | Ns 94.117647
83 | Ka 1.000000 1.000000 1.000000
84 | Kd 0.320000 0.320000 0.320000
85 | Ks 0.500000 0.500000 0.500000
86 | Ke 0.000000 0.000000 0.000000
87 | Ni 1.000000
88 | d 1.000000
89 | illum 2
90 | map_Kd Raspi256x256.png
91 |
92 | newmtl blinn3SG_leeds_raspberry_jam02c.png
93 | Ns 94.117647
94 | Ka 1.000000 1.000000 1.000000
95 | Kd 0.320000 0.320000 0.320000
96 | Ks 0.500000 0.500000 0.500000
97 | Ke 0.000000 0.000000 0.000000
98 | Ni 1.000000
99 | d 1.000000
100 | illum 2
101 | map_Kd leeds_raspberry_jam02c.png
102 |
103 | newmtl blinn4SG
104 | Ns 94.117647
105 | Ka 1.000000 1.000000 1.000000
106 | Kd 0.320000 0.320000 0.320000
107 | Ks 0.500000 0.500000 0.500000
108 | Ke 0.000000 0.000000 0.000000
109 | Ni 1.000000
110 | d 1.000000
111 | illum 2
112 | map_Kd leeds_raspberry_jam02c.png
113 |
114 | newmtl blinn5SG
115 | Ns 94.117647
116 | Ka 1.000000 1.000000 1.000000
117 | Kd 0.320000 0.320000 0.320000
118 | Ks 0.500000 0.500000 0.500000
119 | Ke 0.000000 0.000000 0.000000
120 | Ni 1.000000
121 | d 1.000000
122 | illum 2
123 | map_Kd leeds_raspberry_jam02c.png
124 |
125 | newmtl blinn6SG
126 | Ns 94.117647
127 | Ka 1.000000 1.000000 1.000000
128 | Kd 0.320000 0.320000 0.320000
129 | Ks 0.500000 0.500000 0.500000
130 | Ke 0.000000 0.000000 0.000000
131 | Ni 1.000000
132 | d 1.000000
133 | illum 2
134 | map_Kd leeds_raspberry_jam02c.png
135 |
136 | newmtl blinn7SG
137 | Ns 94.117647
138 | Ka 1.000000 1.000000 1.000000
139 | Kd 0.320000 0.320000 0.320000
140 | Ks 0.500000 0.500000 0.500000
141 | Ke 0.000000 0.000000 0.000000
142 | Ni 1.000000
143 | d 1.000000
144 | illum 2
145 | map_Kd leeds_raspberry_jam02c.png
146 |
147 | newmtl initialShadingGr
148 | Ns 94.117647
149 | Ka 1.000000 1.000000 1.000000
150 | Kd 0.320000 0.320000 0.320000
151 | Ks 0.500000 0.500000 0.500000
152 | Ke 0.000000 0.000000 0.000000
153 | Ni 1.000000
154 | d 1.000000
155 | illum 2
156 | map_Kd Raspi256x256.png
157 |
158 | newmtl initialShadingGr_leeds_raspberry_jam02c.png
159 | Ns 94.117647
160 | Ka 1.000000 1.000000 1.000000
161 | Kd 0.320000 0.320000 0.320000
162 | Ks 0.500000 0.500000 0.500000
163 | Ke 0.000000 0.000000 0.000000
164 | Ni 1.000000
165 | d 1.000000
166 | illum 2
167 | map_Kd leeds_raspberry_jam02c.png
168 |
169 | newmtl lambert2SG
170 | Ns 94.117647
171 | Ka 1.000000 1.000000 1.000000
172 | Kd 0.320000 0.320000 0.320000
173 | Ks 0.500000 0.500000 0.500000
174 | Ke 0.000000 0.000000 0.000000
175 | Ni 1.000000
176 | d 1.000000
177 | illum 2
178 | map_Kd leeds_raspberry_jam02c.png
179 |
180 | newmtl lambert3SG
181 | Ns 94.117647
182 | Ka 1.000000 1.000000 1.000000
183 | Kd 0.320000 0.320000 0.320000
184 | Ks 0.500000 0.500000 0.500000
185 | Ke 0.000000 0.000000 0.000000
186 | Ni 1.000000
187 | d 1.000000
188 | illum 2
189 | map_Kd Raspi256x256.png
190 |
191 | newmtl lambert3SG_leeds_raspberry_jam02c.png
192 | Ns 94.117647
193 | Ka 1.000000 1.000000 1.000000
194 | Kd 0.320000 0.320000 0.320000
195 | Ks 0.500000 0.500000 0.500000
196 | Ke 0.000000 0.000000 0.000000
197 | Ni 1.000000
198 | d 1.000000
199 | illum 2
200 | map_Kd leeds_raspberry_jam02c.png
201 |
202 | newmtl lambert4SG
203 | Ns 94.117647
204 | Ka 1.000000 1.000000 1.000000
205 | Kd 0.320000 0.320000 0.320000
206 | Ks 0.500000 0.500000 0.500000
207 | Ke 0.000000 0.000000 0.000000
208 | Ni 1.000000
209 | d 1.000000
210 | illum 2
211 | map_Kd Raspi256x256.png
212 |
213 | newmtl lambert4SG_leeds_raspberry_jam02c.png
214 | Ns 94.117647
215 | Ka 1.000000 1.000000 1.000000
216 | Kd 0.320000 0.320000 0.320000
217 | Ks 0.500000 0.500000 0.500000
218 | Ke 0.000000 0.000000 0.000000
219 | Ni 1.000000
220 | d 1.000000
221 | illum 2
222 | map_Kd leeds_raspberry_jam02c.png
223 |
224 | newmtl lambert6SG
225 | Ns 94.117647
226 | Ka 1.000000 1.000000 1.000000
227 | Kd 0.320000 0.320000 0.320000
228 | Ks 0.500000 0.500000 0.500000
229 | Ke 0.000000 0.000000 0.000000
230 | Ni 1.000000
231 | d 1.000000
232 | illum 2
233 | map_Kd Raspi256x256.png
234 |
235 | newmtl lambert6SG_leeds_raspberry_jam02c.png
236 | Ns 94.117647
237 | Ka 1.000000 1.000000 1.000000
238 | Kd 0.320000 0.320000 0.320000
239 | Ks 0.500000 0.500000 0.500000
240 | Ke 0.000000 0.000000 0.000000
241 | Ni 1.000000
242 | d 1.000000
243 | illum 2
244 | map_Kd leeds_raspberry_jam02c.png
245 |
246 | newmtl lambert7SG
247 | Ns 94.117647
248 | Ka 1.000000 1.000000 1.000000
249 | Kd 0.320000 0.320000 0.320000
250 | Ks 0.500000 0.500000 0.500000
251 | Ke 0.000000 0.000000 0.000000
252 | Ni 1.000000
253 | d 1.000000
254 | illum 2
255 | map_Kd Raspi256x256.png
256 |
257 | newmtl soyuz_blinn2SG
258 | Ns 94.117647
259 | Ka 1.000000 1.000000 1.000000
260 | Kd 0.320000 0.320000 0.320000
261 | Ks 0.500000 0.500000 0.500000
262 | Ke 0.000000 0.000000 0.000000
263 | Ni 1.000000
264 | d 1.000000
265 | illum 2
266 | map_Kd leeds_raspberry_jam02c.png
267 |
268 | newmtl soyuz_blinn3SG
269 | Ns 94.117647
270 | Ka 1.000000 1.000000 1.000000
271 | Kd 0.320000 0.320000 0.320000
272 | Ks 0.500000 0.500000 0.500000
273 | Ke 0.000000 0.000000 0.000000
274 | Ni 1.000000
275 | d 1.000000
276 | illum 2
277 | map_Kd Raspi256x256.png
278 |
279 | newmtl soyuz_blinn3SG_leeds_raspberry_jam02c.png
280 | Ns 94.117647
281 | Ka 1.000000 1.000000 1.000000
282 | Kd 0.320000 0.320000 0.320000
283 | Ks 0.500000 0.500000 0.500000
284 | Ke 0.000000 0.000000 0.000000
285 | Ni 1.000000
286 | d 1.000000
287 | illum 2
288 | map_Kd leeds_raspberry_jam02c.png
289 |
290 | newmtl soyuz_blinn4SG
291 | Ns 94.117647
292 | Ka 1.000000 1.000000 1.000000
293 | Kd 0.320000 0.320000 0.320000
294 | Ks 0.500000 0.500000 0.500000
295 | Ke 0.000000 0.000000 0.000000
296 | Ni 1.000000
297 | d 1.000000
298 | illum 2
299 | map_Kd leeds_raspberry_jam02c.png
300 |
--------------------------------------------------------------------------------
/pi3d/examples/models/leeds_raspberry_jam02c.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/models/leeds_raspberry_jam02c.png
--------------------------------------------------------------------------------
/pi3d/examples/models/maps/ChevronsCompleteMap.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/models/maps/ChevronsCompleteMap.jpg
--------------------------------------------------------------------------------
/pi3d/examples/models/maps/MedMon1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/models/maps/MedMon1.png
--------------------------------------------------------------------------------
/pi3d/examples/models/maps/ashphalt.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/models/maps/ashphalt.jpg
--------------------------------------------------------------------------------
/pi3d/examples/models/maps/barriersCompleteMap.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/models/maps/barriersCompleteMap.jpg
--------------------------------------------------------------------------------
/pi3d/examples/models/maps/bluealum.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/models/maps/bluealum.jpg
--------------------------------------------------------------------------------
/pi3d/examples/models/maps/bluealumCompleteMap.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/models/maps/bluealumCompleteMap.jpg
--------------------------------------------------------------------------------
/pi3d/examples/models/maps/blueglow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/models/maps/blueglow.png
--------------------------------------------------------------------------------
/pi3d/examples/models/maps/bodyCompleteMap.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/models/maps/bodyCompleteMap.jpg
--------------------------------------------------------------------------------
/pi3d/examples/models/maps/fx3_Panels.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/models/maps/fx3_Panels.png
--------------------------------------------------------------------------------
/pi3d/examples/models/maps/panelCompleteMap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/models/maps/panelCompleteMap.png
--------------------------------------------------------------------------------
/pi3d/examples/models/maps/radar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/models/maps/radar.png
--------------------------------------------------------------------------------
/pi3d/examples/models/maps/red.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/models/maps/red.png
--------------------------------------------------------------------------------
/pi3d/examples/models/maps/rodsCompleteMap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/models/maps/rodsCompleteMap.png
--------------------------------------------------------------------------------
/pi3d/examples/models/maps/sbox_512_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/models/maps/sbox_512_back.png
--------------------------------------------------------------------------------
/pi3d/examples/models/maps/sbox_512_bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/models/maps/sbox_512_bottom.png
--------------------------------------------------------------------------------
/pi3d/examples/models/maps/sbox_512_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/models/maps/sbox_512_front.png
--------------------------------------------------------------------------------
/pi3d/examples/models/maps/sbox_512_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/models/maps/sbox_512_left.png
--------------------------------------------------------------------------------
/pi3d/examples/models/maps/sbox_512_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/models/maps/sbox_512_right.png
--------------------------------------------------------------------------------
/pi3d/examples/models/maps/sbox_512_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/models/maps/sbox_512_top.png
--------------------------------------------------------------------------------
/pi3d/examples/models/maps/stripsCompleteMap.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/models/maps/stripsCompleteMap.jpg
--------------------------------------------------------------------------------
/pi3d/examples/models/maps/walkplate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/models/maps/walkplate.png
--------------------------------------------------------------------------------
/pi3d/examples/models/maps/walkwaysCompleteMap.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/models/maps/walkwaysCompleteMap.jpg
--------------------------------------------------------------------------------
/pi3d/examples/models/maps/white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/models/maps/white.png
--------------------------------------------------------------------------------
/pi3d/examples/models/pi3d.mtl:
--------------------------------------------------------------------------------
1 | # Blender MTL File: 'raspberry.blend'
2 | # Material Count: 8
3 |
4 | newmtl None
5 | Ns 500
6 | Ka 0.8 0.8 0.8
7 | Kd 0.8 0.8 0.8
8 | Ks 0.8 0.8 0.8
9 | d 1
10 | illum 2
11 |
12 | newmtl blue
13 | Ns 225.000000
14 | Ka 1.000000 1.000000 1.000000
15 | Kd 0.034340 0.061246 0.799103
16 | Ks 0.500000 0.500000 0.500000
17 | Ke 0.0 0.0 0.0
18 | Ni 1.450000
19 | d 1.000000
20 | illum 2
21 |
22 | newmtl body
23 | Ns 225.000000
24 | Ka 1.000000 1.000000 1.000000
25 | Kd 0.008023 0.008023 0.008023
26 | Ks 0.500000 0.500000 0.500000
27 | Ke 0.0 0.0 0.0
28 | Ni 1.450000
29 | d 1.000000
30 | illum 2
31 |
32 | newmtl green
33 | Ns 225.000000
34 | Ka 1.000000 1.000000 1.000000
35 | Kd 0.003347 0.309469 0.010330
36 | Ks 0.500000 0.500000 0.500000
37 | Ke 0.0 0.0 0.0
38 | Ni 1.450000
39 | d 1.000000
40 | illum 2
41 |
42 | newmtl leaves
43 | Ns 225.000000
44 | Ka 1.000000 1.000000 1.000000
45 | Kd 0.012286 0.109462 0.006049
46 | Ks 0.500000 0.500000 0.500000
47 | Ke 0.0 0.0 0.0
48 | Ni 1.450000
49 | d 1.000000
50 | illum 2
51 |
52 | newmtl pips
53 | Ns 225.000000
54 | Ka 1.000000 1.000000 1.000000
55 | Kd 0.539480 0.022174 0.033105
56 | Ks 0.500000 0.500000 0.500000
57 | Ke 0.0 0.0 0.0
58 | Ni 1.450000
59 | d 1.000000
60 | illum 2
61 |
62 | newmtl red
63 | Ns 225.000000
64 | Ka 1.000000 1.000000 1.000000
65 | Kd 0.799103 0.000000 0.006512
66 | Ks 0.500000 0.500000 0.500000
67 | Ke 0.0 0.0 0.0
68 | Ni 1.450000
69 | d 1.000000
70 | illum 2
71 |
72 | newmtl yellow
73 | Ns 225.000000
74 | Ka 1.000000 1.000000 1.000000
75 | Kd 0.799103 0.391572 0.004025
76 | Ks 0.500000 0.500000 0.500000
77 | Ke 0.0 0.0 0.0
78 | Ni 1.450000
79 | d 1.000000
80 | illum 2
81 |
--------------------------------------------------------------------------------
/pi3d/examples/models/pi3d_old.mtl:
--------------------------------------------------------------------------------
1 | # Blender MTL File: 'pi3d.blend'
2 | # Material Count: 7
3 | newmtl Material.001_pi3d.jpg
4 | Ns 96.078431
5 | Ka 0.000000 0.000000 0.000000
6 | Kd 0.800000 0.676835 0.000000
7 | Ks 0.005677 0.500000 0.416809
8 | Ni 1.000000
9 | d 1.000000
10 | illum 2
11 | map_Kd pi3d.jpg
12 |
13 |
14 | newmtl Material.002_pi3d.jpg
15 | Ns 96.078431
16 | Ka 0.000000 0.000000 0.000000
17 | Kd 0.800000 0.000000 0.000000
18 | Ks 0.003166 0.500000 0.403850
19 | Ni 1.000000
20 | d 1.000000
21 | illum 2
22 | map_Kd pi3d.jpg
23 |
24 |
25 | newmtl Material.003_pi3d.jpg
26 | Ns 96.078431
27 | Ka 0.000000 0.000000 0.000000
28 | Kd 0.078331 0.626651 0.087035
29 | Ks 0.000000 0.500000 0.426184
30 | Ni 1.000000
31 | d 1.000000
32 | illum 2
33 | map_Kd pi3d.jpg
34 |
35 |
36 | newmtl Material.004_pi3d.jpg
37 | Ns 96.078431
38 | Ka 0.000000 0.000000 0.000000
39 | Kd 0.081481 0.081481 0.836574
40 | Ks 0.023671 0.500000 0.448963
41 | Ni 1.000000
42 | d 1.000000
43 | illum 2
44 | map_Kd pi3d.jpg
45 |
46 |
47 | newmtl Material.005_pi3d.jpg
48 | Ns 96.078431
49 | Ka 0.000000 0.000000 0.000000
50 | Kd 0.020314 0.020314 0.020314
51 | Ks 0.500000 0.500000 0.500000
52 | Ni 1.000000
53 | d 1.000000
54 | illum 2
55 | map_Kd pi3d.jpg
56 |
57 |
58 | newmtl Material.006_pi3d.jpg
59 | Ns 96.078431
60 | Ka 0.000000 0.000000 0.000000
61 | Kd 0.800000 0.000000 0.000000
62 | Ks 0.500000 0.500000 0.500000
63 | Ni 1.000000
64 | d 1.000000
65 | illum 2
66 | map_Kd pi3d.jpg
67 |
68 |
69 | newmtl Material.007_pi3d.jpg
70 | Ns 96.078431
71 | Ka 0.000000 0.000000 0.000000
72 | Kd 0.014302 0.192450 0.000000
73 | Ks 0.038264 0.500000 0.461755
74 | Ni 1.000000
75 | d 1.000000
76 | illum 2
77 | map_Kd pi3d.jpg
78 |
79 |
80 |
--------------------------------------------------------------------------------
/pi3d/examples/models/rust_pi3d.mtl:
--------------------------------------------------------------------------------
1 | # Blender MTL File: 'pi3R.blend'
2 | # Material Count: 6
3 |
4 | newmtl None
5 | Ns 500
6 | Ka 0.8 0.8 0.8
7 | Kd 0.8 0.8 0.8
8 | Ks 0.8 0.8 0.8
9 | d 1
10 | illum 2
11 |
12 | newmtl black_rust
13 | Ns 225.000000
14 | Ka 1.000000 1.000000 1.000000
15 | Kd 0.009134 0.008023 0.007499
16 | Ks 0.500000 0.500000 0.500000
17 | Ke 0.0 0.0 0.0
18 | Ni 1.450000
19 | d 1.000000
20 | illum 3
21 |
22 | newmtl blue
23 | Ns 225.000000
24 | Ka 1.000000 1.000000 1.000000
25 | Kd 0.034340 0.061246 0.799103
26 | Ks 0.500000 0.500000 0.500000
27 | Ke 0.0 0.0 0.0
28 | Ni 1.450000
29 | d 1.000000
30 | illum 2
31 |
32 | newmtl green
33 | Ns 225.000000
34 | Ka 1.000000 1.000000 1.000000
35 | Kd 0.003347 0.309469 0.010330
36 | Ks 0.500000 0.500000 0.500000
37 | Ke 0.0 0.0 0.0
38 | Ni 1.450000
39 | d 1.000000
40 | illum 2
41 |
42 | newmtl red
43 | Ns 225.000000
44 | Ka 1.000000 1.000000 1.000000
45 | Kd 0.799103 0.000000 0.006512
46 | Ks 0.500000 0.500000 0.500000
47 | Ke 0.0 0.0 0.0
48 | Ni 1.450000
49 | d 1.000000
50 | illum 2
51 |
52 | newmtl yellow
53 | Ns 225.000000
54 | Ka 1.000000 1.000000 1.000000
55 | Kd 0.799103 0.391572 0.004025
56 | Ks 0.500000 0.500000 0.500000
57 | Ke 0.0 0.0 0.0
58 | Ni 1.450000
59 | d 1.000000
60 | illum 2
61 |
--------------------------------------------------------------------------------
/pi3d/examples/picture_frame.rs:
--------------------------------------------------------------------------------
1 | extern crate pi3d;
2 | extern crate rand;
3 | extern crate sdl2;
4 |
5 | use rand::seq::SliceRandom;
6 | use rand::thread_rng;
7 | use std::fs;
8 | use std::path::Path;
9 | use std::time::{Duration, Instant};
10 | //use std::thread::sleep;
11 |
12 | const IMG_EXT: [&str; 6] = ["jpg", "JPG", "jpeg", "JPEG", "png", "PNG"];
13 | const FILE_DIR: &str = "./";
14 | //const FILE_DIR: &str = "/home/patrick/Pictures"; // or absolute path
15 |
16 | // recursive function to build list of image files. Pass ref to vec to build in place
17 | fn get_files(dir: &Path, file_list: &mut Vec) {
18 | for entry in fs::read_dir(dir).unwrap() {
19 | // will panic if dir is not a Path
20 | match entry {
21 | Ok(dir_entry) => {
22 | let path = dir_entry.path();
23 | if path.is_dir() {
24 | get_files(&path, file_list); // recurse into dir
25 | } else {
26 | // it's a file, check if image TODO exif dates and rotation
27 | let path_str = path.to_str().unwrap().to_string();
28 | let extension = path_str.split(".").last().unwrap();
29 | if IMG_EXT.iter().any(|&x| x == extension) {
30 | file_list.push(path_str);
31 | }
32 | }
33 | }
34 | _ => {
35 | println!("odd entry in directory, permission?");
36 | }
37 | }
38 | }
39 | }
40 |
41 | fn main() {
42 | let time_delay = Duration::new(10, 0); // duration per slide in (seconds, nanoseconds)
43 | let fade_time = Duration::new(5, 0);
44 |
45 | // initially set up display, shader, camera, texture and shapes
46 | let mut display =
47 | pi3d::display::create("picture_frame ESC to quit", 100.0, 100.0, "GL", 2, 1).unwrap();
48 | display.set_fullscreen(true);
49 | display.set_background(&[0.2, 0.2, 0.2, 1.0]);
50 | display.set_target_fps(30.0);
51 | let shader = pi3d::shader::Program::from_res("shaders/blend_new").unwrap();
52 | let mut camera = pi3d::camera::create(&display);
53 | camera.set_3d(false); // make it a 2D shader
54 | let (w, h) = display.get_size();
55 | let mut slide = pi3d::shapes::plane::create(camera.reference(), w as f32, h as f32); // fullscreen
56 | slide.set_draw_details(&shader, &vec![], 1.0, 1.0, 1.0, 1.0, 1.0);
57 | //slide.position_z(5.0);
58 |
59 | // pi3d has a resources function that checks if path has root
60 | let file_path = pi3d::util::resources::resource_name_to_path(FILE_DIR);
61 | let mut file_list: Vec = vec![];
62 | get_files(&file_path, &mut file_list);
63 | let mut rng = thread_rng();
64 | file_list.shuffle(&mut rng);
65 |
66 | let mut sbg: Option = None; //Options used to cater for bad image files later
67 | let mut sfg: Option = None;
68 |
69 | let mut last_tm = Instant::now().checked_sub(time_delay).unwrap();
70 | let mut pic_num = 0usize;
71 | // draw in a loop
72 | while display.loop_running() {
73 | // default sdl2 check for ESC or click cross
74 | let delta_tm = last_tm.elapsed();
75 | if delta_tm.as_secs() > time_delay.as_secs() {
76 | let mut loop_i = 0;
77 | loop {
78 | loop_i += 1;
79 | if sfg.is_some() {
80 | sbg = sfg.take(); // leave None in its place
81 | }
82 | if !sfg.is_some() {
83 | // as could have been set to None
84 | let mut tex = pi3d::texture::create_from_file(file_list[pic_num].as_str());
85 | tex.set_mirrored_repeat(true);
86 | sfg = Some(tex);
87 | pic_num += 1;
88 | if pic_num >= file_list.len() {
89 | pic_num = 0;
90 | }
91 | }
92 | if (sfg.is_some() && sbg.is_some()) || loop_i > 5 {
93 | break;
94 | }
95 | }
96 | let sfg_tex = sfg.expect("missing f_gnd image"); // unwrap them here to use contained info
97 | let sbg_tex = sbg.expect("missing bk_gnd image");
98 | slide.set_textures(&vec![sfg_tex.id, sbg_tex.id]);
99 | let w = sfg_tex.width;
100 | let h = sfg_tex.height;
101 | sfg = Some(sfg_tex); // wrapped up again for next loop
102 | sbg = Some(sbg_tex);
103 | slide.unif[[15, 0]] = slide.unif[[14, 0]]; // copy forgrnd to bkgrnd
104 | slide.unif[[15, 1]] = slide.unif[[14, 1]];
105 | slide.unif[[17, 0]] = slide.unif[[16, 0]];
106 | slide.unif[[17, 1]] = slide.unif[[16, 1]];
107 | let wh_rat = (display.width * h as f32) / (display.height * w as f32);
108 | let (ix0, ix1) = if wh_rat > 1.0 { (0, 1) } else { (1, 0) };
109 | slide.unif[[14, ix0]] = wh_rat;
110 | slide.unif[[14, ix1]] = 1.0;
111 | slide.unif[[16, ix0]] = (wh_rat - 1.0) * 0.5;
112 | slide.unif[[16, ix1]] = 0.0;
113 |
114 | slide.unif[[14, 2]] = 0.0;
115 | slide.unif[[15, 2]] = 0.5;
116 | last_tm = Instant::now();
117 | } else {
118 | let a: f32 = delta_tm.as_millis() as f32 / fade_time.as_millis() as f32;
119 | slide.unif[[14, 2]] = if a < 1.0 { a } else { 1.0 };
120 | }
121 | slide.draw();
122 | //TODO sleep while nothing's changing?
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/pi3d/examples/shader_in_src.rs:
--------------------------------------------------------------------------------
1 | extern crate gl;
2 | extern crate pi3d;
3 | extern crate sdl2;
4 |
5 | use std::ffi::CString;
6 |
7 | fn main() {
8 | // initially set up display, shader, camera, texture and shapes
9 | let mut display = pi3d::display::create(
10 | "shader source in code ESC to quit",
11 | 800.0,
12 | 500.0,
13 | "GLES",
14 | 3,
15 | 0,
16 | )
17 | .unwrap();
18 | display.set_background(&[0.4, 0.5, 0.4, 1.0]);
19 | display.set_opacity(0.9);
20 | let v_shader = pi3d::shader::Shader::from_source(
21 | &CString::new(
22 | "#version 300 es
23 | precision mediump float;
24 |
25 | layout(location = 0) in vec3 vertex; /// called vertex in pi3d
26 |
27 | void main()
28 | {
29 | gl_Position = vec4(vertex, 1.0);
30 | }",
31 | )
32 | .unwrap(),
33 | gl::VERTEX_SHADER,
34 | )
35 | .unwrap();
36 | /*
37 | // simple setup from github.com/Blakkis/GLSL_Python
38 | let f_shader = pi3d::shader::Shader::from_source(&CString::new(
39 | "#version 300 es
40 | precision mediump float;
41 | #define fragCoord gl_FragCoord.xy
42 | //uniform vec2 iMouse;
43 | //uniform float iTime; /// unif[19].z
44 | //uniform vec2 iResolution; /// unif[19].xy
45 | uniform vec3 unif[20];
46 | out vec4 fragColor;
47 | void main()
48 | {
49 | vec2 iResolution = unif[19].xy;
50 | float iTime = unif[19][2];
51 | // Set origin to center of the screen
52 | vec2 uv = fragCoord/iResolution.xy * 2.0 - 1.0;
53 | // Fix aspect ratio
54 | uv.x *= iResolution.x / iResolution.y;
55 | // Time varying pixel color (Copied from ShaderToy default scene)
56 | vec3 color = 0.5 + 0.5 * cos(iTime + uv.xyx + vec3(0.0, 2.0, 4.0));
57 | fragColor = vec4(color, 1.0);
58 | //fragColor = vec4(1.0, 1.0, 0.5, 1.0);
59 | }").unwrap(), gl::FRAGMENT_SHADER).unwrap();
60 | */
61 | // raymarch_mod setup from github.com/Blakkis/GLSL_Python
62 | let f_shader = pi3d::shader::Shader::from_source(
63 | &CString::new(
64 | "#version 300 es
65 | precision mediump float;
66 | #define fragCoord gl_FragCoord.xy
67 | //uniform vec2 iMouse; /// unif[18].xy
68 | //uniform float iTime; /// unif[19].z
69 | //uniform vec2 iResolution; /// unif[19].xy
70 | uniform vec3 unif[20];
71 | out vec4 fragColor;
72 |
73 | float sdSphere(vec3 p, float r) {
74 | return length(p) - r;
75 | }
76 |
77 | float map_the_world(in vec3 pos) {
78 | float iTime = unif[19].z;
79 | float displacement = sin(abs(4.0 * cos(iTime)) * pos.x) *
80 | sin(abs(4.0 * sin(iTime)) * pos.y) *
81 | sin(4.0 * pos.z) *
82 | (0.1 + abs(0.1 * sin(iTime * 2.0)));
83 | float sphere_0 = sdSphere(pos, 2.5) + displacement;
84 | return sphere_0;
85 | }
86 |
87 | vec3 calculate_normal(in vec3 pos) {
88 | const vec3 small_step = vec3(0.001, 0.0, 0.0);
89 | float gradient_x = map_the_world(pos + small_step.xyy) - map_the_world(pos - small_step.xyy);
90 | float gradient_y = map_the_world(pos + small_step.yxy) - map_the_world(pos - small_step.yxy);
91 | float gradient_z = map_the_world(pos + small_step.yyx) - map_the_world(pos - small_step.yyx);
92 | vec3 normal = vec3(gradient_x, gradient_y, gradient_z);
93 | return normalize(normal);
94 | }
95 |
96 | vec3 ray_march(in vec3 ro, in vec3 rd) {
97 | vec2 iMouse = unif[18].xy;
98 | float total_distance_traveled = 0.0;
99 | const int NUMBER_OF_STEPS = 128;
100 | const float MINIMUM_HIT_DISTANCE = 0.001;
101 | const float MAXIMUM_TRACE_DISTANCE = 512.0;
102 | const float AMBIENT = 0.2;
103 | for (int i = 0; i < NUMBER_OF_STEPS; ++i)
104 | {
105 | vec3 current_position = ro + total_distance_traveled * rd;
106 | float distance_to_closest = map_the_world(current_position);
107 | if (distance_to_closest < MINIMUM_HIT_DISTANCE)
108 | {
109 | vec3 normal = calculate_normal(current_position);
110 | vec3 light_position = vec3(-iMouse.x, iMouse.y, 4.0);
111 | vec3 direction_to_light = normalize(current_position - light_position);
112 | float diffuse_intensity = max(AMBIENT, pow(dot(normal, direction_to_light), 16.0));
113 | return vec3(1.0, 0.0, 0.0) * diffuse_intensity;
114 | }
115 | if (total_distance_traveled > MAXIMUM_TRACE_DISTANCE){
116 | break;
117 | }
118 | total_distance_traveled += distance_to_closest;
119 | }
120 | return vec3(0.0);
121 | }
122 |
123 | void main() {
124 | vec2 iResolution = unif[19].xy;
125 | vec2 uv = fragCoord / iResolution.xy * 2.0 - 1.0;
126 | uv.x *= iResolution.x / iResolution.y;
127 | vec3 camera_position = vec3(0.0, 0.0, -5.0);
128 | vec3 ray_origin = camera_position;
129 | vec3 ray_direction = vec3(uv, 1.0);
130 | vec3 result = ray_march(ray_origin, ray_direction);
131 | fragColor = vec4(result, 1.0);
132 | }
133 | ",
134 | )
135 | .unwrap(),
136 | gl::FRAGMENT_SHADER,
137 | )
138 | .unwrap();
139 |
140 | let shader = pi3d::shader::Program::from_shaders(&[v_shader, f_shader]).unwrap();
141 | let mut camera = pi3d::camera::create(&display);
142 | camera.set_3d(false); // make it a 2D shader
143 | let (w, h) = display.get_size();
144 | let mut slide = pi3d::shapes::plane::create(camera.reference(), 0.5 * w as f32, 0.5 * h as f32); // fullscreen
145 | slide.set_draw_details(&shader, &vec![], 1.0, 1.0, 1.0, 1.0, 1.0);
146 | slide.unif[[19, 0]] = w as f32;
147 | slide.unif[[19, 1]] = h as f32;
148 | let mut t: f32 = 0.0;
149 | let mut mx: f32 = 0.0;
150 | let mut my: f32 = 0.0;
151 | // draw in a loop
152 | while display.loop_running() {
153 | // default sdl2 check for ESC or click cross
154 | t += 0.0001; // v. approx time
155 | slide.unif[[19, 2]] = t;
156 | if display.mouse_moved {
157 | my = display.mouse_y as f32;
158 | mx = display.mouse_x as f32;
159 | }
160 | slide.unif[[18, 0]] = 2.0 * mx / w - 1.0;
161 | slide.unif[[18, 1]] = 2.0 * my / h - 1.0;
162 | slide.draw();
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/pi3d/examples/shaders/blend_new.fs:
--------------------------------------------------------------------------------
1 | #include std_head_fs.inc
2 |
3 | varying vec2 texcoordoutf;
4 | varying vec2 texcoordoutb;
5 |
6 | //fragcolor
7 |
8 | void main(void) {
9 | vec4 texf = texture2D(tex0, texcoordoutf);
10 | if (texcoordoutf[0] < 0.0 || texcoordoutf[0] > 1.0 ||
11 | texcoordoutf[1] < 0.0 || texcoordoutf[1] > 1.0) {
12 | texf.a = unif[15][2];
13 | }
14 | vec4 texb = texture2D(tex1, texcoordoutb);
15 | if (texcoordoutb[0] < 0.0 || texcoordoutb[0] > 1.0 ||
16 | texcoordoutb[1] < 0.0 || texcoordoutf[1] > 1.0) {
17 | texb.a = unif[15][2];
18 | }
19 |
20 | // blending
21 | float a = unif[14][2];
22 |
23 | // simple fade //////////////////////////////////////////////////////
24 | //gl_FragColor = mix(texb, texf, clamp(1.1 * a - 1.0, 0.0, 1.0));
25 |
26 | // burn /////////////////////////////////////////////////////////////
27 | float y = 1.0 - smoothstep(a + 0.1, a + 0.3, length(texf.rgb) * 0.5);
28 | gl_FragColor = mix(texb, texf * y, step(1.0, y));
29 |
30 | // bump /////////////////////////////////////////////////////////////
31 | //vec4 light = vec4(0.577, 0.577, 0.577, 1.0);
32 | //float ffact = dot(light, texf);
33 | //gl_FragColor = mix(texb * (1.0 + a * (ffact - 1.0)), texf, clamp(2.0 * a - 1.0, 0.0, 1.0));
34 | }
35 |
--------------------------------------------------------------------------------
/pi3d/examples/shaders/blend_new.vs:
--------------------------------------------------------------------------------
1 | #include std_head_vs.inc
2 |
3 | varying vec2 texcoordoutf;
4 | varying vec2 texcoordoutb;
5 |
6 | void main(void) {
7 | texcoordoutf = (texcoord * unif[14].xy - unif[16].xy);
8 | texcoordoutb = (texcoord * unif[15].xy - unif[17].xy);
9 | gl_Position = modelviewmatrix[1] * vec4(vertex, 1.0);
10 | dist = gl_Position.z;
11 | gl_PointSize = unib[2][2] / dist;
12 | }
--------------------------------------------------------------------------------
/pi3d/examples/shaders/farris_p67.fs:
--------------------------------------------------------------------------------
1 | #version 120
2 | //precision mediump float;
3 |
4 | varying vec2 texcoordout;
5 |
6 | uniform sampler2D tex0;
7 | uniform vec3 unif[20];
8 |
9 | //fragcolor
10 |
11 | float TWO_PI = radians(360.0);
12 | float ROOT_3 = sqrt(3.0);
13 |
14 |
15 | vec2 eul(float angle) {
16 | return vec2(cos(angle), sin(angle));
17 | }
18 |
19 | void main(void) {
20 | float F = unif[16][1]; // borrow R-rot
21 | float F1 = unif[11][0]; // borrow L-n1
22 | float F2 = unif[11][1]; // borrow L-m1
23 | vec2 z = texcoordout * F;
24 |
25 | vec2 uv_coord = (eul(TWO_PI * z.y) +
26 | eul(TWO_PI * (ROOT_3 * z.x - z.y) * F1) +
27 | eul(TWO_PI * (-ROOT_3 * z.x - z.y) * F2)) / 3.0 + 0.5;
28 | /* When F1 = F2 = 0.5 this is approximately as per Farris page 67 with
29 | the modification that rather then everything being divided by 3.0 it is
30 | divided by 6.0 and has 0.5 added this is to scale the uv coordinates to
31 | the mapping used by GLSL (0,0) in the top right corner and (1,1) bottom
32 | left
33 | */
34 | gl_FragColor = texture2D(tex0, uv_coord);
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/pi3d/examples/shaders/farris_p67.vs:
--------------------------------------------------------------------------------
1 | #version 120
2 | //precision mediump float;
3 |
4 | attribute vec3 vertex;
5 | attribute vec2 texcoord;
6 |
7 | uniform mat4 modelviewmatrix[2]; // 0 model movement in real coords, 1 in camera coords
8 | uniform vec3 unib[4];
9 | //uniform vec2 umult, vmult => unib[2]
10 | //uniform vec2 u_off, v_off => unib[3]
11 | uniform vec3 unif[20]; // hpe
12 |
13 | varying vec2 texcoordout;
14 |
15 | void main(void) {
16 | texcoordout = texcoord * unib[2].xy + unib[3].xy;
17 | gl_Position = modelviewmatrix[1] * vec4(vertex, 1.0);
18 | }
19 |
--------------------------------------------------------------------------------
/pi3d/examples/shaders/farris_p67a.fs:
--------------------------------------------------------------------------------
1 | #version 120
2 | //precision mediump float;
3 |
4 | varying vec2 texcoordout;
5 |
6 | uniform sampler2D tex0;
7 | uniform vec3 unif[20];
8 |
9 | //fragcolor
10 |
11 | float TWO_PI = radians(360.0);
12 | float ROOT_3 = sqrt(3.0);
13 | float F3 = 0.5;
14 | float Q_PI = radians(45.0);
15 |
16 | vec2 eul(float angle) {
17 | return vec2(cos(angle), sin(angle));
18 | }
19 |
20 | void main(void) {
21 | /* This shader is the same as farris_p67 apart from the pattern scaling
22 | z is fixed at 2.0 times the texcoord (which varies 0,0 top left to 1,1
23 | bottom right.) F now varies the amount of color rotation by multiplying with
24 | the x component of z. i.e. none at left and F at right.
25 |
26 | If the rgb vector is rotated about the origin the values will become
27 | negative for much of the time (and default is to clamp to range 0-1).
28 | So the vector from (0.5, 0.5, 0.5) to the rgp point is rotated about an
29 | orthogonal axis to that (i.e. (0, -b', g').dot(r', g', b') == 0) and the result
30 | has (0.5, 0.5, 0.5) added back to it. The result will still fall outside
31 | the 0-1 range occasionally but won't be too bad.
32 |
33 | The 3x3 matrix rot is standard for rotating about an axis
34 | */
35 | float F = unif[16][1]; // scales the color rotation
36 | float F1 = unif[11][0]; // borrow L-n1
37 | float F2 = unif[11][1]; // borrow L-m1
38 | vec2 z = texcoordout * 2.0;
39 |
40 | vec2 uv_coord = (eul(TWO_PI * z.y) +
41 | eul(TWO_PI * (ROOT_3 * z.x - z.y) * F1) +
42 | eul(TWO_PI * (-ROOT_3 * z.x - z.y) * F2)) / 6.0 + 0.5;
43 | gl_FragColor = texture2D(tex0, uv_coord) - vec4(0.5, 0.5, 0.5, 0.0); //keep alpha 1.0
44 | vec3 ax = normalize(vec3(0.0, gl_FragColor.z, -gl_FragColor.y)); // unit vector along axis
45 | float sa = sin(F * texcoordout.x * Q_PI);
46 | float ca = 1.0 - cos(F * texcoordout.x * Q_PI);
47 | mat3 rot = mat3(1.0 - ca, ax.z * sa, -ax.y * sa,
48 | -ax.y * sa, 1.0 + ca * (ax.y * ax.y - 1.0), ca * ax.y * ax.z,
49 | ax.y * sa, ca * ax.z * ax.y, 1.0 + ca * (ax.z * ax.z - 1.0));
50 |
51 | gl_FragColor.xyz = rot * gl_FragColor.xyz + vec3(0.5);
52 | }
53 |
54 |
--------------------------------------------------------------------------------
/pi3d/examples/shaders/farris_p67a.vs:
--------------------------------------------------------------------------------
1 | #version 120
2 | //precision mediump float;
3 |
4 | attribute vec3 vertex;
5 | attribute vec2 texcoord;
6 |
7 | uniform mat4 modelviewmatrix[2]; // 0 model movement in real coords, 1 in camera coords
8 | uniform vec3 unib[4];
9 | //uniform vec2 umult, vmult => unib[2]
10 | //uniform vec2 u_off, v_off => unib[3]
11 | uniform vec3 unif[20];
12 |
13 | varying vec2 texcoordout;
14 |
15 | void main(void) {
16 | texcoordout = texcoord * unib[2].xy + unib[3].xy;
17 | gl_Position = modelviewmatrix[1] * vec4(vertex, 1.0);
18 | }
19 |
--------------------------------------------------------------------------------
/pi3d/examples/shaders/farris_p67b.fs:
--------------------------------------------------------------------------------
1 | #version 120
2 | //precision mediump float;
3 |
4 | varying vec2 texcoordout;
5 |
6 | uniform sampler2D tex0;
7 | uniform vec3 unif[20];
8 |
9 | //fragcolor
10 |
11 | float TWO_PI = radians(360.0);
12 | float INV_RT3 = inversesqrt(3.0);
13 |
14 |
15 | vec2 eul(float angle) {
16 | return vec2(cos(angle), sin(angle));
17 | }
18 |
19 | vec2 W(float n, float m, vec2 z) {
20 | return (eul(TWO_PI * (n * z.x + (n + 2.0 * m) * z.y * INV_RT3)) +
21 | eul(TWO_PI * (m * z.x - (2.0 * n + m) * z.y * INV_RT3)) +
22 | eul(TWO_PI * (-(n + m) * z.x + (n - m) * z.y * INV_RT3))) / 3.0;
23 | }
24 |
25 | void main(void) {
26 | float mix_f = smoothstep(0.2, 0.8, texcoordout.x); // linear between 0->1 as x 0.2->0.8
27 | float n1 = mix(unif[11][0], unif[13][2], mix_f); // lerp between left value and right value
28 | float m1 = mix(unif[11][1], unif[14][0], mix_f);
29 | float ar1 = mix(unif[11][2], unif[14][1], mix_f);
30 | float ai1 = mix(unif[12][0], unif[14][2], mix_f);
31 | float n2 = mix(unif[12][1], unif[15][0], mix_f);
32 | float m2 = mix(unif[12][2], unif[15][1], mix_f);
33 | float ar2 = mix(unif[13][0], unif[15][2], mix_f);
34 | float ai2 = mix(unif[13][1], unif[16][0], mix_f);
35 |
36 | vec2 z = texcoordout * 4.0;
37 | /* This shader uses the Hexagonal lattice recipe P6 from Farris p213
38 | it scales z to value fixed above. n, m, a_real and a_imag are taken from
39 | unif as above. There are four Ws n1,m1 -n1,-m1 n2,m2 -n2,-m2 but these
40 | can be added in pairs because of the requirement for a_n,m == a_-n,-m
41 | */
42 | vec2 w1 = W(n1, m1, z) + W(-n1, -m1, z);
43 | vec2 w2 = W(n2, m2, z) + W(-n2, -m2, z);
44 | vec2 uv_coord = vec2(ar1 * w1.x - ai1 * w1.y + ar2 * w2.x - ai2 * w2.y,
45 | ar1 * w1.y + ai1 * w1.x + ar2 * w2.y + ai2 * w2.x);
46 | /* The right sample texture can be rotated by the passed in unif[16][1]
47 | which is pro-ratad across the width. The rotation is done by simple
48 | 2D rotation matrix as below. (vec2(0.5) adjustment to rotate about centre)
49 | */
50 | float c_angl = mix_f * unif[16][1];
51 | mat2 rotn = mat2(cos(c_angl), sin(c_angl),
52 | -sin(c_angl), cos(c_angl));
53 | gl_FragColor = texture2D(tex0, rotn * (uv_coord - vec2(0.5)) + vec2(0.5));
54 | }
55 |
56 |
--------------------------------------------------------------------------------
/pi3d/examples/shaders/farris_p67b.vs:
--------------------------------------------------------------------------------
1 | #version 120
2 | //precision mediump float;
3 |
4 | attribute vec3 vertex;
5 | attribute vec2 texcoord;
6 |
7 | uniform mat4 modelviewmatrix[2]; // 0 model movement in real coords, 1 in camera coords
8 | uniform vec3 unib[4];
9 | //uniform vec2 umult, vmult => unib[2]
10 | //uniform vec2 u_off, v_off => unib[3]
11 | uniform vec3 unif[20]; // hpe
12 |
13 | varying vec2 texcoordout;
14 |
15 | void main(void) {
16 | texcoordout = texcoord * unib[2].xy + unib[3].xy;
17 | gl_Position = modelviewmatrix[1] * vec4(vertex, 1.0);
18 | }
19 |
--------------------------------------------------------------------------------
/pi3d/examples/shaders/farris_p67b_ES30.fs:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision mediump float;
3 |
4 | in vec2 texcoordout;
5 |
6 | uniform sampler2D tex0;
7 | uniform vec3 unif[20];
8 |
9 | out vec4 fragColor;
10 |
11 | float TWO_PI = radians(360.0);
12 | float INV_RT3 = inversesqrt(3.0);
13 |
14 | vec2 eul(float angle) {
15 | return vec2(cos(angle), sin(angle));
16 | }
17 |
18 | vec2 W(float n, float m, vec2 z) {
19 | return (eul(TWO_PI * (n * z.x + (n + 2.0 * m) * z.y * INV_RT3)) +
20 | eul(TWO_PI * (m * z.x - (2.0 * n + m) * z.y * INV_RT3)) +
21 | eul(TWO_PI * (-(n + m) * z.x + (n - m) * z.y * INV_RT3))) / 3.0;
22 | }
23 |
24 | void main(void) {
25 | float mix_f = smoothstep(0.2, 0.8, texcoordout.x); // linear between 0->1 as x 0.2->0.8
26 | float n1 = mix(unif[11][0], unif[13][2], mix_f); // lerp between left value and right value
27 | float m1 = mix(unif[11][1], unif[14][0], mix_f);
28 | float ar1 = mix(unif[11][2], unif[14][1], mix_f);
29 | float ai1 = mix(unif[12][0], unif[14][2], mix_f);
30 | float n2 = mix(unif[12][1], unif[15][0], mix_f);
31 | float m2 = mix(unif[12][2], unif[15][1], mix_f);
32 | float ar2 = mix(unif[13][0], unif[15][2], mix_f);
33 | float ai2 = mix(unif[13][1], unif[16][0], mix_f);
34 |
35 | vec2 z = texcoordout * 4.0;
36 | /* This shader uses the Hexagonal lattice recipe P6 from Farris p213
37 | it scales z to value fixed above. n, m, a_real and a_imag are taken from
38 | unif as above. There are four Ws n1,m1 -n1,-m1 n2,m2 -n2,-m2 but these
39 | can be added in pairs because of the requirement for a_n,m == a_-n,-m
40 | */
41 | vec2 w1 = W(n1, m1, z) + W(-n1, -m1, z);
42 | vec2 w2 = W(n2, m2, z) + W(-n2, -m2, z);
43 | vec2 uv_coord = vec2(ar1 * w1.x - ai1 * w1.y + ar2 * w2.x - ai2 * w2.y,
44 | ar1 * w1.y + ai1 * w1.x + ar2 * w2.y + ai2 * w2.x);
45 | /* The right sample texture can be rotated by the passed in unif[16][1]
46 | which is pro-ratad across the width. The rotation is done by simple
47 | 2D rotation matrix as below. (vec2(0.5) adjustment to rotate about centre)
48 | */
49 | float c_angl = mix_f * unif[16][1];
50 | mat2 rotn = mat2(cos(c_angl), sin(c_angl),
51 | -sin(c_angl), cos(c_angl));
52 | fragColor = texture(tex0, rotn * (uv_coord - vec2(0.5)) + vec2(0.5));
53 | }
54 |
55 |
--------------------------------------------------------------------------------
/pi3d/examples/shaders/farris_p67b_ES30.vs:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision mediump float;
3 |
4 | in vec3 vertex;
5 | in vec2 texcoord;
6 |
7 | uniform mat4 modelviewmatrix[2]; // 0 model movement in real coords, 1 in camera coords
8 | uniform vec3 unib[4];
9 | //uniform vec2 umult, vmult => unib[2]
10 | //uniform vec2 u_off, v_off => unib[3]
11 | uniform vec3 unif[20]; // hpe
12 |
13 | out vec2 texcoordout;
14 |
15 | void main(void) {
16 | texcoordout = texcoord * unib[2].xy + unib[3].xy;
17 | gl_Position = modelviewmatrix[1] * vec4(vertex, 1.0);
18 | }
19 |
--------------------------------------------------------------------------------
/pi3d/examples/shaders/farris_p6_6term.fs:
--------------------------------------------------------------------------------
1 | #version 120
2 | //precision mediump float;
3 |
4 | varying vec2 texcoordout;
5 |
6 | uniform sampler2D tex0;
7 | uniform vec3 unif[20];
8 |
9 | //fragcolor
10 |
11 | float TWO_PI = radians(360.0);
12 | float INV_RT3 = inversesqrt(3.0);
13 |
14 |
15 | vec2 eul(float angle) {
16 | return vec2(cos(angle), sin(angle));
17 | }
18 |
19 | vec2 W(float n, float m, vec2 z) {
20 | return (eul(TWO_PI * (n * z.x + (n + 2.0 * m) * z.y * INV_RT3)) +
21 | eul(TWO_PI * (m * z.x - (2.0 * n + m) * z.y * INV_RT3)) +
22 | eul(TWO_PI * (-(n + m) * z.x + (n - m) * z.y * INV_RT3))) / 3.0;
23 | }
24 |
25 | void main(void) {
26 | float mix_f = smoothstep(0.2, 0.8, texcoordout.x); // linear between 0->1 as x 0.2->0.8
27 | float n1 = mix(unif[11][0], unif[15][0], mix_f); // lerp between left value and right value
28 | float m1 = mix(unif[11][1], unif[15][1], mix_f);
29 | float ar1 = mix(unif[11][2], unif[15][2], mix_f);
30 | float ai1 = mix(unif[12][0], unif[16][0], mix_f);
31 | float n2 = mix(unif[12][1], unif[16][1], mix_f);
32 | float m2 = mix(unif[12][2], unif[16][2], mix_f);
33 | float ar2 = mix(unif[13][0], unif[17][0], mix_f);
34 | float ai2 = mix(unif[13][1], unif[17][1], mix_f);
35 | float n3 = mix(unif[13][2], unif[17][2], mix_f);
36 | float m3 = mix(unif[14][0], unif[18][0], mix_f);
37 | float ar3 = mix(unif[14][1], unif[18][1], mix_f);
38 | float ai3 = mix(unif[14][2], unif[18][2], mix_f);
39 |
40 | vec2 z = texcoordout * 4.0;
41 | /* This shader uses the Hexagonal lattice recipe P6 from Farris p213
42 | it scales z to value fixed above. n, m, a_real and a_imag are taken from
43 | unif as above. There are four Ws n1,m1 -n1,-m1 n2,m2 -n2,-m2 but these
44 | can be added in pairs because of the requirement for a_n,m == a_-n,-m
45 | */
46 | vec2 w1 = W(n1, m1, z) + W(-n1, -m1, z);
47 | vec2 w2 = W(n2, m2, z) + W(-n2, -m2, z);
48 | vec2 w3 = W(n3, m3, z) + W(-n3, -m3, z);
49 | vec2 uv_coord = vec2(ar1 * w1.x - ai1 * w1.y + ar2 * w2.x - ai2 * w2.y + ar3 * w3.x - ai3 * w3.y,
50 | ar1 * w1.y + ai1 * w1.x + ar2 * w2.y + ai2 * w2.x + ar3 * w3.y + ai3 * w3.x);
51 | /* The right sample texture can be rotated by the passed in unif[16][0]
52 | which is pro-ratad across the width. The rotation is done by simple
53 | 2D rotation matrix as below. (vec2(0.5) adjustment to rotate about centre)
54 | */
55 | float c_angl = mix_f * unif[19][0];
56 | mat2 rotn = mat2(cos(c_angl), sin(c_angl),
57 | -sin(c_angl), cos(c_angl));
58 | gl_FragColor = texture2D(tex0, rotn * (uv_coord - vec2(0.5)) + vec2(0.5));
59 |
60 | }
61 |
62 |
--------------------------------------------------------------------------------
/pi3d/examples/shaders/farris_p6_6term.vs:
--------------------------------------------------------------------------------
1 | #version 120
2 | //precision mediump float;
3 |
4 | attribute vec3 vertex;
5 | attribute vec2 texcoord;
6 |
7 | uniform mat4 modelviewmatrix[2]; // 0 model movement in real coords, 1 in camera coords
8 | uniform vec3 unib[4];
9 | //uniform vec2 umult, vmult => unib[2]
10 | //uniform vec2 u_off, v_off => unib[3]
11 | uniform vec3 unif[20]; // hpe
12 |
13 | varying vec2 texcoordout;
14 |
15 | void main(void) {
16 | texcoordout = texcoord * unib[2].xy + unib[3].xy;
17 | gl_Position = modelviewmatrix[1] * vec4(vertex, 1.0);
18 | }
19 |
--------------------------------------------------------------------------------
/pi3d/examples/shaders/triangle.fs:
--------------------------------------------------------------------------------
1 | #version 120
2 | //precision mediump float;
3 |
4 | uniform sampler2D tex0;
5 | uniform sampler2D tex1;
6 | uniform sampler2D tex2;
7 | uniform vec3 unib[4];
8 | // see docstring Buffer
9 | uniform vec3 unif[20];
10 | // see docstring Shape
11 |
12 | varying float dist;
13 | varying float fog_start;
14 | varying vec3 normout;
15 | varying vec2 texcoordout;
16 | varying vec3 lightVector;
17 | varying float lightFactor;
18 |
19 | //fragcolor
20 |
21 | void main(void) {
22 | vec4 texc = texture2D(tex0, texcoordout); // ------ material or basic colour from texture
23 | if (texc.a < unib[0][2]) discard; // ------ to allow rendering behind the transparent parts of this object
24 | texc.rgb += unib[1] - vec3(0.5);
25 | float ffact = smoothstep(fog_start, unif[5][0], dist); // ------ smoothly increase fog between 1/3 and full fogdist
26 | float intensity = clamp(dot(lightVector, vec3(0.0, 0.0, 1.0)) * lightFactor, 0.0, 1.0); // ------ adjustment of colour according to combined normal
27 | texc.rgb = (texc.rgb * unif[9]) * intensity + (texc.rgb * unif[10]); // ------ directional lightcol * intensity + ambient lightcol
28 | gl_FragColor = (1.0 - ffact) * texc + ffact * vec4(unif[4], unif[5][1]); // ------ combine using factors
29 | gl_FragColor.a *= unif[5][2];
30 | }
31 |
--------------------------------------------------------------------------------
/pi3d/examples/shaders/triangle.vs:
--------------------------------------------------------------------------------
1 | #version 120
2 | //precision mediump float;
3 |
4 | attribute vec3 vertex;
5 | attribute vec3 normal;
6 | attribute vec2 texcoord;
7 |
8 | uniform mat4 modelviewmatrix[3]; // [0] model movement in real coords, [1] in camera coords, [2] camera at light
9 | uniform vec3 unib[4];
10 | //uniform float ntiles => unib[0][0]
11 | //uniform vec2 umult, vmult => unib[2]
12 | //uniform vec2 u_off, v_off => unib[3]
13 | uniform vec3 unif[20];
14 | //uniform vec3 eye > unif[6]
15 | //uniform vec3 lightpos > unif[8]
16 |
17 | varying float dist;
18 | varying float fog_start;
19 |
20 | varying vec2 texcoordout;
21 | varying vec3 lightVector;
22 | varying float lightFactor;
23 |
24 | void main(void) {
25 | vec3 normout;
26 | vec4 relPosn = modelviewmatrix[0] * vec4(vertex, 1.0);
27 |
28 | if (unif[7][0] == 1.0) { // this is a point light and unif[8] is location
29 | lightVector = vec3(relPosn) - unif[8];
30 | lightFactor = pow(length(lightVector), -2.0);
31 | lightVector = normalize(lightVector);
32 | lightVector.z *= -1.0;
33 | } else { // this is directional light
34 | lightVector = normalize(unif[8]);
35 | lightFactor = 1.0;
36 | }
37 | lightVector.z *= -1.0;
38 | // uvec, vvec are tangent and bitangent vectors at the vertex approx
39 | // lining up with the uv texture mapping. Because (0, 1, 0) is such a
40 | // common normal direction uvec is generated using just off vertical
41 | vec3 uvec = normalize(cross(normal, vec3(0.0003, -1.0, 0.0003)));
42 | vec3 vvec = normalize(cross(uvec, normal));
43 | normout = normalize(vec3(modelviewmatrix[0] * vec4(normal, 0.0)));
44 | uvec = vec3(modelviewmatrix[0] * vec4(uvec, 0.0));
45 | vvec = vec3(modelviewmatrix[0] * vec4(vvec, 0.0));
46 |
47 | lightVector = vec3(mat4(uvec.x, vvec.x, -normout.x, 0.0,
48 | uvec.y, vvec.y, -normout.y, 0.0,
49 | uvec.z, vvec.z, -normout.z, 0.0,
50 | 0.0, 0.0, 0.0, 1.0) * vec4(lightVector, 0.0));
51 |
52 | vec3 inray = vec3(relPosn - vec4(unif[6], 0.0)); // ----- vector from the camera to this vertex
53 | dist = length(inray);
54 | fog_start = fract(unif[5][0]);
55 | if (fog_start == 0.0) {
56 | fog_start = unif[5][0] * 0.333;
57 | } else {
58 | fog_start *= unif[5][0];
59 | }
60 |
61 | texcoordout = texcoord * unib[2].xy + unib[3].xy;
62 |
63 | gl_Position = modelviewmatrix[1] * vec4(vertex,1.0);
64 | gl_PointSize = unib[2][2] / dist;
65 | }
66 |
--------------------------------------------------------------------------------
/pi3d/examples/shaders/uv_flat_ES30.fs:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision mediump float;
3 |
4 | uniform sampler2D tex0;
5 | uniform sampler2D tex1;
6 | uniform sampler2D tex2;
7 | uniform vec3 unib[5];
8 | // see docstring Buffer
9 | uniform vec3 unif[20];
10 | // see docstring Shape
11 |
12 | in float dist;
13 | in float fog_start;
14 | in vec2 texcoordout;
15 |
16 | out vec4 fragColor;
17 |
18 | void main(void) {
19 | //std_main_uv.inc
20 | // ----- boiler-plate code for fragment shaders with uv textures
21 |
22 | // NB previous define: tex0, texcoordout, unib, unif, dist
23 |
24 | vec4 texc = texture(tex0, texcoordout); // ------ material or basic colour from texture
25 | if (texc.a < unib[0][2]) discard; // ------ to allow rendering behind the transparent parts of this object
26 | texc.rgb += unib[1] - vec3(0.5);
27 | float ffact = smoothstep(fog_start, unif[5][0], dist); // ------ smoothly increase fog between 1/3 and full fogdist
28 |
29 | fragColor = mix(texc, vec4(unif[4], unif[5][1]), ffact); // ------ combine using factors
30 | fragColor.a *= unif[5][2];
31 | }
32 |
--------------------------------------------------------------------------------
/pi3d/examples/shaders/uv_flat_ES30.vs:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision mediump float;
3 |
4 | in vec3 vertex;
5 | in vec3 normal;
6 | in vec2 texcoord;
7 |
8 | uniform mat4 modelviewmatrix[3]; // [0] model movement in real coords, [1] in camera coords, [2] camera at light
9 | uniform vec3 unib[5];
10 | //uniform float ntiles => unib[0][0]
11 | //uniform vec2 umult, vmult => unib[2]
12 | //uniform vec2 u_off, v_off => unib[3]
13 | uniform vec3 unif[20];
14 | //uniform vec3 eye > unif[6]
15 | //uniform vec3 lightpos > unif[8]
16 |
17 | out float dist;
18 | out float fog_start;
19 | out vec2 texcoordout;
20 |
21 | void main(void) {
22 | texcoordout = texcoord * unib[2].xy + unib[3].xy;
23 | gl_Position = modelviewmatrix[1] * vec4(vertex,1.0);
24 | dist = gl_Position.z;
25 | //std_fog_start.inc
26 | //NB previousl (in std_head_vs.inc) define fog_start and unif[20]
27 | fog_start = fract(unif[5][0]);
28 | if (fog_start == 0.0) {
29 | fog_start = unif[5][0] * 0.333;
30 | } else {
31 | fog_start *= unif[5][0];
32 | } gl_PointSize = unib[2][2] / dist;
33 | }
34 |
--------------------------------------------------------------------------------
/pi3d/examples/shaders/uv_light.fs:
--------------------------------------------------------------------------------
1 | #version 120
2 | //precision mediump float;
3 |
4 | uniform sampler2D tex0;
5 | uniform sampler2D tex1;
6 | uniform sampler2D tex2;
7 | uniform vec3 unib[4];
8 | // see docstring Buffer
9 | uniform vec3 unif[20];
10 | // see docstring Shape
11 |
12 | varying float dist;
13 | varying float fog_start;
14 | varying vec3 normout;
15 | varying vec2 texcoordout;
16 | varying vec3 lightVector;
17 | varying float lightFactor;
18 |
19 | //fragcolor
20 |
21 | void main(void) {
22 | vec4 texc = texture2D(tex0, texcoordout); // ------ material or basic colour from texture
23 | if (texc.a < unib[0][2]) discard; // ------ to allow rendering behind the transparent parts of this object
24 | texc.rgb += unib[1] - vec3(0.5);
25 | float ffact = smoothstep(fog_start, unif[5][0], dist); // ------ smoothly increase fog between 1/3 and full fogdist
26 | float intensity = clamp(dot(lightVector, vec3(0.0, 0.0, 1.0)) * lightFactor, 0.0, 1.0); // ------ adjustment of colour according to combined normal
27 | texc.rgb = (texc.rgb * unif[9]) * intensity + (texc.rgb * unif[10]); // ------ directional lightcol * intensity + ambient lightcol
28 |
29 | gl_FragColor = (1.0 - ffact) * texc + ffact * vec4(unif[4], unif[5][1]); // ------ combine using factors
30 | gl_FragColor.a *= unif[5][2];
31 | }
32 |
33 |
34 |
--------------------------------------------------------------------------------
/pi3d/examples/shaders/uv_light.vs:
--------------------------------------------------------------------------------
1 | #version 120
2 | //precision mediump float;
3 |
4 | attribute vec3 vertex;
5 | attribute vec3 normal;
6 | attribute vec2 texcoord;
7 |
8 | uniform mat4 modelviewmatrix[3]; // [0] model movement in real coords, [1] in camera coords, [2] camera at light
9 | uniform vec3 unib[4];
10 | //uniform float ntiles => unib[0][0]
11 | //uniform vec2 umult, vmult => unib[2]
12 | //uniform vec2 u_off, v_off => unib[3]
13 | uniform vec3 unif[20];
14 | //uniform vec3 eye > unif[6]
15 | //uniform vec3 lightpos > unif[8]
16 |
17 | varying float dist;
18 | varying float fog_start;
19 |
20 | varying vec2 texcoordout;
21 | varying vec3 lightVector;
22 | varying float lightFactor;
23 |
24 | void main(void) {
25 | vec3 normout;
26 | vec4 relPosn = modelviewmatrix[0] * vec4(vertex, 1.0);
27 |
28 | if (unif[7][0] == 1.0) { // this is a point light and unif[8] is location
29 | lightVector = vec3(relPosn) - unif[8];
30 | lightFactor = pow(length(lightVector), -2.0);
31 | lightVector = normalize(lightVector);
32 | lightVector.z *= -1.0;
33 | } else { // this is directional light
34 | lightVector = normalize(unif[8]);
35 | lightFactor = 1.0;
36 | }
37 | lightVector.z *= -1.0;
38 | // uvec, vvec are tangent and bitangent vectors at the vertex approx
39 | // lining up with the uv texture mapping. Because (0, 1, 0) is such a
40 | // common normal direction uvec is generated using just off vertical
41 | vec3 uvec = normalize(cross(normal, vec3(0.0003, -1.0, 0.0003)));
42 | vec3 vvec = normalize(cross(uvec, normal));
43 | normout = normalize(vec3(modelviewmatrix[0] * vec4(normal, 0.0)));
44 | uvec = vec3(modelviewmatrix[0] * vec4(uvec, 0.0));
45 | vvec = vec3(modelviewmatrix[0] * vec4(vvec, 0.0));
46 |
47 | lightVector = vec3(mat4(uvec.x, vvec.x, -normout.x, 0.0,
48 | uvec.y, vvec.y, -normout.y, 0.0,
49 | uvec.z, vvec.z, -normout.z, 0.0,
50 | 0.0, 0.0, 0.0, 1.0) * vec4(lightVector, 0.0));
51 |
52 | vec3 inray = vec3(relPosn - vec4(unif[6], 0.0)); // ----- vector from the camera to this vertex
53 | dist = length(inray);
54 | fog_start = fract(unif[5][0]);
55 | if (fog_start == 0.0) {
56 | fog_start = unif[5][0] * 0.333;
57 | } else {
58 | fog_start *= unif[5][0];
59 | }
60 |
61 | texcoordout = texcoord * unib[2].xy + unib[3].xy;
62 |
63 | gl_Position = modelviewmatrix[1] * vec4(vertex,1.0);
64 | gl_PointSize = unib[2][2] / dist;
65 | }
66 |
--------------------------------------------------------------------------------
/pi3d/examples/shaders/uv_pointsprite_ES30.fs:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision mediump float;
3 |
4 | uniform sampler2D tex0;
5 | uniform vec3 unib[5];
6 |
7 | in float dist;
8 | in mat2 rotn;
9 | in vec2 corner;
10 | in float subsize;
11 | in float alpha;
12 | in vec4 colour;
13 |
14 | out vec4 fragColor;
15 |
16 | const vec2 p_centre = vec2(0.5);
17 | const vec2 limit = vec2(0.6);
18 |
19 | void main(void) {
20 | vec2 rot_coord = rotn * (gl_PointCoord - p_centre);
21 | if (any(greaterThan(abs(rot_coord), limit))) discard;
22 | rot_coord += p_centre;
23 | vec4 texc = texture(tex0, (rot_coord * subsize + corner));
24 | if (texc.a < unib[0][2]) discard; // ------ to allow rendering behind the transparent parts of this object
25 | fragColor = colour * texc;
26 | //fragColor.a *= texc.a;
27 | }
28 |
--------------------------------------------------------------------------------
/pi3d/examples/shaders/uv_pointsprite_ES30.vs:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision mediump float;
3 |
4 | in vec3 vertex;
5 | in vec3 normal;
6 | in vec2 texcoord;
7 |
8 | uniform mat4 modelviewmatrix[2]; // [0] model movement in real coords, [1] in camera coords
9 | uniform vec3 unib[5];
10 | //uniform float ntiles => unib[0][0]
11 | //uniform vec2 umult, vmult => unib[2]
12 | //uniform vec2 u_off, v_off => unib[3]
13 | uniform vec3 unif[20];
14 |
15 | out float dist;
16 | out mat2 rotn;
17 | out vec2 corner;
18 | out float subsize;
19 | out vec4 colour;
20 |
21 | void main(void) {
22 | gl_Position = modelviewmatrix[1] * vec4(vertex,1.0);
23 | dist = vertex[2];
24 | rotn = mat2(cos(normal[0]), sin(normal[0]),
25 | -sin(normal[0]), cos(normal[0]));
26 | gl_PointSize = unib[2][2] * fract(dist);
27 | corner = texcoord;
28 | subsize = unif[16][0];
29 | colour = vec4(normal[1]/1000.0, fract(normal[1]), normal[2]/1000.0, fract(normal[2]) );
30 | }
31 |
--------------------------------------------------------------------------------
/pi3d/examples/ship_demo.rs:
--------------------------------------------------------------------------------
1 | extern crate pi3d;
2 | extern crate rand;
3 | extern crate sdl2;
4 | use sdl2::keyboard::Keycode;
5 |
6 | const W: f32 = 1920.0;
7 | const H: f32 = 1080.0;
8 |
9 | fn main() {
10 | let mut display =
11 | pi3d::display::create("ship_demo (C Tim Skillman) window", W, H, "GL", 2, 1).unwrap();
12 | display.set_background(&[0.1, 0.1, 0.2, 1.0]);
13 | display.set_mouse_relative(true);
14 | display.set_target_fps(1000.0);
15 | let flatsh = pi3d::shader::Program::from_res("uv_flat").unwrap();
16 | let textsh = pi3d::shader::Program::from_res("uv_pointsprite").unwrap();
17 | let mut camera = pi3d::camera::create(&display);
18 | let mut camera2d = pi3d::camera::create(&display);
19 | camera2d.set_3d(false);
20 |
21 | let font = pi3d::util::font::create("fonts/NotoSans-Regular.ttf", "", "ęĻ", 64.0);
22 |
23 | let (mut cargo_hold, _texlist) =
24 | pi3d::shapes::model_obj::create(camera.reference(), "models/CargoHoldBaked2.obj");
25 | cargo_hold.set_shader(&flatsh);
26 | cargo_hold.set_material(&[0.4, 0.4, 0.4]);
27 | cargo_hold.set_fog(&[0.3, 0.3, 0.3], 200.2, 1.0);
28 | let mut radar_num: usize = 0;
29 | for k in 0..cargo_hold.buf.len() {
30 | if cargo_hold.buf[k].array_buffer[[0, 0]] == 97.226921 {
31 | radar_num = k;
32 | break;
33 | }
34 | }
35 |
36 | let (mut ecube, _tex_list) = pi3d::shapes::environment_cube::create(
37 | camera.reference(),
38 | 500.0,
39 | "models/maps/sbox_512",
40 | "png",
41 | );
42 | ecube.set_shader(&flatsh);
43 |
44 | // fps counter
45 | let mut fps_text = pi3d::shapes::point_text::create(camera2d.reference(), &font, 20, 24.0);
46 | fps_text.set_shader(&textsh);
47 | let fps_blk = fps_text.add_text_block(
48 | &font,
49 | &[-W * 0.5 + 20.0, -H * 0.5 + 20.0, 0.1],
50 | 19,
51 | "00.0 FPS",
52 | );
53 |
54 | let mut n: usize = 0;
55 | let mut x: f32 = 0.0;
56 | let mut y: f32 = 0.0;
57 | let mut z: f32 = -0.1;
58 | let mut df: f32 = 0.01;
59 | let mut ds: f32 = 0.0;
60 | let mut rot: f32 = 0.0;
61 | let mut tilt: f32 = 0.0;
62 |
63 | while display.loop_running() {
64 | ecube.draw();
65 | cargo_hold.draw();
66 | fps_text.set_text(&font, fps_blk, &format!("{:5.1} FPS", display.fps()));
67 | fps_text.draw();
68 |
69 | n += 1;
70 | if n > 5 {
71 | cargo_hold.buf[radar_num].unib[[3, 0]] += 0.083333;
72 | if cargo_hold.buf[radar_num].unib[[3, 0]] > 1.0 {
73 | cargo_hold.buf[radar_num].unib[[3, 0]] = 0.0;
74 | }
75 | n = 0;
76 | }
77 |
78 | if display.keys_pressed.contains(&Keycode::Escape) {
79 | break;
80 | }
81 | if display.mouse_moved {
82 | tilt = (display.mouse_y as f32 - 300.0) * 0.005;
83 | rot = (display.mouse_x as f32 - 400.0) * 0.005;
84 | }
85 | if display.keys_pressed.contains(&Keycode::W) {
86 | df = 0.5
87 | }
88 | if display.keys_pressed.contains(&Keycode::S) {
89 | df = -0.25;
90 | }
91 | if display.keys_pressed.contains(&Keycode::A) {
92 | ds = 0.25;
93 | }
94 | if display.keys_pressed.contains(&Keycode::D) {
95 | ds = -0.25;
96 | }
97 | let cd = camera.get_direction();
98 | x += cd[0] * df - cd[2] * ds;
99 | y += cd[1] * df;
100 | z += cd[2] * df + cd[0] * ds;
101 | camera.reset();
102 | camera.rotate(&[tilt, rot, 0.0]);
103 | if df != 0.0 || ds != 0.0 {
104 | //let (newy, _mapnorm) = pi3d::shapes::elevation_map::calc_height(&map, x, z);
105 | //y = newy + 5.0;
106 | camera.position(&[x, y, z]);
107 | }
108 | ds = 0.0;
109 | df = 0.0;
110 | }
111 | }
112 |
113 | // ==========================================================================
114 | // ship_demo models and image files used by this code made by Tim Skillman
115 | // ==========================================================================
116 | //
117 | // The MIT License
118 | //
119 | // Copyright (c) 2019 Tim Skillman
120 | //
121 | // Permission is hereby granted, free of charge, to any person obtaining a copy
122 | // of this software and associated documentation files (the "Software"), to deal
123 | // in the Software without restriction, including without limitation the rights
124 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
125 | // copies of the Software, and to permit persons to whom the Software is
126 | // furnished to do so, subject to the following conditions:
127 | //
128 | // The above copyright notice and this permission notice shall be included in
129 | // all copies or substantial portions of the Software.
130 | //
131 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
132 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
133 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
134 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
135 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
136 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
137 | // THE SOFTWARE.
138 | //
139 | // Dedicated to the One who has blessed me beyond my dreams ...
140 | // Jesus Christ, King of Kings and Lord of Lords :-)
141 | // =======================================================================
142 |
--------------------------------------------------------------------------------
/pi3d/examples/textures/floor_nm.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/textures/floor_nm.jpg
--------------------------------------------------------------------------------
/pi3d/examples/textures/grasstile_n.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/textures/grasstile_n.jpg
--------------------------------------------------------------------------------
/pi3d/examples/textures/hornbeam2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/textures/hornbeam2.png
--------------------------------------------------------------------------------
/pi3d/examples/textures/mountains3_512.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/textures/mountains3_512.jpg
--------------------------------------------------------------------------------
/pi3d/examples/textures/mountainsHgt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/textures/mountainsHgt.png
--------------------------------------------------------------------------------
/pi3d/examples/textures/pattern.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/textures/pattern.png
--------------------------------------------------------------------------------
/pi3d/examples/textures/poppy1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/textures/poppy1.jpg
--------------------------------------------------------------------------------
/pi3d/examples/textures/stars.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/textures/stars.jpg
--------------------------------------------------------------------------------
/pi3d/examples/textures/tree1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/textures/tree1.png
--------------------------------------------------------------------------------
/pi3d/examples/textures/tree2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/examples/textures/tree2.png
--------------------------------------------------------------------------------
/pi3d/src/lib.rs:
--------------------------------------------------------------------------------
1 | #[macro_use(s)]
2 | extern crate ndarray;
3 | extern crate gl;
4 | extern crate image;
5 | extern crate rusttype;
6 | #[macro_use]
7 | extern crate lazy_static;
8 |
9 | use std::path::PathBuf;
10 |
11 | lazy_static! {
12 | static ref EXE_PATH: PathBuf = std::env::current_exe().unwrap()
13 | .parent().unwrap()
14 | .into();
15 | static ref CURRENT_DIR: PathBuf = std::env::current_dir().unwrap();
16 | static ref GL_ID: String = {
17 | // NB must be run after GL initialized
18 | let mut gl_str = String::from("");
19 | unsafe {
20 | let version = gl::GetString(gl::VERSION);
21 | for i in 0..12 {
22 | if version.add(i).is_null() || *version.add(1) == 0 {
23 | break;
24 | }
25 | gl_str.push(*version.add(i) as char);
26 | }
27 | }
28 | let mut gl_id = String::from("GL");
29 | if gl_str.contains("ES") {
30 | gl_id.push_str("ES");
31 | }
32 | for s in gl_str.split(' ') {
33 | if s.contains('.') {
34 | for n in s.split('.').take(2) {
35 | gl_id.push_str(n);
36 | }
37 | break;
38 | }
39 | }
40 | gl_id
41 | };
42 | }
43 |
44 | pub mod buffer;
45 | pub mod camera;
46 | pub mod display;
47 | pub mod shader;
48 | pub mod shape;
49 | pub mod texture;
50 |
51 | pub mod shaders;
52 | pub mod shapes;
53 | pub mod util;
54 |
--------------------------------------------------------------------------------
/pi3d/src/light.rs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pi3d/src/light.rs
--------------------------------------------------------------------------------
/pi3d/src/shaders/mod.rs:
--------------------------------------------------------------------------------
1 | pub mod built_in_shaders;
2 |
--------------------------------------------------------------------------------
/pi3d/src/shapes/cone.rs:
--------------------------------------------------------------------------------
1 | use std::cell::RefCell;
2 | use std::rc::Rc;
3 | use crate::{camera, shape, shapes};
4 |
5 | pub fn create(
6 | cam: Rc>,
7 | radius: f32,
8 | height: f32,
9 | sides: usize,
10 | ) -> shape::Shape {
11 | let path: Vec<[f32; 2]> = vec![
12 | [0.0, height * 0.5],
13 | [radius * 0.999, -height * 0.499],
14 | [radius, -height * 0.5],
15 | [radius * 0.999, -height * 0.5],
16 | [0.0, -height * 0.5],
17 | ];
18 |
19 | shapes::lathe::create(cam, path, sides, 0.0, 1.0)
20 | }
21 |
--------------------------------------------------------------------------------
/pi3d/src/shapes/cuboid.rs:
--------------------------------------------------------------------------------
1 | use ndarray as nd;
2 | use std::cell::RefCell;
3 | use std::rc::Rc;
4 | use crate::{camera, shape, shader, buffer};
5 |
6 | pub fn create(
7 | cam: Rc>,
8 | w: f32,
9 | h: f32,
10 | d: f32,
11 | tw: f32,
12 | th: f32,
13 | td: f32,
14 | ) -> shape::Shape {
15 | let wh = w * 0.5;
16 | let hh = h * 0.5;
17 | let dh = d * 0.5;
18 | let verts: nd::Array2 = nd::arr2(&[
19 | [-wh, hh, dh],
20 | [wh, hh, dh],
21 | [wh, -hh, dh],
22 | [-wh, -hh, dh],
23 | [wh, hh, dh],
24 | [wh, hh, -dh],
25 | [wh, -hh, -dh],
26 | [wh, -hh, dh],
27 | [-wh, hh, dh],
28 | [-wh, hh, -dh],
29 | [wh, hh, -dh],
30 | [wh, hh, dh],
31 | [wh, -hh, dh],
32 | [wh, -hh, -dh],
33 | [-wh, -hh, -dh],
34 | [-wh, -hh, dh],
35 | [-wh, -hh, dh],
36 | [-wh, -hh, -dh],
37 | [-wh, hh, -dh],
38 | [-wh, hh, dh],
39 | [-wh, hh, -dh],
40 | [-wh, -hh, -dh],
41 | [wh, -hh, -dh],
42 | [wh, hh, -dh],
43 | [0.0, 0.0, 0.0],
44 | ]);
45 | let norms: nd::Array2 = nd::arr2(&[
46 | [0.0, 0.0, 1.0],
47 | [0.0, 0.0, 1.0],
48 | [0.0, 0.0, 1.0],
49 | [0.0, 0.0, 1.0],
50 | [1.0, 0.0, 0.0],
51 | [1.0, 0.0, 0.0],
52 | [1.0, 0.0, 0.0],
53 | [1.0, 0.0, 0.0],
54 | [0.0, 1.0, 0.0],
55 | [0.0, 1.0, 0.0],
56 | [0.0, 1.0, 0.0],
57 | [0.0, 1.0, 0.0],
58 | [0.0, -1.0, 0.0],
59 | [0.0, -1.0, 0.0],
60 | [0.0, -1.0, 0.0],
61 | [0.0, -1.0, 0.0],
62 | [-1.0, 0.0, 0.0],
63 | [-1.0, 0.0, 0.0],
64 | [-1.0, 0.0, 0.0],
65 | [-1.0, 0.0, 0.0],
66 | [0.0, 0.0, -1.0],
67 | [0.0, 0.0, -1.0],
68 | [0.0, 0.0, -1.0],
69 | [0.0, 0.0, -1.0],
70 | [0.0, 0.0, 0.0],
71 | ]);
72 | let tw = tw * 0.5;
73 | let th = th * 0.5;
74 | let td = td * 0.5;
75 | let texcoords: nd::Array2 = nd::arr2(&[
76 | [0.5 + tw, 0.5 - th],
77 | [0.5 - tw, 0.5 - th],
78 | [0.5 - tw, 0.5 + th],
79 | [0.5 + tw, 0.5 + th], // tw x th
80 | [0.5 + td, 0.5 - th],
81 | [0.5 - td, 0.5 - th],
82 | [0.5 - td, 0.5 + th],
83 | [0.5 + td, 0.5 + th], // td x th
84 | [0.5 + tw, 0.5 + td],
85 | [0.5 + tw, 0.5 - td],
86 | [0.5 - tw, 0.5 - td],
87 | [0.5 - tw, 0.5 + td], // tw x td
88 | [0.5 + tw, 0.5 + td],
89 | [0.5 + tw, 0.5 - td],
90 | [0.5 - tw, 0.5 - td],
91 | [0.5 - tw, 0.5 + td], // tw x td
92 | [0.5 - td, 0.5 + th],
93 | [0.5 + td, 0.5 + th],
94 | [0.5 + td, 0.5 - th],
95 | [0.5 - td, 0.5 - th], // td x th
96 | [0.5 - tw, 0.5 - th],
97 | [0.5 - tw, 0.5 + th],
98 | [0.5 + tw, 0.5 + th],
99 | [0.5 + tw, 0.5 - th],
100 | [0.0, 0.0], // tw x th
101 | ]);
102 | let faces: nd::Array2 = nd::arr2(&[
103 | [1, 0, 3],
104 | [3, 2, 1],
105 | [5, 4, 7],
106 | [7, 6, 5],
107 | [9, 8, 11],
108 | [11, 10, 9],
109 | [14, 13, 12],
110 | [12, 15, 14],
111 | [17, 16, 19],
112 | [19, 18, 17],
113 | [21, 20, 23],
114 | [23, 22, 21],
115 | ]);
116 | let new_buffer = buffer::create(
117 | &shader::Program::new(),
118 | verts,
119 | norms,
120 | texcoords,
121 | faces,
122 | true,
123 | );
124 | shape::create(vec![new_buffer], cam)
125 | }
126 |
--------------------------------------------------------------------------------
/pi3d/src/shapes/cylinder.rs:
--------------------------------------------------------------------------------
1 | use std::cell::RefCell;
2 | use std::rc::Rc;
3 | use crate::{camera, shape, shapes};
4 |
5 | pub fn create(
6 | cam: Rc>,
7 | radius: f32,
8 | height: f32,
9 | sides: usize,
10 | ) -> shape::Shape {
11 | let path: Vec<[f32; 2]> = vec![
12 | [0.0, height * 0.5],
13 | [radius * 0.999, height * 0.5],
14 | [radius, height * 0.5],
15 | [radius, height * 0.499],
16 | [radius, -height * 0.499],
17 | [radius, -height * 0.5],
18 | [radius * 0.999, -height * 0.5],
19 | [0.0, -height * 0.5],
20 | ];
21 |
22 | shapes::lathe::create(cam, path, sides, 0.0, 1.0)
23 | }
24 |
--------------------------------------------------------------------------------
/pi3d/src/shapes/elevation_map.rs:
--------------------------------------------------------------------------------
1 | use ndarray as nd;
2 | use std::cell::RefCell;
3 | use std::rc::Rc;
4 | use crate::util::{resources, vec3};
5 | use crate::{camera, shape, shader, buffer};
6 |
7 | // create a new struct definition
8 | pub struct ElevationMap {
9 | pub shape: shape::Shape,
10 | ix: f32,
11 | iz: f32,
12 | width: f32,
13 | depth: f32,
14 | }
15 |
16 | /// generate an elevation map Shape
17 | ///
18 | /// * `disp` reference to the display object which has file path functionality
19 | /// * `mapfile` relative path to image file representing heights
20 | /// * `width` edge to edge in x direction
21 | /// * `depth` in z direction
22 | /// * `height` in y direction scaled by pixel values 0 to 255
23 | /// * `ix` number of polygons in x direction
24 | /// * `iz` polygons in z direction
25 | /// * `ntiles` uv repeats for texture mapping
26 | /// * `_texmap` TODO used for allocating multiple textures to the map
27 | /// NB for no image scaling the mapfile should be one more pixel than ix and iz
28 | /// i.e. 33x33 image for 32x32 squares in grid
29 | ///
30 | /// TODO put this as class method (i.e. ::new())
31 | pub fn new(
32 | cam: Rc>,
33 | mapfile: &str,
34 | width: f32,
35 | depth: f32,
36 | height: f32,
37 | ix: usize,
38 | iz: usize,
39 | ntiles: f32,
40 | _texmap: &str,
41 | ) -> ElevationMap {
42 | let ix = if ix < 200 { ix + 1 } else { 200 }; // one more vertex in each direction than number of divisions
43 | let iz = if iz < 200 { iz + 1 } else { 200 };
44 | //let res = ::util::resources::from_exe_path().unwrap();
45 | let f = resources::resource_name_to_path(mapfile);
46 | //println!("f={:?}", f);
47 | let im = image::open(f).unwrap();
48 | // convert to Gray
49 | let mut im = image::imageops::colorops::grayscale(&im);
50 | // resize
51 | let (w, h) = im.dimensions();
52 | if w != ix as u32 || h != iz as u32 {
53 | im = image::imageops::resize(&im, ix as u32, iz as u32, image::FilterType::Lanczos3);
54 | }
55 | // flip top to bottom and left to right - which results in 180 degree rotation
56 | let im = image::imageops::rotate180(&im);
57 | let pixels = nd::Array::from_shape_vec((iz, ix, 1), im.into_raw()).unwrap();
58 |
59 | //TODO texmap used for mapping other info into uv coords (integer part)
60 |
61 | let wh = width * 0.5;
62 | let hh = depth * 0.5;
63 | let ws = width / (ix as f32 - 1.0);
64 | let hs = depth / (iz as f32 - 1.0);
65 | let ht = height / 255.0;
66 | let tx = 1.0 * ntiles / ix as f32;
67 | let tz = 1.0 * ntiles / iz as f32;
68 |
69 | let mut verts = Vec::::new();
70 | let mut faces = Vec::::new();
71 | let mut tex_coords = Vec::::new();
72 |
73 | for z in 0..iz {
74 | for x in 0..ix {
75 | //println!("z,x {:?},{:?}", z, x);
76 | verts.extend_from_slice(&[
77 | -wh + x as f32 * ws,
78 | pixels[[z, x, 0]] as f32 * ht,
79 | -hh + z as f32 * hs,
80 | ]);
81 | tex_coords.extend_from_slice(&[(ix - x) as f32 * tx, (iz - z) as f32 * tz]);
82 | }
83 | }
84 |
85 | //create one long triangle_strip by alternating X directions
86 | for z in 0..(iz - 1) {
87 | for x in 0..(ix - 1) {
88 | let i = (z * ix) + x;
89 | faces.extend_from_slice(&[i as u16, (i + ix) as u16, (i + ix + 1) as u16]);
90 | faces.extend_from_slice(&[(i + ix + 1) as u16, (i + 1) as u16, i as u16]);
91 | }
92 | }
93 |
94 | let nverts = verts.len() / 3;
95 | let nfaces = faces.len() / 3;
96 | let new_buffer = buffer::create(
97 | &shader::Program::new(),
98 | nd::Array::from_shape_vec((nverts, 3usize), verts).unwrap(),
99 | nd::Array2::::zeros((0, 3)),
100 | nd::Array::from_shape_vec((nverts, 2usize), tex_coords).unwrap(),
101 | nd::Array::from_shape_vec((nfaces, 3usize), faces).unwrap(),
102 | true,
103 | );
104 | let shape = shape::create(vec![new_buffer], cam);
105 | ElevationMap {
106 | shape,
107 | ix: ix as f32 - 1.0, // hold these for calc_height in additional attributes
108 | iz: iz as f32 - 1.0,
109 | width,
110 | depth,
111 | }
112 | }
113 |
114 | /// find the value of the y component of the location on the triangle
115 | /// where the x, z location lies within the elevation_map
116 | ///
117 | /// * `px` x location in world space
118 | /// * `pz` z location
119 | ///
120 | /// returns a tuple of the (height, normal vector at that point) this can
121 | /// be used for resistance to movement, bouncing etc.
122 | impl ElevationMap {
123 | pub fn calc_height(&self, px: f32, pz: f32) -> (f32, Vec) {
124 | //TODO a) the skip method will only work for regular maps
125 | // b) Buffer.calc_normals does cross product calc already so should save result
126 | // in Buffer on creation
127 | let px = px - self.shape.unif[[0, 0]];
128 | let pz = pz - self.shape.unif[[0, 2]];
129 | let skip_n = (((pz + self.depth * 0.5) * self.iz / self.depth).floor() * self.ix * 2.0
130 | + ((px + self.width * 0.5) * self.ix / self.width).floor() * 2.0)
131 | as usize;
132 | for f in self.shape.buf[0]
133 | .element_array_buffer
134 | .axis_iter(nd::Axis(0))
135 | .skip(skip_n)
136 | {
137 | let mut v: Vec> = vec![vec![0.0; 3]; 3];
138 | for i in 0..3 {
139 | // the three vertices of this element
140 | for j in 0..3 {
141 | // the x, y, z components of each vertex
142 | v[i][j] = self.shape.buf[0].array_buffer[[f[[i]] as usize, j]];
143 | }
144 | }
145 | if ((v[1][2] - v[0][2]) * (px - v[0][0]) + (-v[1][0] + v[0][0]) * (pz - v[0][2]) >= 0.0)
146 | && ((v[2][2] - v[1][2]) * (px - v[1][0]) + (-v[2][0] + v[1][0]) * (pz - v[1][2])
147 | >= 0.0)
148 | && ((v[0][2] - v[2][2]) * (px - v[2][0]) + (-v[0][0] + v[2][0]) * (pz - v[2][2])
149 | >= 0.0)
150 | {
151 | let v0 = nd::arr1(&v[0]);
152 | let v1 = nd::arr1(&v[1]);
153 | let v2 = nd::arr1(&v[2]);
154 | //calc normal from two edge vectors v2-v1 and v3-v1
155 | let n_vec = vec3::cross(&(&v1 - &v0), &(v2 - v0));
156 | //equation of plane: Ax + By + Cz = k_val where A,B,C are components of normal. x,y,z for point v1 to find k_val
157 | let k_val = vec3::dot(&n_vec, &v1);
158 | //return y val i.e. y = (k_val - Ax - Cz)/B also the normal vector seeing as this has been calculated
159 | return (
160 | (k_val - n_vec[[0]] * px - n_vec[[2]] * pz) / n_vec[[1]],
161 | n_vec.to_vec(),
162 | );
163 | }
164 | }
165 | //TODO fn should return Option<> and need to be unwrapped rather than return something
166 | (0.0, vec![0.0, 1.0, 0.0])
167 | }
168 | }
169 |
--------------------------------------------------------------------------------
/pi3d/src/shapes/environment_cube.rs:
--------------------------------------------------------------------------------
1 | use ndarray as nd;
2 | use std::cell::RefCell;
3 | use std::collections::HashMap;
4 | use std::rc::Rc;
5 | use crate::{camera, shape, buffer, texture, shader};
6 |
7 | /// generate an enviroment cube which uses six textures
8 | ///
9 | /// * `disp` reference to the display object which has file path functionality
10 | /// * `size` cube width
11 | /// * `stem` stem of the name, i.e. before '_back' '_front' etc
12 | /// * `suffix` i.e. jpg, png etc
13 | ///
14 | /// NB this function returns a tuple of Shape and Vec of Texture object
15 | /// as they will need to live as long as the enviroment cube is used
16 | ///
17 | pub fn create(
18 | cam: Rc>,
19 | size: f32,
20 | stem: &str,
21 | suffix: &str,
22 | ) -> (shape::Shape, HashMap) {
23 | let parts = vec!["front", "right", "top", "bottom", "left", "back"];
24 | let mut bufs = Vec::::new();
25 | let ww = size / 2.0;
26 | let hh = size / 2.0;
27 | let dd = size / 2.0;
28 | //TODO why does the uv array need a 'sacrificial' entry on the end?
29 | bufs.push(buffer::create(
30 | &shader::Program::new(),
31 | nd::arr2(&[
32 | [-ww, hh, dd],
33 | [ww, hh, dd],
34 | [ww, -hh, dd],
35 | [-ww, -hh, dd],
36 | [0.0, 0.0, 0.0],
37 | ]),
38 | nd::arr2(&[
39 | [0.0, 0.0, 1.0],
40 | [0.0, 0.0, 1.0],
41 | [0.0, 0.0, 1.0],
42 | [0.0, 0.0, 1.0],
43 | [0.0, 0.0, 0.0],
44 | ]),
45 | nd::arr2(&[
46 | [0.002, 0.002],
47 | [0.998, 0.002],
48 | [0.998, 0.998],
49 | [0.002, 0.998],
50 | [0.0, 0.0],
51 | ]),
52 | nd::arr2(&[[3, 0, 1], [2, 3, 1]]),
53 | false,
54 | )); //front
55 |
56 | bufs.push(buffer::create(
57 | &shader::Program::new(),
58 | nd::arr2(&[
59 | [ww, hh, dd],
60 | [ww, hh, -dd],
61 | [ww, -hh, -dd],
62 | [ww, -hh, dd],
63 | [0.0, 0.0, 0.0],
64 | ]),
65 | nd::arr2(&[
66 | [1.0, 0.0, 0.0],
67 | [1.0, 0.0, 0.0],
68 | [1.0, 0.0, 0.0],
69 | [1.0, 0.0, 0.0],
70 | [0.0, 0.0, 0.0],
71 | ]),
72 | nd::arr2(&[
73 | [0.002, 0.002],
74 | [0.998, 0.002],
75 | [0.998, 0.998],
76 | [0.002, 0.998],
77 | [0.0, 0.0],
78 | ]),
79 | nd::arr2(&[[3, 0, 1], [2, 3, 1]]),
80 | false,
81 | )); //right
82 |
83 | bufs.push(buffer::create(
84 | &shader::Program::new(),
85 | nd::arr2(&[
86 | [-ww, hh, dd],
87 | [-ww, hh, -dd],
88 | [ww, hh, -dd],
89 | [ww, hh, dd],
90 | [0.0, 0.0, 0.0],
91 | ]),
92 | nd::arr2(&[
93 | [0.0, 1.0, 0.0],
94 | [0.0, 1.0, 0.0],
95 | [0.0, 1.0, 0.0],
96 | [0.0, 1.0, 0.0],
97 | [0.0, 0.0, 0.0],
98 | ]),
99 | nd::arr2(&[
100 | [0.002, 0.998],
101 | [0.002, 0.002],
102 | [0.998, 0.002],
103 | [0.998, 0.998],
104 | [0.0, 0.0],
105 | ]),
106 | nd::arr2(&[[3, 0, 1], [2, 3, 1]]),
107 | false,
108 | )); //top
109 |
110 | bufs.push(buffer::create(
111 | &shader::Program::new(),
112 | nd::arr2(&[
113 | [ww, -hh, dd],
114 | [ww, -hh, -dd],
115 | [-ww, -hh, -dd],
116 | [-ww, -hh, dd],
117 | [0.0, 0.0, 0.0],
118 | ]),
119 | nd::arr2(&[
120 | [0.0, -1.0, 0.0],
121 | [0.0, -1.0, 0.0],
122 | [0.0, -1.0, 0.0],
123 | [0.0, -1.0, 0.0],
124 | [0.0, 0.0, 0.0],
125 | ]),
126 | nd::arr2(&[
127 | [0.998, 0.002],
128 | [0.998, 0.998],
129 | [0.002, 0.998],
130 | [0.002, 0.002],
131 | [0.0, 0.0],
132 | ]),
133 | nd::arr2(&[[3, 0, 1], [2, 3, 1]]),
134 | false,
135 | )); //bottom
136 |
137 | bufs.push(buffer::create(
138 | &shader::Program::new(),
139 | nd::arr2(&[
140 | [-ww, -hh, dd],
141 | [-ww, -hh, -dd],
142 | [-ww, hh, -dd],
143 | [-ww, hh, dd],
144 | [0.0, 0.0, 0.0],
145 | ]),
146 | nd::arr2(&[
147 | [-1.0, 0.0, 0.0],
148 | [-1.0, 0.0, 0.0],
149 | [-1.0, 0.0, 0.0],
150 | [-1.0, 0.0, 0.0],
151 | [0.0, 0.0, 0.0],
152 | ]),
153 | nd::arr2(&[
154 | [0.998, 0.998],
155 | [0.002, 0.998],
156 | [0.002, 0.002],
157 | [0.998, 0.002],
158 | [0.0, 0.0],
159 | ]),
160 | nd::arr2(&[[3, 0, 1], [2, 3, 1]]),
161 | false,
162 | )); //left
163 |
164 | bufs.push(buffer::create(
165 | &shader::Program::new(),
166 | nd::arr2(&[
167 | [-ww, hh, -dd],
168 | [ww, hh, -dd],
169 | [ww, -hh, -dd],
170 | [-ww, -hh, -dd],
171 | [0.0, 0.0, 0.0],
172 | ]),
173 | nd::arr2(&[
174 | [0.0, 0.0, -1.0],
175 | [0.0, 0.0, -1.0],
176 | [0.0, 0.0, -1.0],
177 | [0.0, 0.0, -1.0],
178 | [0.0, 0.0, 0.0],
179 | ]),
180 | nd::arr2(&[
181 | [0.998, 0.002],
182 | [0.002, 0.002],
183 | [0.002, 0.998],
184 | [0.998, 0.998],
185 | [0.0, 0.0],
186 | ]),
187 | nd::arr2(&[[3, 1, 0], [2, 1, 3]]),
188 | false,
189 | )); //back
190 |
191 | let mut tex_list = HashMap::::new();
192 |
193 | for i in 0..bufs.len() {
194 | //let path_str = path_buf.to_str().unwrap();
195 | let fname = format!("{}_{}.{}", &stem, &parts[i], &suffix);
196 | let tex = texture::create_from_file(&fname);
197 | bufs[i].set_textures(&vec![tex.id]);
198 | tex_list.insert(parts[i].to_string(), tex);
199 | }
200 | let mut new_shape = shape::create(bufs, cam);
201 | new_shape.set_fog(&[0.5, 0.5, 0.5], 5000.0, 1.0);
202 | (new_shape, tex_list)
203 | }
204 |
--------------------------------------------------------------------------------
/pi3d/src/shapes/lathe.rs:
--------------------------------------------------------------------------------
1 | use ndarray as nd;
2 | use std::cell::RefCell;
3 | use std::f32::consts;
4 | use std::rc::Rc;
5 | use crate::{camera, shape, buffer, shader};
6 |
7 | pub fn create(
8 | cam: Rc>,
9 | path: Vec<[f32; 2]>,
10 | sides: usize,
11 | rise: f32,
12 | loops: f32,
13 | ) -> shape::Shape {
14 | let s = path.len(); // iterations along path
15 | let rl = sides * loops as usize; // iterations around axis
16 |
17 | let mut pn: u16 = 0; // keep track of vert index for faces
18 | let mut pp: u16 = 0; // ditto
19 | let tcx = 1.0 / sides as f32; // UV step horizontally
20 | let pr = (consts::PI / sides as f32) * 2.0; // angle rotated per vertex
21 | let rdiv = rise / rl as f32; // increment axially each step
22 |
23 | // Find length of the path
24 | let mut path_len = 0.0;
25 | for p in 1..s {
26 | path_len += ((path[p][0] - path[p - 1][0]).powf(2.0)
27 | + (path[p][1] - path[p - 1][1]).powf(2.0))
28 | .powf(0.5);
29 | }
30 |
31 | let mut verts = Vec::::new();
32 | let mut norms = Vec::::new();
33 | let mut faces = Vec::::new();
34 | let mut tex_coords = Vec::::new();
35 |
36 | let mut opx = path[0][0];
37 | let mut opy = path[0][1];
38 |
39 | let mut tcy = 0.0; // UV val vertically
40 | for p in 0..s {
41 | let px = path[p][0]; // for brevity
42 | let mut py = path[p][1]; // and clarity (and need to increment!)
43 | let step_len = ((px - opx).powf(2.0) + (py - opy).powf(2.0)).powf(0.5);
44 | if p > 0 {
45 | tcy += step_len / path_len;
46 | }
47 | let dx = (px - opx) / step_len;
48 | let dy = (py - opy) / step_len;
49 |
50 | for r in 0..(rl + 1) {
51 | let sinr = (pr * r as f32).sin();
52 | let cosr = (pr * r as f32).cos();
53 | verts.extend_from_slice(&[px * sinr, py, px * cosr]);
54 | norms.extend_from_slice(&[-sinr * dy, dx, -cosr * dy]);
55 | tex_coords.extend_from_slice(&[1.0 - tcx * r as f32, tcy]);
56 | py += rdiv;
57 | }
58 | if p < (s - 1) {
59 | pn += rl as u16 + 1;
60 | for r in 0..rl {
61 | faces.extend_from_slice(&[pp + r as u16 + 1, pp + r as u16, pn + r as u16]);
62 | faces.extend_from_slice(&[pn + r as u16, pn + r as u16 + 1, pp + r as u16 + 1]);
63 | }
64 | pp += rl as u16 + 1;
65 | }
66 | opx = px;
67 | opy = py;
68 | }
69 | let nverts = verts.len() / 3;
70 | let nfaces = faces.len() / 3;
71 | let new_buffer = buffer::create(
72 | &shader::Program::new(),
73 | nd::Array::from_shape_vec((nverts, 3usize), verts).unwrap(), //TODO make functions return Result and feedback errors
74 | nd::Array::from_shape_vec((nverts, 3usize), norms).unwrap(),
75 | nd::Array::from_shape_vec((nverts, 2usize), tex_coords).unwrap(),
76 | nd::Array::from_shape_vec((nfaces, 3usize), faces).unwrap(),
77 | false,
78 | );
79 | shape::create(vec![new_buffer], cam)
80 | }
81 |
--------------------------------------------------------------------------------
/pi3d/src/shapes/lines.rs:
--------------------------------------------------------------------------------
1 | use ndarray as nd;
2 | use std::cell::RefCell;
3 | use std::rc::Rc;
4 | use crate::{camera, shape, buffer, shader};
5 |
6 | pub fn create(
7 | cam: Rc>,
8 | verts: &[f32],
9 | line_width: f32,
10 | closed: bool,
11 | ) -> shape::Shape {
12 | //TODO sort out reason for extra vertex (uv point)
13 | let norms = nd::Array2::::zeros((0, 3));
14 | let tex_coords = nd::Array2::::zeros((0, 2));
15 | let nverts = verts.len() / 3;
16 | let nfaces = nverts / 3 + 1;
17 | let mut faces = Vec::::new();
18 | for a in 0..nfaces {
19 | for i in 0..3 {
20 | let v = a * 3 + i;
21 | faces.push(if v < nverts { v } else { nverts - 1 } as u16);
22 | }
23 | }
24 |
25 | let mut new_buffer = buffer::create(
26 | &shader::Program::new(),
27 | nd::Array::from_shape_vec((nverts, 3usize), verts.to_vec()).unwrap(), //TODO make functions return Result and feedback errors
28 | norms,
29 | tex_coords,
30 | nd::Array::from_shape_vec((nfaces, 3usize), faces).unwrap(),
31 | false,
32 | );
33 |
34 | new_buffer.set_line_width(line_width, true, closed);
35 |
36 | shape::create(vec![new_buffer], cam)
37 | }
38 |
--------------------------------------------------------------------------------
/pi3d/src/shapes/merge_shape.rs:
--------------------------------------------------------------------------------
1 | use ndarray as nd;
2 | use std::cell::RefCell;
3 | use std::f32::consts;
4 | use std::rc::Rc;
5 |
6 | use crate::util::vec3::{rotate_vec, rotate_vec_slice};
7 | use crate::{shape, shapes, buffer, shader, camera};
8 |
9 | /// add a Vec of Buffers at specific location, rotation, scales to an existing
10 | /// Shape
11 | ///
12 | /// * `merge_to` existing shape to merge new shapes to
13 | /// * `new_bufs` Vec of &Buffer objects to build into merge_to
14 | /// * `loc` Vec of [x, y, z] locations matching each Buffer in new_bufs
15 | /// * `rot` Vec of [rx, ry, rz] rotations
16 | /// * `scl` Vec of [sx, sy, sz] scales
17 | /// * `num` Vec of index values to merge_to.buf[] for merging new Buffers
18 | ///
19 | pub fn add_buffers(
20 | merge_to: &mut shape::Shape,
21 | new_bufs: Vec<&buffer::Buffer>,
22 | loc: Vec<[f32; 3]>,
23 | rot: Vec<[f32; 3]>,
24 | scl: Vec<[f32; 3]>,
25 | num: Vec,
26 | ) {
27 | if new_bufs.len() != loc.len() || loc.len() != rot.len() || rot.len() != scl.len() {
28 | panic!("\n\nadd_buffers() needs four Vecs of same size\n\n");
29 | }
30 | // make note of num of verts and faces already there.
31 | // also have a new mut num_v, verts, norms, tex_coord and faces for each num
32 | let mut num_v = Vec::::new();
33 | let mut verts = Vec::>::new();
34 | let mut norms = Vec::>::new();
35 | let mut tex_coords = Vec::>::new();
36 | let mut faces = Vec::>::new();
37 | let mut new_buf_ix = Vec::::new();
38 | for i in 0..merge_to.buf.len() {
39 | num_v.push(merge_to.buf[i].array_buffer.shape()[0] as u16);
40 | verts.push(merge_to.buf[i].array_buffer.slice(s![.., 0..3]).to_owned());
41 | norms.push(merge_to.buf[i].array_buffer.slice(s![.., 3..6]).to_owned());
42 | tex_coords.push(merge_to.buf[i].array_buffer.slice(s![.., 6..8]).to_owned());
43 | faces.push(merge_to.buf[i].element_array_buffer.to_owned());
44 | new_buf_ix.push(0);
45 | }
46 | for i in 0..new_bufs.len() {
47 | // if num >= merge_to.buf.len() -> add new empty buffers to bring to size
48 | while num[i] >= merge_to.buf.len() {
49 | merge_to.buf.push(buffer::create_empty());
50 | num_v.push(0); // and crete empty buffers
51 | verts.push(
52 | merge_to.buf[0]
53 | .array_buffer
54 | .slice(s![0..0, 0..3])
55 | .to_owned(),
56 | );
57 | norms.push(
58 | merge_to.buf[0]
59 | .array_buffer
60 | .slice(s![0..0, 3..6])
61 | .to_owned(),
62 | );
63 | tex_coords.push(
64 | merge_to.buf[0]
65 | .array_buffer
66 | .slice(s![0..0, 6..8])
67 | .to_owned(),
68 | );
69 | faces.push(
70 | merge_to.buf[0]
71 | .element_array_buffer
72 | .slice(s![0..0, ..])
73 | .to_owned(),
74 | );
75 | new_buf_ix.push(0);
76 | }
77 | // scale then rotate new verts then add displacement
78 | let new_verts = &new_bufs[i].array_buffer.slice(s![.., 0..3]) * &nd::arr1(&scl[i]);
79 | let new_verts = rotate_vec(&rot[i], &new_verts) + &nd::arr1(&loc[i]);
80 | // then add them to existing verts
81 | verts[num[i]].append(nd::Axis(0), new_verts.view()).unwrap();
82 | // rotate new normals
83 | let new_norms = rotate_vec_slice(&rot[i], &new_bufs[i].array_buffer.slice(s![.., 3..6]));
84 | // then add them to existing normals
85 | norms[num[i]].append(nd::Axis(0), new_norms.view()).unwrap();
86 | // stack tex_coords
87 | tex_coords[num[i]].append(nd::Axis(0), new_bufs[i].array_buffer.slice(s![.., 6..8]).view()).unwrap();
88 | // add num_v to values in faces
89 | faces[num[i]].append(nd::Axis(0), (&new_bufs[i].element_array_buffer + num_v[num[i]]).view()).unwrap();
90 | num_v[num[i]] += new_verts.shape()[0] as u16;
91 | new_buf_ix[num[i]] = i;
92 | }
93 | for i in 0..merge_to.buf.len() {
94 | let mut extended_buf = buffer::create(
95 | &shader::Program::new(),
96 | verts[i].to_owned(),
97 | norms[i].to_owned(),
98 | tex_coords[i].to_owned(),
99 | faces[i].to_owned(),
100 | false,
101 | );
102 | // copy over shader, textures, unib, draw_method
103 | let ix = new_buf_ix[i];
104 | extended_buf.unib = new_bufs[ix].unib.clone();
105 | extended_buf.draw_method = new_bufs[ix].draw_method;
106 | extended_buf.shader_id = new_bufs[ix].shader_id;
107 | extended_buf.attribute_names = new_bufs[ix].attribute_names.clone();
108 | extended_buf.attribute_values = new_bufs[ix].attribute_values.clone();
109 | extended_buf.uniform_names = new_bufs[ix].uniform_names.clone();
110 | extended_buf.uniform_values = new_bufs[ix].uniform_values.clone();
111 | extended_buf.textures = new_bufs[ix].textures.clone();
112 | merge_to.buf[i] = extended_buf;
113 | }
114 | }
115 |
116 | /// wrapper round add_buffers that can be passed a Vec of Shape objects
117 | /// and will the buf Vec and add all the Buffer objects
118 | ///
119 | pub fn add_shapes(
120 | merge_to: &mut shape::Shape,
121 | new_shapes: Vec<&shape::Shape>,
122 | loc: Vec<[f32; 3]>,
123 | rot: Vec<[f32; 3]>,
124 | scl: Vec<[f32; 3]>,
125 | num: Vec,
126 | ) {
127 | let mut bufs = Vec::<&buffer::Buffer>::new();
128 | let mut new_loc = Vec::<[f32; 3]>::new();
129 | let mut new_rot = Vec::<[f32; 3]>::new();
130 | let mut new_scl = Vec::<[f32; 3]>::new();
131 | let mut new_num = Vec::::new();
132 | for i in 0..new_shapes.len() {
133 | for j in 0..new_shapes[i].buf.len() {
134 | bufs.push(&new_shapes[i].buf[j]);
135 | new_loc.push([loc[i][0], loc[i][1], loc[i][2]]);
136 | new_rot.push([rot[i][0], rot[i][1], rot[i][2]]);
137 | new_scl.push([scl[i][0], scl[i][1], scl[i][2]]);
138 | new_num.push(num[i]);
139 | }
140 | }
141 | add_buffers(merge_to, bufs, new_loc, new_rot, new_scl, new_num);
142 | }
143 |
144 | /// create a cluster of shapes on an elevation map
145 | ///
146 | /// * `merge_to` existing Shape to merge cluster of duplicate shapes to
147 | /// * `new_shape' new Shape to duplicate
148 | /// * `map' elevation_map for calculating height
149 | /// * `xpos`, `ypos` centre of cluster
150 | /// * `w`, `d` width and depth of cluster
151 | /// * `minscl`, `maxscl` range of scaling factors to apply
152 | /// * `count` number of duplicates to make
153 | ///
154 | pub fn cluster(
155 | merge_to: &mut shape::Shape,
156 | new_shape: &shape::Shape,
157 | map: &shapes::elevation_map::ElevationMap,
158 | xpos: f32,
159 | zpos: f32,
160 | w: f32,
161 | d: f32,
162 | minscl: f32,
163 | maxscl: f32,
164 | count: usize,
165 | ) {
166 | let mut bufs = Vec::<&buffer::Buffer>::new();
167 | let mut new_loc = Vec::<[f32; 3]>::new();
168 | let mut new_rot = Vec::<[f32; 3]>::new();
169 | let mut new_scl = Vec::<[f32; 3]>::new();
170 | let mut new_num = Vec::::new();
171 | for _i in 0..count {
172 | let x = xpos - 0.5 * w + w * rand::random::();
173 | let z = zpos - 0.5 * d + d * rand::random::();
174 | let (y, _norm) = map.calc_height(x, z);
175 | let ry = 2.0 * consts::PI * rand::random::();
176 | let scl = minscl + (maxscl - minscl) * rand::random::();
177 | for j in 0..new_shape.buf.len() {
178 | bufs.push(&new_shape.buf[j]);
179 | new_loc.push([x, y, z]);
180 | new_rot.push([0.0, ry, 0.0]);
181 | new_scl.push([scl, scl, scl]);
182 | new_num.push(j);
183 | }
184 | }
185 |
186 | add_buffers(merge_to, bufs, new_loc, new_rot, new_scl, new_num);
187 | }
188 |
189 | /// initial creation produces a shape with an empty buffer
190 | ///
191 | pub fn create(cam: Rc>) -> shape::Shape {
192 | let new_buffer = buffer::create_empty();
193 | shape::create(vec![new_buffer], cam)
194 | }
195 |
196 | //TODO pub fn radial_copy();
197 |
--------------------------------------------------------------------------------
/pi3d/src/shapes/mod.rs:
--------------------------------------------------------------------------------
1 | extern crate image;
2 |
3 | pub mod cone;
4 | pub mod cuboid;
5 | pub mod cylinder;
6 | pub mod elevation_map;
7 | pub mod environment_cube;
8 | pub mod lathe;
9 | pub mod lines;
10 | pub mod merge_shape;
11 | pub mod model_obj;
12 | pub mod plane;
13 | pub mod point_text;
14 | pub mod points;
15 | pub mod sphere;
16 | pub mod string;
17 | pub mod tcone;
18 | pub mod torus;
19 | pub mod tube;
20 |
--------------------------------------------------------------------------------
/pi3d/src/shapes/plane.rs:
--------------------------------------------------------------------------------
1 | use ndarray as nd;
2 | use std::cell::RefCell;
3 | use std::rc::Rc;
4 | use crate::{camera, shape, buffer, shader};
5 |
6 | pub fn create(cam: Rc>, w: f32, h: f32) -> shape::Shape {
7 | let wh = w * 0.5;
8 | let hh = h * 0.5;
9 | //TODO sort out reason for extra vertex (uv point)
10 | let verts: nd::Array2 = nd::arr2(&[
11 | [-wh, hh, 0.0],
12 | [wh, hh, 0.0],
13 | [wh, -hh, 0.0],
14 | [-wh, -hh, 0.0],
15 | [-wh, hh, 0.0],
16 | [wh, hh, 0.0],
17 | [wh, -hh, 0.0],
18 | [-wh, -hh, 0.0],
19 | [0.0, 0.0, 0.0],
20 | ]);
21 | let norms: nd::Array2 = nd::arr2(&[
22 | [-wh, hh, 0.0],
23 | [wh, hh, 0.0],
24 | [wh, -hh, 0.0],
25 | [-wh, -hh, 0.0],
26 | [-wh, hh, 0.0],
27 | [wh, hh, 0.0],
28 | [wh, -hh, 0.0],
29 | [-wh, -hh, 0.0],
30 | [0.0, 0.0, 0.0],
31 | ]);
32 | let texcoords: nd::Array2 = nd::arr2(&[
33 | [0.0, 0.0],
34 | [1.0, 0.0],
35 | [1.0, 1.0],
36 | [0.0, 1.0],
37 | [0.0, 0.0],
38 | [1.0, 0.0],
39 | [1.0, 1.0],
40 | [0.0, 1.0],
41 | [0.0, 0.0],
42 | ]);
43 | let faces: nd::Array2 = nd::arr2(&[[3, 0, 1], [1, 2, 3], [7, 6, 5], [5, 4, 7]]);
44 |
45 | let new_buffer = buffer::create(
46 | &shader::Program::new(),
47 | verts,
48 | norms,
49 | texcoords,
50 | faces,
51 | true,
52 | );
53 | shape::create(vec![new_buffer], cam)
54 | }
55 |
--------------------------------------------------------------------------------
/pi3d/src/shapes/point_text.rs:
--------------------------------------------------------------------------------
1 | use std::cell::RefCell;
2 | use std::rc::Rc;
3 | use crate::{camera, shape, shapes, shader};
4 | use crate::util::font;
5 |
6 | pub struct TextBlock {
7 | x: f32,
8 | y: f32,
9 | z: f32,
10 | capacity: usize,
11 | size: f32,
12 | text: String,
13 | rot: f32,
14 | char_rot: f32,
15 | spacing: char,
16 | space: f32,
17 | rgba: [f32; 4],
18 | justification: f32,
19 | start: usize,
20 | }
21 |
22 | pub struct PointText {
23 | pub points: shape::Shape,
24 | blocks: Vec,
25 | max_chars: usize,
26 | point_size: f32,
27 | }
28 |
29 | impl PointText {
30 | //pub fn add_text_block(&mut self,
31 | pub fn add_text_block(
32 | &mut self,
33 | font: &font::TextureFont,
34 | position: &[f32; 3],
35 | capacity: usize,
36 | text: &str,
37 | ) -> usize {
38 | if text.chars().count() > capacity {
39 | panic!("text won't fit into capacity for this TextBlock");
40 | }
41 | let start = match self.blocks.last() {
42 | Some(blk) => blk.start + blk.capacity,
43 | _ => 0, // it must have been an empty Vec
44 | };
45 | if (start + capacity) > self.max_chars {
46 | panic!("TextBlock is going to overflow PointText");
47 | }
48 | let new_block = TextBlock {
49 | x: position[0],
50 | y: position[1],
51 | z: position[2],
52 | capacity,
53 | size: 0.99,
54 | text: text.to_string(),
55 | rot: 0.0,
56 | char_rot: 0.0,
57 | spacing: 'F',
58 | space: 0.05,
59 | rgba: [0.999; 4],
60 | justification: 0.0,
61 | start,
62 | };
63 | self.blocks.push(new_block);
64 | let block_id = self.blocks.len() - 1;
65 | self.regen(font, block_id);
66 | block_id
67 | }
68 |
69 | pub fn draw(&mut self) {
70 | self.points.draw();
71 | }
72 |
73 | pub fn set_shader(&mut self, shader: &shader::Program) {
74 | self.points.set_shader(shader);
75 | }
76 |
77 | // these all apply to one of the TextBlocks
78 | //pub fn set_position(&mut self,
79 | pub fn set_position(
80 | &mut self,
81 | font: &font::TextureFont,
82 | block_id: usize,
83 | position: &[f32; 3],
84 | ) {
85 | self.blocks[block_id].x = position[0];
86 | self.blocks[block_id].y = position[1];
87 | self.blocks[block_id].z = position[2];
88 |
89 | self.regen(font, block_id);
90 | }
91 |
92 | //pub fn set_text(&mut self,
93 | pub fn set_text(&mut self, font: &font::TextureFont, block_id: usize, text: &str) {
94 | let start = self.blocks[block_id].start;
95 | let capacity = self.blocks[block_id].capacity;
96 | let end = start + capacity;
97 | if text.chars().count() >= capacity {
98 | panic!("text won't fit into capacity for this TextBlock");
99 | }
100 | for i in start..end {
101 | // set alpha to zero first
102 | self.points.buf[0].array_buffer[[i, 5]] = 0.0;
103 | }
104 | self.blocks[block_id].text = text.to_string();
105 | self.regen(font, block_id);
106 | }
107 |
108 | //pub fn set_rgba(&mut self,
109 | pub fn set_rgba(&mut self, font: &font::TextureFont, block_id: usize, rgba: &[f32; 4]) {
110 | self.blocks[block_id].rgba = *rgba;
111 | self.regen(font, block_id);
112 | }
113 |
114 | pub fn set_rot(&mut self, font: &font::TextureFont, block_id: usize, rot: f32) {
115 | self.blocks[block_id].rot = rot;
116 | self.regen(font, block_id);
117 | }
118 |
119 | pub fn set_char_rot(
120 | &mut self,
121 | font: &font::TextureFont,
122 | block_id: usize,
123 | char_rot: f32,
124 | ) {
125 | self.blocks[block_id].char_rot = char_rot;
126 | self.regen(font, block_id);
127 | }
128 |
129 | pub fn set_spacing(
130 | &mut self,
131 | font: &font::TextureFont,
132 | block_id: usize,
133 | spacing: char,
134 | ) {
135 | self.blocks[block_id].spacing = spacing;
136 | self.regen(font, block_id);
137 | }
138 |
139 | pub fn set_justification(
140 | &mut self,
141 | font: &font::TextureFont,
142 | block_id: usize,
143 | justification: f32,
144 | ) {
145 | self.blocks[block_id].justification = justification;
146 | self.regen(font, block_id);
147 | }
148 |
149 | pub fn set_size(&mut self, font: &font::TextureFont, block_id: usize, size: f32) {
150 | self.blocks[block_id].size = size;
151 | self.regen(font, block_id);
152 | }
153 |
154 | pub fn set_space(&mut self, font: &font::TextureFont, block_id: usize, space: f32) {
155 | self.blocks[block_id].space = space;
156 | self.regen(font, block_id);
157 | }
158 |
159 | //fn regen(&mut self, block_id: usize) {
160 | fn regen(&mut self, font: &font::TextureFont, block_id: usize) {
161 | //position, rotation etc
162 | let blk = &self.blocks[block_id]; // alias for brevity
163 | let const_w = match blk.spacing {
164 | 'M' => 0.0,
165 | _ => font.size * blk.size * blk.space,
166 | };
167 | let vari_w = match blk.spacing {
168 | 'M' => blk.size * blk.space,
169 | 'F' => blk.size,
170 | _ => 0.0,
171 | };
172 | let default = &font.glyph_table[&' '];
173 | let mut offset = 0.0;
174 | let mut n_char = 0usize; // used for second loop
175 | let g_scale = self.point_size / font.height;
176 | for c in blk.text.chars() {
177 | let glyph = match &font.glyph_table.get(&c) {
178 | &Some(g) => g,
179 | _ => default,
180 | };
181 | let vi = blk.start + n_char; // index within array_buffer
182 | self.points.buf[0].array_buffer[[vi, 0]] = offset;
183 | self.points.buf[0].array_buffer[[vi, 1]] = glyph.verts[2][1] * g_scale * blk.size;
184 | self.points.buf[0].array_buffer[[vi, 2]] = (blk.z * 10.0).trunc() + blk.size.fract();
185 | self.points.buf[0].array_buffer[[vi, 3]] = blk.rot + blk.char_rot;
186 | self.points.buf[0].array_buffer[[vi, 4]] =
187 | (blk.rgba[0] * 1000.0).trunc() + blk.rgba[1] * 0.999;
188 | self.points.buf[0].array_buffer[[vi, 5]] =
189 | (blk.rgba[2] * 1000.0).trunc() + blk.rgba[3] * 0.999;
190 | self.points.buf[0].array_buffer[[vi, 6]] = glyph.x; // uv positions
191 | self.points.buf[0].array_buffer[[vi, 7]] = glyph.y;
192 | if blk.spacing == 'F' {
193 | //char centre to right
194 | offset += glyph.w * g_scale * blk.size * 0.5;
195 | }
196 | offset += glyph.w * g_scale * vari_w + const_w;
197 | n_char += 1;
198 | }
199 | let x_off = blk.justification * offset;
200 | let sin_r = blk.rot.sin();
201 | let cos_r = blk.rot.cos();
202 | for i in 0..n_char {
203 | let vi = blk.start + i;
204 | let old_x = self.points.buf[0].array_buffer[[vi, 0]] - x_off;
205 | let old_y = self.points.buf[0].array_buffer[[vi, 1]];
206 | self.points.buf[0].array_buffer[[vi, 0]] = blk.x + old_x * cos_r - old_y * sin_r;
207 | self.points.buf[0].array_buffer[[vi, 1]] = blk.y + old_x * sin_r + old_y * cos_r;
208 | }
209 | self.points.buf[0].re_init();
210 | }
211 | }
212 |
213 | pub fn create(
214 | cam: Rc>,
215 | font: &font::TextureFont,
216 | max_chars: usize,
217 | point_size: f32,
218 | ) -> PointText {
219 | let verts: Vec = vec![0.0; max_chars * 3];
220 | let mut new_shape = shapes::points::create(cam, &verts, point_size);
221 | new_shape.buf[0].set_textures(&vec![font.tex.id]);
222 | new_shape.buf[0].set_blend(true);
223 | new_shape.unif[[16, 0]] = 0.05; //TODO base on point_size and
224 | PointText {
225 | points: new_shape,
226 | blocks: vec![],
227 | max_chars,
228 | point_size,
229 | }
230 | }
231 |
--------------------------------------------------------------------------------
/pi3d/src/shapes/points.rs:
--------------------------------------------------------------------------------
1 | use ndarray as nd;
2 | use std::cell::RefCell;
3 | use std::rc::Rc;
4 | use crate::{camera, shape, buffer, shader};
5 |
6 | pub fn create(
7 | cam: Rc>,
8 | verts: &[f32],
9 | point_size: f32,
10 | ) -> shape::Shape {
11 | //TODO sort out reason for extra vertex (uv point)
12 | let nverts = verts.len() / 3;
13 | let nfaces = nverts / 3 + 1;
14 | let mut faces = Vec::::new();
15 | for a in 0..nfaces {
16 | for i in 0..3 {
17 | let v = a * 3 + i;
18 | faces.push(if v < nverts { v } else { nverts - 1 } as u16);
19 | }
20 | }
21 | let norms = nd::Array2::::zeros((nverts, 3));
22 | let tex_coords = nd::Array2::::zeros((nverts, 2));
23 |
24 | let mut new_buffer = buffer::create(
25 | &shader::Program::new(),
26 | nd::Array::from_shape_vec((nverts, 3usize), verts.to_vec()).unwrap(), //TODO make functions return Result and feedback errors
27 | norms,
28 | tex_coords,
29 | nd::Array::from_shape_vec((nfaces, 3usize), faces).unwrap(),
30 | false,
31 | );
32 |
33 | new_buffer.set_point_size(point_size);
34 |
35 | shape::create(vec![new_buffer], cam)
36 | }
37 |
--------------------------------------------------------------------------------
/pi3d/src/shapes/sphere.rs:
--------------------------------------------------------------------------------
1 | use std::cell::RefCell;
2 | use std::f32::consts;
3 | use std::rc::Rc;
4 | use crate::{camera, shape, shapes};
5 |
6 | pub fn create(
7 | cam: Rc>,
8 | radius: f32,
9 | slices: usize,
10 | sides: usize,
11 | hemi: f32,
12 | invert: bool,
13 | ) -> shape::Shape {
14 | let mut path = Vec::<[f32; 2]>::new();
15 | // extra points added at poles to reduce distortion (mainly normals)
16 | let st = ((consts::PI - 0.002) * (1.0 - hemi)) / slices as f32; // angular step
17 | path.push([0.0, radius]);
18 | for r in 0..(slices + 1) {
19 | path.push([
20 | radius * (0.001 + st * r as f32).sin(),
21 | radius * (0.001 + st * r as f32).cos(),
22 | ]);
23 | }
24 | path.push([
25 | radius * (0.002 + st * slices as f32).sin(),
26 | radius * (0.002 + st * slices as f32).cos(),
27 | ]);
28 | if invert {
29 | path.reverse();
30 | }
31 | shapes::lathe::create(cam, path, sides, 0.0, 1.0)
32 | }
33 |
--------------------------------------------------------------------------------
/pi3d/src/shapes/string.rs:
--------------------------------------------------------------------------------
1 | use ndarray as nd;
2 | use std::cell::RefCell;
3 | use std::rc::Rc;
4 | use crate::{camera, shape, buffer, shader};
5 | use crate::util::font;
6 |
7 | const GAP: f32 = 1.0; // line spacing
8 | const SPACE: f32 = 0.03; // between char (proportion of line space)
9 | const NORMALS: [[f32; 3]; 4] = [[0.0, 0.0, -1.0]; 4];
10 |
11 | pub fn create(
12 | cam: Rc>,
13 | font: &font::TextureFont,
14 | string: &str,
15 | justify: f32,
16 | ) -> shape::Shape {
17 | //TODO sort out reason for extra vertex (uv point)
18 | let mut verts = Vec::::new();
19 | let mut norms = Vec::::new();
20 | let mut tex_coords = Vec::::new();
21 | let mut faces = Vec::::new();
22 |
23 | let mut xoff = 0.0;
24 | let mut yoff = 0.0;
25 | let nlines = string.matches('\n').count() + 1;
26 | let default = &font.glyph_table[&' '];
27 | let mut temp_verts = Vec::<[f32; 3]>::new();
28 | let mut lines = 0;
29 | let sx = 0.24 * 4.0; //TODO pass size argument?
30 | let sy = 0.24 * 4.0;
31 | let mut maxx = -10000.0;
32 | let mut minx = 10000.0;
33 | let mut maxy = -10000.0;
34 | let mut miny = 10000.0;
35 |
36 | let last_char = string.chars().count() - 1;
37 | for (i, c) in string.chars().enumerate() {
38 | if c != '\n' {
39 | let glyph = match &font.glyph_table.get(&c) {
40 | &Some(g) => g,
41 | _ => default,
42 | };
43 | //let (w, h, texc, verts) = glyph[0:4]
44 | for j in glyph.verts.iter() {
45 | temp_verts.push([j[0] + xoff, j[1], j[2]]);
46 | }
47 | xoff += glyph.w + SPACE * font.height;
48 | for j in glyph.uv.iter() {
49 | tex_coords.push(j[0]);
50 | tex_coords.push(j[1]);
51 | }
52 | for j in NORMALS.iter() {
53 | for k in j.iter() {
54 | norms.push(*k);
55 | }
56 | }
57 | //# Take Into account unprinted \n characters
58 | let stv = 4 * (i - lines) as u16;
59 | faces.push(stv);
60 | faces.push(stv + 1);
61 | faces.push(stv + 2);
62 | faces.push(stv + 2);
63 | faces.push(stv + 3);
64 | faces.push(stv);
65 | }
66 | if i == last_char || c == '\n' {
67 | let cx = xoff * justify;
68 | for temp_vert in &temp_verts {
69 | let x = (temp_vert[0] - cx) * sx;
70 | let y = (temp_vert[1] + nlines as f32 * font.height * GAP / 2.0 - yoff) * sy;
71 | let z = temp_vert[2];
72 | if x < minx {
73 | minx = x;
74 | }
75 | if x > maxx {
76 | maxx = x;
77 | }
78 | if y < miny {
79 | miny = y;
80 | }
81 | if y > maxy {
82 | maxy = y;
83 | }
84 | verts.push(x);
85 | verts.push(y);
86 | verts.push(z);
87 | }
88 | yoff += font.height * GAP;
89 | xoff = 0.0;
90 | temp_verts.clear();
91 | lines += 1;
92 | continue; //don't attempt to draw this character!
93 | }
94 | }
95 | verts.append(&mut vec![0.0; 3]); //TODO why needs extra tex coord?
96 | norms.append(&mut vec![0.0; 3]);
97 | tex_coords.append(&mut vec![0.0; 2]);
98 |
99 | let nverts = verts.len() / 3;
100 | let nfaces = faces.len() / 3;
101 | let av_x = (maxx + minx) * 0.5;
102 | let av_y = (maxy + miny) * 0.5;
103 | for i in 0..nverts {
104 | verts[i * 3] -= av_x; // shift x values
105 | verts[i * 3 + 1] -= av_y; // shift y values and flip
106 | }
107 | let mut new_buffer = buffer::create(
108 | &shader::Program::new(),
109 | nd::Array::from_shape_vec((nverts, 3usize), verts).unwrap(), //TODO make functions return Result and feedback errors
110 | nd::Array::from_shape_vec((nverts, 3usize), norms).unwrap(),
111 | nd::Array::from_shape_vec((nverts, 2usize), tex_coords).unwrap(),
112 | nd::Array::from_shape_vec((nfaces, 3usize), faces).unwrap(),
113 | false,
114 | );
115 | new_buffer.set_textures(&vec![font.tex.id]);
116 | new_buffer.set_blend(true);
117 | shape::create(vec![new_buffer], cam)
118 | }
119 |
--------------------------------------------------------------------------------
/pi3d/src/shapes/tcone.rs:
--------------------------------------------------------------------------------
1 | use std::cell::RefCell;
2 | use std::rc::Rc;
3 | use crate::{camera, shape, shapes};
4 |
5 | pub fn create(
6 | cam: Rc>,
7 | radius_bot: f32,
8 | radius_top: f32,
9 | height: f32,
10 | sides: usize,
11 | ) -> shape::Shape {
12 | let path: Vec<[f32; 2]> = vec![
13 | [0.0, height * 0.5],
14 | [radius_top * 0.999, height * 0.5],
15 | [radius_top, height * 0.5],
16 | [radius_top, height * 0.499],
17 | [radius_bot, -height * 0.499],
18 | [radius_bot, -height * 0.5],
19 | [radius_bot * 0.999, -height * 0.5],
20 | [0.0, -height * 0.5],
21 | ];
22 |
23 | shapes::lathe::create(cam, path, sides, 0.0, 1.0)
24 | }
25 |
--------------------------------------------------------------------------------
/pi3d/src/shapes/torus.rs:
--------------------------------------------------------------------------------
1 | use std::cell::RefCell;
2 | use std::f32::consts;
3 | use std::rc::Rc;
4 | use crate::{camera, shape, shapes};
5 |
6 | pub fn create(
7 | cam: Rc>,
8 | radius: f32,
9 | thickness: f32,
10 | ringrots: usize,
11 | sides: usize,
12 | ) -> shape::Shape {
13 | let st = consts::PI * 2.0 / ringrots as f32;
14 | let path: Vec<[f32; 2]> = (0..=ringrots)
15 | .map(|i| {
16 | let r = st * i as f32;
17 | [radius - thickness * r.cos(), thickness * r.sin()]
18 | })
19 | .collect();
20 |
21 | shapes::lathe::create(cam, path, sides, 0.0, 1.0)
22 | }
23 |
--------------------------------------------------------------------------------
/pi3d/src/shapes/tube.rs:
--------------------------------------------------------------------------------
1 | use ndarray as nd;
2 | use std::cell::RefCell;
3 | use std::f32::consts;
4 | use std::rc::Rc;
5 | use crate::{camera, shape, shapes, buffer, shader};
6 |
7 | pub fn create(
8 | cam: Rc>,
9 | radius: f32,
10 | thickness: f32,
11 | height: f32,
12 | sides: usize,
13 | use_lathe: bool,
14 | ) -> shape::Shape {
15 | let t = thickness * 0.5;
16 | if use_lathe {
17 | let path: Vec<[f32; 2]> = vec![
18 | [radius - t * 0.999, height * 0.5],
19 | [radius + t * 0.999, height * 0.5],
20 | [radius + t, height * 0.5],
21 | [radius + t, height * 0.4999],
22 | [radius + t, -height * 0.4999],
23 | [radius + t, -height * 0.5],
24 | [radius + t * 0.999, -height * 0.5],
25 | [radius - t * 0.999, -height * 0.5],
26 | [radius - t, -height * 0.5],
27 | [radius - t, -height * 0.499],
28 | [radius - t, height * 0.499],
29 | [radius - t, height * 0.5],
30 | ];
31 |
32 | shapes::lathe::create(cam, path, sides, 0.0, 1.0)
33 | } else {
34 | let step = consts::PI * 2.0 / sides as f32;
35 | let otr = radius + t;
36 | let inr = radius - t;
37 | let ht = height * 0.5;
38 | let mut verts = Vec::::new();
39 | let mut norms = Vec::::new();
40 | let mut uvs = Vec::::new();
41 | let mut faces = Vec::::new();
42 |
43 | let normdirs: [[f32; 2]; 4] = [
44 | [0.0, 1.0], //up
45 | [1.0, 0.0], //out
46 | [0.0, -1.0], //down
47 | [-1.0, 0.0],
48 | ]; //in
49 | for i in 0..=sides {
50 | for (j, (xz, y)) in [
51 | (inr, ht),
52 | (otr, ht), // up
53 | (otr, ht),
54 | (otr, -ht), // out
55 | (otr, -ht),
56 | (inr, -ht), // down
57 | (inr, -ht),
58 | (inr, ht),
59 | ]
60 | .iter()
61 | .enumerate()
62 | {
63 | // in
64 | let s = (i as f32 * step).sin();
65 | let c = (i as f32 * step).cos();
66 | verts.extend_from_slice(&[xz * s, *y, xz * c]);
67 | let k: usize = j / 2;
68 | norms.extend_from_slice(&[normdirs[k][0] * s, normdirs[k][1], normdirs[k][0] * c]);
69 | if k == 0 || k == 2 {
70 | // top or bottom
71 | uvs.extend_from_slice(&[
72 | 0.5 * (1.0 + verts[j * 3] / otr),
73 | 0.5 * (1.0 + verts[j * 3 + 2] / otr),
74 | ]);
75 | } else {
76 | uvs.extend_from_slice(&[i as f32 / sides as f32, 0.5 * (1.0 + y / ht)]);
77 | }
78 | }
79 | if i < sides {
80 | for (a, b, c) in [
81 | (0, 1, 8),
82 | (1, 9, 8),
83 | (2, 3, 10),
84 | (3, 11, 10),
85 | (4, 5, 12),
86 | (12, 5, 13),
87 | (6, 7, 14),
88 | (7, 15, 14),
89 | ]
90 | .iter()
91 | {
92 | let f_off = 8 * i as u16;
93 | faces.extend_from_slice(&[a + f_off, b + f_off, c + f_off]);
94 | }
95 | }
96 | }
97 | let nverts = verts.len() / 3;
98 | let nfaces = faces.len() / 3;
99 | let new_buffer = buffer::create(
100 | &shader::Program::new(),
101 | nd::Array::from_shape_vec((nverts, 3usize), verts).unwrap(), //TODO make functions return Result and feedback errors
102 | nd::Array::from_shape_vec((nverts, 3usize), norms).unwrap(),
103 | nd::Array::from_shape_vec((nverts, 2usize), uvs).unwrap(),
104 | nd::Array::from_shape_vec((nfaces, 3usize), faces).unwrap(),
105 | false,
106 | );
107 | shape::create(vec![new_buffer], cam)
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/pi3d/src/texture.rs:
--------------------------------------------------------------------------------
1 | use crate::image::GenericImageView;
2 | use gl::types::*;
3 | use ndarray as nd;
4 | use crate::util::resources;
5 |
6 | pub struct Texture {
7 | pub id: GLuint,
8 | pub image: nd::Array3,
9 | pub width: usize,
10 | pub height: usize,
11 | pub repeat: GLint,
12 | }
13 |
14 | impl Texture {
15 | pub fn update_ndarray(&mut self) {
16 | let (h, w, d) = self.image.dim();
17 | let c_type = match d {
18 | 1 => gl::RED,
19 | 2 => gl::RG,
20 | 3 => gl::RGB,
21 | _ => gl::RGBA, //TODO catching other types such as 5_6_5 or 4_4_4_4
22 | };
23 | unsafe {
24 | gl::BindTexture(gl::TEXTURE_2D, self.id);
25 |
26 | gl::TexParameteri(
27 | gl::TEXTURE_2D,
28 | gl::TEXTURE_MIN_FILTER,
29 | gl::LINEAR_MIPMAP_NEAREST as GLint,
30 | );
31 | gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::LINEAR as GLint);
32 | gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, self.repeat);
33 | gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, self.repeat);
34 | gl::TexImage2D(
35 | gl::TEXTURE_2D,
36 | 0,
37 | c_type as GLint,
38 | w as GLint,
39 | h as GLint,
40 | 0,
41 | c_type,
42 | gl::UNSIGNED_BYTE,
43 | self.image.as_ptr() as *const GLvoid,
44 | );
45 | gl::Enable(gl::TEXTURE_2D);
46 | gl::GenerateMipmap(gl::TEXTURE_2D);
47 | }
48 | }
49 |
50 | pub fn flip_image(&mut self, vert: bool, horizontal: bool) {
51 | let v = if vert { -1 } else { 1 };
52 | let h = if horizontal { -1 } else { 1 };
53 | self.image = self.image.slice(s![..;v, ..;h, ..]).to_owned();
54 | self.update_ndarray();
55 | }
56 |
57 | pub fn size(&mut self) -> (usize, usize) {
58 | let (h, w, _d) = self.image.dim();
59 | (w, h)
60 | }
61 |
62 | pub fn set_mirrored_repeat(&mut self, on: bool) {
63 | self.repeat = if on { gl::MIRRORED_REPEAT } else { gl::REPEAT } as GLint;
64 | self.update_ndarray();
65 | }
66 | }
67 |
68 | impl Drop for Texture {
69 | fn drop(&mut self) {
70 | print!("-tex{:?} ", self.id);
71 | unsafe {
72 | gl::BindTexture(gl::TEXTURE, 0);
73 | gl::DeleteTextures(1, &self.id);
74 | }
75 | }
76 | }
77 |
78 | pub fn create_from_array(image: nd::Array3) -> Texture {
79 | let mut new_id: GLuint = 0;
80 | unsafe {
81 | gl::GenTextures(1, &mut new_id);
82 | }
83 | let (height, width, _d) = image.dim();
84 | let mut tex = Texture {
85 | id: new_id,
86 | image,
87 | width,
88 | height,
89 | repeat: gl::REPEAT as GLint,
90 | };
91 | tex.update_ndarray();
92 | tex
93 | }
94 |
95 | pub fn create_from_file(name: &str) -> Texture {
96 | let pb = resources::resource_name_to_path(name);
97 | let im = image::open(pb).unwrap();
98 | let (w, h) = im.dimensions();
99 | let c_type: usize = match im.color() {
100 | image::ColorType::Gray(_u8) => 1,
101 | image::ColorType::GrayA(_u8) => 2,
102 | image::ColorType::RGB(_u8) => 3,
103 | image::ColorType::RGBA(_u8) => 4,
104 | _ => 4, // TODO catch unrecognised types, need to cope with indexed
105 | };
106 | let image =
107 | nd::Array::from_shape_vec((h as usize, w as usize, c_type), im.raw_pixels()).unwrap();
108 | create_from_array(image)
109 | }
110 |
--------------------------------------------------------------------------------
/pi3d/src/util/font.rs:
--------------------------------------------------------------------------------
1 | use ndarray as nd;
2 | use rusttype::{point, Font, Scale};
3 | use std::collections::HashMap;
4 | use std::fs::File;
5 | use std::io::Read;
6 | use crate::util::resources;
7 | use crate::texture;
8 |
9 | const TEX_SZ: usize = 1024;
10 |
11 | pub struct GlyphTable {
12 | pub w: f32,
13 | pub h: f32,
14 | pub uv: [[f32; 2]; 4],
15 | pub verts: [[f32; 3]; 4],
16 | pub x: f32, //
17 | pub y: f32,
18 | }
19 |
20 | pub struct TextureFont {
21 | pub tex: texture::Texture,
22 | pub glyph_table: HashMap,
23 | pub height: f32,
24 | pub size: f32,
25 | }
26 |
27 | pub fn create(file_name: &str, glyphs: &str, add_glyphs: &str, size: f32) -> TextureFont {
28 | let grid_n = TEX_SZ / (size as usize); //TODO magic numbers!
29 | // Load the font
30 | let path_buf = resources::resource_name_to_path(file_name);
31 | let mut f = File::open(path_buf).expect("file not found");
32 | let mut contents = Vec::new();
33 | f.read_to_end(&mut contents)
34 | .expect("something went wrong reading the file");
35 | let font = Font::from_bytes(contents).expect("Error constructing Font");
36 |
37 | let mut image = nd::Array3::::zeros((TEX_SZ, TEX_SZ, 4));
38 |
39 | let scale = Scale { x: size, y: size };
40 | //TODO space needed
41 | let glyph_list = if glyphs.is_empty() {
42 | "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`1234567890-=~!@#$%^&*()_+[]\\{}|;':,./<>?\""
43 | } else {
44 | glyphs
45 | };
46 | let glyph_list = [glyph_list, add_glyphs].concat();
47 |
48 | let f_v_metrics = font.v_metrics(scale);
49 | let v_step = f_v_metrics.ascent - f_v_metrics.descent; // +ve is up here!
50 | //println!("{:?}", f_v_metrics);
51 | let mut cpoint = point(size * 0.5, size);
52 | //let mut advance = 0.0;
53 | let mut glyph_table = HashMap::::new();
54 | // put in a space as no pixel_bounding_box
55 | glyph_table.insert(
56 | ' ',
57 | GlyphTable {
58 | w: size * 0.2,
59 | h: 1.0,
60 | uv: [[0.01, 0.0], [0.0, 0.0], [0.0, 0.01], [0.01, 0.01]],
61 | verts: [
62 | [0.01, 0.0, 0.0],
63 | [0.0, 0.0, 0.0],
64 | [0.0, -0.01, 0.0],
65 | [0.01, -0.01, 0.0],
66 | ],
67 | x: 0.0,
68 | y: 0.01,
69 | },
70 | );
71 | for (i, c) in glyph_list.chars().enumerate() {
72 | let g = font.glyph(c);
73 | let g = g.scaled(scale);
74 | if let Some(g_b_box) = g.exact_bounding_box() {
75 | // only do this if there's a glyph
76 | cpoint.x =
77 | ((i + 1) % grid_n) as f32 * size + (size - g_b_box.max.x - g_b_box.min.x) * 0.5;
78 | cpoint.y = ((i + 1) / grid_n + 1) as f32 * size; //TODO magic numbers
79 | let g = g.positioned(cpoint);
80 | if let Some(p_b_box) = g.pixel_bounding_box() {
81 | //TODO error catching
82 | g.draw(|x, y, v| {
83 | let px = (x + p_b_box.min.x as u32) as usize;
84 | let py = (y + p_b_box.min.y as u32) as usize;
85 | for j in 0..3 {
86 | image[[py, px, j]] = 255;
87 | }
88 | image[[py, px, 3]] = (v * 255.0) as u8;
89 | });
90 | let cwidth = g_b_box.max.x - g_b_box.min.x;
91 | let cheight = g_b_box.max.y - g_b_box.min.y;
92 | let xscl = (cpoint.x + g_b_box.min.x) / TEX_SZ as f32;
93 | let yscl = (cpoint.y + g_b_box.min.y) / TEX_SZ as f32;
94 | let tw = cwidth / TEX_SZ as f32;
95 | let th = cheight / TEX_SZ as f32;
96 | let gt = GlyphTable {
97 | w: cwidth,
98 | h: cheight,
99 | uv: [
100 | [xscl + tw, yscl + th],
101 | [xscl, yscl + th],
102 | [xscl, yscl],
103 | [xscl + tw, yscl],
104 | ],
105 | verts: [
106 | [cwidth, -g_b_box.max.y, 0.0],
107 | [0.0, -g_b_box.max.y, 0.0],
108 | [0.0, cheight - g_b_box.max.y, 0.0],
109 | [cwidth, cheight - g_b_box.max.y, 0.0],
110 | ],
111 | x: xscl,
112 | y: yscl,
113 | };
114 | glyph_table.insert(c, gt);
115 | }
116 | }
117 | }
118 | let tex = texture::create_from_array(image);
119 | TextureFont {
120 | tex,
121 | glyph_table,
122 | height: v_step,
123 | size,
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/pi3d/src/util/mod.rs:
--------------------------------------------------------------------------------
1 | pub mod font;
2 | pub mod offscreen_texture;
3 | pub mod post_process;
4 | pub mod resources;
5 | pub mod vec3;
6 | pub mod vec4;
7 |
--------------------------------------------------------------------------------
/pi3d/src/util/offscreen_texture.rs:
--------------------------------------------------------------------------------
1 | use gl::types::*;
2 | use crate::display;
3 |
4 | pub struct OffscreenTexture {
5 | pub color_tex_id: GLuint,
6 | pub depth_tex_id: GLuint,
7 | pub width: usize,
8 | pub height: usize,
9 | pub framebuffer: GLuint,
10 | pub depthbuffer: GLuint,
11 | }
12 |
13 | impl OffscreenTexture {
14 | ///
15 | pub fn start(&mut self, clear: bool) {
16 | unsafe {
17 | gl::BindFramebuffer(gl::FRAMEBUFFER, self.framebuffer);
18 | gl::BindRenderbuffer(gl::RENDERBUFFER, self.depthbuffer);
19 | gl::RenderbufferStorage(
20 | gl::RENDERBUFFER,
21 | gl::DEPTH_COMPONENT16,
22 | self.width as GLsizei,
23 | self.height as GLsizei,
24 | );
25 | gl::FramebufferRenderbuffer(
26 | gl::FRAMEBUFFER,
27 | gl::DEPTH_ATTACHMENT,
28 | gl::RENDERBUFFER,
29 | self.depthbuffer,
30 | );
31 | gl::FramebufferTexture2D(
32 | gl::FRAMEBUFFER,
33 | gl::COLOR_ATTACHMENT0,
34 | gl::TEXTURE_2D,
35 | self.color_tex_id,
36 | 0,
37 | );
38 | gl::BindTexture(gl::TEXTURE_2D, 0); // this seems to be needed here
39 | gl::FramebufferTexture2D(
40 | gl::FRAMEBUFFER,
41 | gl::DEPTH_ATTACHMENT,
42 | gl::TEXTURE_2D,
43 | self.depth_tex_id,
44 | 0,
45 | );
46 | if clear {
47 | // TODO allow just depth or just color clearing?
48 | gl::Clear(gl::DEPTH_BUFFER_BIT | gl::COLOR_BUFFER_BIT);
49 | }
50 | }
51 | //TODO global offscreen queue - check why needed.
52 | }
53 | ///
54 | pub fn end(&self) {
55 | unsafe {
56 | gl::BindTexture(gl::TEXTURE_2D, 0);
57 | gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
58 | }
59 | //TODO offscreen queue?
60 | }
61 | ///
62 | pub fn delete_buffers(&mut self) {
63 | unsafe {
64 | gl::DeleteFramebuffers(1, &self.framebuffer);
65 | gl::DeleteRenderbuffers(1, &self.depthbuffer);
66 | gl::BindTexture(gl::TEXTURE, 0);
67 | gl::DeleteTextures(1, &self.color_tex_id);
68 | gl::DeleteTextures(1, &self.depth_tex_id);
69 | }
70 | }
71 | }
72 | ///
73 | impl Drop for OffscreenTexture {
74 | fn drop(&mut self) {
75 | print!("-ost{:?}.{:?} ", self.color_tex_id, self.depth_tex_id);
76 | self.delete_buffers();
77 | }
78 | }
79 |
80 | ///
81 | pub fn create(display: &display::Display) -> OffscreenTexture {
82 | let height = display.height as usize;
83 | let width = display.width as usize;
84 | let mut color_tex_id: GLuint = 0;
85 | let mut depth_tex_id: GLuint = 0;
86 | unsafe {
87 | gl::GenTextures(1, &mut color_tex_id);
88 | gl::BindTexture(gl::TEXTURE_2D, color_tex_id);
89 | gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as GLint);
90 | gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::LINEAR as GLint);
91 | gl::TexParameteri(
92 | gl::TEXTURE_2D,
93 | gl::TEXTURE_WRAP_S,
94 | gl::CLAMP_TO_EDGE as GLint,
95 | );
96 | gl::TexParameteri(
97 | gl::TEXTURE_2D,
98 | gl::TEXTURE_WRAP_T,
99 | gl::CLAMP_TO_EDGE as GLint,
100 | );
101 | gl::TexImage2D(
102 | gl::TEXTURE_2D,
103 | 0,
104 | gl::RGBA as GLint,
105 | width as GLint,
106 | height as GLint,
107 | 0,
108 | gl::RGBA,
109 | gl::UNSIGNED_BYTE,
110 | std::ptr::null() as *const GLvoid,
111 | );
112 | gl::GenerateMipmap(gl::TEXTURE_2D);
113 | gl::BindTexture(gl::TEXTURE_2D, 0);
114 |
115 | gl::GenTextures(1, &mut depth_tex_id);
116 | gl::BindTexture(gl::TEXTURE_2D, depth_tex_id);
117 | gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as GLint);
118 | gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::LINEAR as GLint);
119 | gl::TexParameteri(
120 | gl::TEXTURE_2D,
121 | gl::TEXTURE_WRAP_S,
122 | gl::CLAMP_TO_EDGE as GLint,
123 | );
124 | gl::TexParameteri(
125 | gl::TEXTURE_2D,
126 | gl::TEXTURE_WRAP_T,
127 | gl::CLAMP_TO_EDGE as GLint,
128 | );
129 | gl::TexImage2D(
130 | gl::TEXTURE_2D,
131 | 0,
132 | gl::DEPTH_COMPONENT16 as GLint,
133 | width as GLint,
134 | height as GLint,
135 | 0,
136 | gl::DEPTH_COMPONENT,
137 | gl::UNSIGNED_SHORT,
138 | std::ptr::null() as *const GLvoid,
139 | );
140 | gl::GenerateMipmap(gl::TEXTURE_2D);
141 | gl::BindTexture(gl::TEXTURE_2D, 0);
142 | gl::Enable(gl::TEXTURE_2D);
143 | }
144 | let mut framebuffer: GLuint = 0;
145 | let mut depthbuffer: GLuint = 0;
146 | unsafe {
147 | gl::GenFramebuffers(1, &mut framebuffer);
148 | gl::GenRenderbuffers(1, &mut depthbuffer);
149 | }
150 | OffscreenTexture {
151 | color_tex_id,
152 | depth_tex_id,
153 | width,
154 | height,
155 | framebuffer,
156 | depthbuffer,
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/pi3d/src/util/post_process.rs:
--------------------------------------------------------------------------------
1 | use gl::types::*;
2 |
3 | use std::cell::RefCell;
4 | use std::rc::Rc;
5 | use crate::util::offscreen_texture;
6 | use crate::{shape, camera, shapes, display, shader};
7 |
8 | pub struct PostProcess {
9 | pub offscreen_texture: offscreen_texture::OffscreenTexture,
10 | pub sprite: shape::Shape,
11 | pub scale: f32,
12 | }
13 |
14 | impl PostProcess {
15 | ///
16 | pub fn start_capture(&mut self, clear: bool) {
17 | self.offscreen_texture.start(clear);
18 | let width = self.offscreen_texture.width as f32;
19 | let height = self.offscreen_texture.height as f32;
20 | //if self.scale != 1.0 {
21 | let xx = (width / 2.0 * (1.0 - self.scale)) as GLint;
22 | let yy = (height / 2.0 * (1.0 - self.scale)) as GLint;
23 | let ww = (width * self.scale) as GLint;
24 | let hh = (height * self.scale) as GLint;
25 | unsafe {
26 | gl::Enable(gl::SCISSOR_TEST);
27 | gl::Scissor(xx, yy, ww, hh);
28 | }
29 | //}
30 | }
31 | ///
32 | pub fn end_capture(&mut self) {
33 | self.offscreen_texture.end();
34 | //if self.scale != 1.0 {
35 | unsafe {
36 | gl::Disable(gl::SCISSOR_TEST);
37 | }
38 | //}
39 | }
40 | ///
41 | pub fn draw(&mut self, unif_vals: Vec<(usize, usize, f32)>) {
42 | for (i, j, val) in unif_vals {
43 | self.sprite.unif[[i, j]] = val;
44 | }
45 | self.sprite.draw();
46 | }
47 | }
48 |
49 | pub fn create(
50 | cam: Rc>,
51 | display: &display::Display,
52 | shader: &shader::Program,
53 | add_tex: &[GLuint],
54 | scale: f32,
55 | ) -> PostProcess {
56 | let offscreen_texture = offscreen_texture::create(display);
57 | let mut sprite = shapes::plane::create(cam, display.width, display.height);
58 | sprite.buf[0].unib[[2, 0]] = scale;
59 | sprite.buf[0].unib[[2, 1]] = scale;
60 | sprite.buf[0].unib[[3, 0]] = (1.0 - scale) * 0.5;
61 | sprite.buf[0].unib[[3, 1]] = (1.0 - scale) * 0.5;
62 | sprite.buf[0].textures = vec![
63 | offscreen_texture.color_tex_id,
64 | offscreen_texture.depth_tex_id,
65 | ];
66 | sprite.buf[0].textures.extend(add_tex);
67 | sprite.buf[0].set_shader(shader);
68 | sprite.position_z(20.0);
69 | PostProcess {
70 | offscreen_texture,
71 | sprite,
72 | scale,
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/pi3d/src/util/resources.rs:
--------------------------------------------------------------------------------
1 | use std::fs;
2 | use std::io::{self, Read};
3 | use std::path::PathBuf;
4 |
5 | use crate::shaders::built_in_shaders::{CODES, NAMES};
6 | use crate::{EXE_PATH, CURRENT_DIR};
7 |
8 | #[derive(Debug)]
9 | pub enum Error {
10 | Io(io::Error),
11 | FileContainsNil,
12 | FailedToGetExePath,
13 | MissingResource,
14 | RecursionDepth,
15 | WindowBuildError { name: String },
16 | }
17 |
18 | impl From for Error {
19 | fn from(other: io::Error) -> Self {
20 | Error::Io(other)
21 | }
22 | }
23 |
24 | pub fn load_string(resource_name: &str) -> Result {
25 | let mut listing = Vec::::new();
26 | load_includes(resource_name, &mut listing, 0)?;
27 | Ok(listing.join("\n"))
28 | }
29 | /*
30 | pub fn resource_name_to_path(location: &str) -> PathBuf {
31 | let new_path = PathBuf::from(location);
32 | let mut path = PathBuf::new();
33 | if !new_path.has_root() { // only start from exe root path if not /
34 | path = (*EXE_PATH).to_path_buf(); //why does it need this (clone says it's a Path)
35 | }
36 | path.join(new_path)
37 | }
38 | */
39 | pub fn resource_name_to_path(location: &str) -> PathBuf {
40 | //let new_path = PathBuf::from(location);
41 | let mut exe_path = (*EXE_PATH).to_path_buf();
42 | exe_path.push(location);
43 | let mut cur_path = (*CURRENT_DIR).to_path_buf();
44 | cur_path.push(location);
45 | if cur_path.is_file() {
46 | return cur_path;
47 | }
48 | if exe_path.is_file() {
49 | return exe_path;
50 | }
51 | if cur_path.is_dir() {
52 | return cur_path;
53 | }
54 | exe_path
55 | }
56 |
57 | fn load_includes(resource_name: &str, listing: &mut Vec, depth: u32) -> Result<(), Error> {
58 | if depth > 16 {
59 | return Err(Error::RecursionDepth);
60 | }
61 | let mut text_chunk = String::new();
62 | for (i, name) in NAMES.iter().enumerate() {
63 | // first try built_in_shaders
64 | if *name == resource_name.trim() {
65 | text_chunk = CODES[i].to_string();
66 | break;
67 | }
68 | }
69 | if text_chunk.is_empty() {
70 | // now check file path
71 | let path_buf = resource_name_to_path(resource_name);
72 | if !path_buf.is_file() {
73 | return Err(Error::MissingResource);
74 | } // nope
75 | let mut file = fs::File::open(path_buf).unwrap();
76 | file.read_to_string(&mut text_chunk)?;
77 | }
78 | if text_chunk.is_empty() {
79 | return Err(Error::MissingResource); // still not got anything so stop now
80 | }
81 | for s in (&text_chunk).lines() {
82 | match s.find("#include") {
83 | Some(ix) => {
84 | let (_, new_key) = s.split_at(ix + 9);
85 | load_includes(new_key, listing, depth + 1)?;
86 | }
87 | None => {
88 | listing.push(s.to_string());
89 | }
90 | }
91 | }
92 | Ok(())
93 | }
94 |
--------------------------------------------------------------------------------
/pi3d/src/util/vec3.rs:
--------------------------------------------------------------------------------
1 | /* utility functions working with 1D vectors of xyz f32 values using ndarray::arr1
2 | */
3 | extern crate ndarray;
4 |
5 | use ndarray as nd;
6 |
7 | pub fn add(a: &nd::Array1, b: &nd::Array1) -> nd::Array1 {
8 | a + b
9 | }
10 |
11 | pub fn sub(a: &nd::Array1, b: &nd::Array1) -> nd::Array1 {
12 | a - b
13 | }
14 |
15 | pub fn len(a: &nd::Array1) -> f32 {
16 | let len: f32 = a.iter().map(|x| x * x).sum();
17 | len.sqrt()
18 | }
19 |
20 | pub fn norm(a: &nd::Array1) -> nd::Array1 {
21 | let len = len(a);
22 | if len == 0.0 {
23 | return nd::arr1(&[0.0, 1.0, 0.0]);
24 | }
25 | a / len
26 | }
27 |
28 | pub fn dot(a: &nd::Array1, b: &nd::Array1) -> f32 {
29 | (a * b).sum() // ndarray has .dot()
30 | }
31 |
32 | pub fn cross(a: &nd::Array1, b: &nd::Array1) -> nd::Array1 {
33 | nd::arr1(&[
34 | a[1] * b[2] - a[2] * b[1],
35 | a[2] * b[0] - a[0] * b[2],
36 | a[0] * b[1] - a[1] * b[0],
37 | ])
38 | }
39 |
40 | pub fn rotate_vec(a: &[f32; 3], vecs: &nd::Array2) -> nd::Array2 {
41 | rotate_vec_slice(a, &vecs.slice(s![.., ..]))
42 | }
43 | pub fn rotate_vec_slice(a: &[f32; 3], vecs: &nd::ArrayView2) -> nd::Array2 {
44 | let (cx, sx) = (a[0].cos(), a[0].sin());
45 | let (cy, sy) = (a[1].cos(), a[1].sin());
46 | let (cz, sz) = (a[2].cos(), a[2].sin());
47 | let rx = nd::arr2(&[[1.0, 0.0, 0.0], [0.0, cx, sx], [0.0, -sx, cx]]);
48 | let ry = nd::arr2(&[[cy, 0.0, -sy], [0.0, 1.0, 0.0], [sy, 0.0, cy]]);
49 | let rz = nd::arr2(&[[cz, sz, 0.0], [-sz, cz, 0.0], [0.0, 0.0, 1.0]]);
50 | rz.dot(&rx.dot(&ry.dot(&vecs.reversed_axes())))
51 | .reversed_axes()
52 | }
53 |
54 | /// normalize a 3 column wide slice of an array in place.
55 | ///
56 | /// NB in order for this to be able to work on a slice of an array it
57 | /// requires the lefthand colum 'from' to be supplied as an argument
58 | pub fn normalize_slice(vecs: &mut nd::Array2, from: usize) {
59 | let n = vecs.shape()[0];
60 | for i in 0..n {
61 | let len: f32 = vecs
62 | .slice(s![i, from..(from + 3)])
63 | .iter()
64 | .map(|x| x * x)
65 | .sum();
66 | if len > 0.0 {
67 | let len_inv = 1.0 / len.sqrt();
68 | for j in from..(from + 3) {
69 | vecs[[i, j]] *= len_inv;
70 | }
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/pi3d/src/util/vec4.rs:
--------------------------------------------------------------------------------
1 | /* utility functions working with 1D vectors of xyz f32 values using ndarray::arr1
2 | */
3 | extern crate ndarray;
4 |
5 | use ndarray as nd;
6 |
7 | /// invert a 4x4 matrix TODO not used at the moment
8 | fn _inv_matrix(m: &nd::Array2) -> nd::Array2 {
9 | let a2323 = m[[2, 2]] * m[[3, 3]] - m[[2, 3]] * m[[3, 2]];
10 | let a1323 = m[[2, 1]] * m[[3, 3]] - m[[2, 3]] * m[[3, 1]];
11 | let a1223 = m[[2, 1]] * m[[3, 2]] - m[[2, 2]] * m[[3, 1]];
12 | let a0323 = m[[2, 0]] * m[[3, 3]] - m[[2, 3]] * m[[3, 0]];
13 | let a0223 = m[[2, 0]] * m[[3, 2]] - m[[2, 2]] * m[[3, 0]];
14 | let a0123 = m[[2, 0]] * m[[3, 1]] - m[[2, 1]] * m[[3, 0]];
15 | let a2313 = m[[1, 2]] * m[[3, 3]] - m[[1, 3]] * m[[3, 2]];
16 | let a1313 = m[[1, 1]] * m[[3, 3]] - m[[1, 3]] * m[[3, 1]];
17 | let a1213 = m[[1, 1]] * m[[3, 2]] - m[[1, 2]] * m[[3, 1]];
18 | let a2312 = m[[1, 2]] * m[[2, 3]] - m[[1, 3]] * m[[2, 2]];
19 | let a1312 = m[[1, 1]] * m[[2, 3]] - m[[1, 3]] * m[[2, 1]];
20 | let a1212 = m[[1, 1]] * m[[2, 2]] - m[[1, 2]] * m[[2, 1]];
21 | let a0313 = m[[1, 0]] * m[[3, 3]] - m[[1, 3]] * m[[3, 0]];
22 | let a0213 = m[[1, 0]] * m[[3, 2]] - m[[1, 2]] * m[[3, 0]];
23 | let a0312 = m[[1, 0]] * m[[2, 3]] - m[[1, 3]] * m[[2, 0]];
24 | let a0212 = m[[1, 0]] * m[[2, 2]] - m[[1, 2]] * m[[2, 0]];
25 | let a0113 = m[[1, 0]] * m[[3, 1]] - m[[1, 1]] * m[[3, 0]];
26 | let a0112 = m[[1, 0]] * m[[2, 1]] - m[[1, 1]] * m[[2, 0]];
27 |
28 | let det = 1.0f32
29 | / (m[[0, 0]] * (m[[1, 1]] * a2323 - m[[1, 2]] * a1323 + m[[1, 3]] * a1223)
30 | - m[[0, 1]] * (m[[1, 0]] * a2323 - m[[1, 2]] * a0323 + m[[1, 3]] * a0223)
31 | + m[[0, 2]] * (m[[1, 0]] * a1323 - m[[1, 1]] * a0323 + m[[1, 3]] * a0123)
32 | - m[[0, 3]] * (m[[1, 0]] * a1223 - m[[1, 1]] * a0223 + m[[1, 2]] * a0123));
33 |
34 | nd::arr2(&[
35 | [
36 | det * (m[[1, 1]] * a2323 - m[[1, 2]] * a1323 + m[[1, 3]] * a1223),
37 | det * -(m[[0, 1]] * a2323 - m[[0, 2]] * a1323 + m[[0, 3]] * a1223),
38 | det * (m[[0, 1]] * a2313 - m[[0, 2]] * a1313 + m[[0, 3]] * a1213),
39 | det * -(m[[0, 1]] * a2312 - m[[0, 2]] * a1312 + m[[0, 3]] * a1212),
40 | ],
41 | [
42 | det * -(m[[1, 0]] * a2323 - m[[1, 2]] * a0323 + m[[1, 3]] * a0223),
43 | det * (m[[0, 0]] * a2323 - m[[0, 2]] * a0323 + m[[0, 3]] * a0223),
44 | det * -(m[[0, 0]] * a2313 - m[[0, 2]] * a0313 + m[[0, 3]] * a0213),
45 | det * (m[[0, 0]] * a2312 - m[[0, 2]] * a0312 + m[[0, 3]] * a0212),
46 | ],
47 | [
48 | det * (m[[1, 0]] * a1323 - m[[1, 1]] * a0323 + m[[1, 3]] * a0123),
49 | det * -(m[[0, 0]] * a1323 - m[[0, 1]] * a0323 + m[[0, 3]] * a0123),
50 | det * (m[[0, 0]] * a1313 - m[[0, 1]] * a0313 + m[[0, 3]] * a0113),
51 | det * -(m[[0, 0]] * a1312 - m[[0, 1]] * a0312 + m[[0, 3]] * a0112),
52 | ],
53 | [
54 | det * -(m[[1, 0]] * a1223 - m[[1, 1]] * a0223 + m[[1, 2]] * a0123),
55 | det * (m[[0, 0]] * a1223 - m[[0, 1]] * a0223 + m[[0, 2]] * a0123),
56 | det * -(m[[0, 0]] * a1213 - m[[0, 1]] * a0213 + m[[0, 2]] * a0113),
57 | det * (m[[0, 0]] * a1212 - m[[0, 1]] * a0212 + m[[0, 2]] * a0112),
58 | ],
59 | ])
60 | }
61 |
--------------------------------------------------------------------------------
/pyo3_module/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | edition = "2024"
3 | name = "rpi3d"
4 | version = "0.1.0"
5 | authors = ["paddywwof "]
6 |
7 | [lib]
8 | name = "rpi3d"
9 | crate-type = ["cdylib"]
10 |
11 | [dependencies]
12 | numpy = "0.22"
13 | ndarray = "0.16"
14 | pi3d = {path = "../pi3d"}
15 | gl = "^0.10"
16 |
17 | [dependencies.pyo3]
18 | version = "0.22"
19 | features = ["extension-module"]
20 |
21 | [profile.release]
22 | codegen-units = 1
23 | incremental = true
--------------------------------------------------------------------------------
/pyo3_module/README.md:
--------------------------------------------------------------------------------
1 | Start of an attempt to make a python wrapper for rust_pi3d using pyo3.
2 | You should be able to compile the module either:
3 |
4 | in pyo3_module run ``python3 setup.py bdist_wheel`` then open the
5 | whl file in ``dist`` and extract ``rpi3d/rpi3d-0.1....so`` to the
6 | ``pyo3_module/test`` directory. You should be able to run test1.py
7 |
8 | or:
9 |
10 | in pyo3_module run ``cargo build --release`` then copy and rename
11 | ``librpi3d.so`` to ``pyo3_module/test/rpi3d.so``
12 |
13 | ~~NB you must use nightly for pyo3 ``rustup install nightly`` then
14 | ``rust default nightly``, switch back with ``rustup default stable``~~ Works
15 | using stable rust now.
16 |
--------------------------------------------------------------------------------
/pyo3_module/setup.py:
--------------------------------------------------------------------------------
1 | from setuptools import find_packages, setup
2 |
3 | try:
4 | from setuptools_rust import RustExtension
5 | except ImportError:
6 | import subprocess
7 | import sys
8 |
9 | errno = subprocess.call([sys.executable, "-m", "pip", "install", "setuptools-rust", "--user"])
10 | if errno:
11 | print("Please install setuptools-rust package")
12 | raise SystemExit(errno)
13 | else:
14 | from setuptools_rust import RustExtension
15 |
16 | setup_requires = ['setuptools-rust>=0.10.2']
17 | #install_requires = ['numpy']
18 |
19 | setup(
20 | name='rpi3d',
21 | version='0.1.0',
22 | description='Python wrapper on rust_pi3d using pyo3',
23 | rust_extensions=[RustExtension(
24 | 'rpi3d.rpi3d',
25 | './Cargo.toml',
26 | )],
27 | #install_requires=install_requires,
28 | setup_requires=setup_requires,
29 | packages=find_packages(),
30 | zip_safe=False,
31 | )
--------------------------------------------------------------------------------
/pyo3_module/src/core.rs:
--------------------------------------------------------------------------------
1 | use pyo3::exceptions;
2 | use pyo3::prelude::*;
3 | use pyo3::PyObject; //, PyRawObject};
4 |
5 | use numpy::{IntoPyArray, PyArray3};
6 |
7 | use std::cell::RefCell;
8 | use std::rc::Rc;
9 | use crate::{util, shapes};
10 |
11 | #[pyclass(unsendable)] // think SDL requires this to stay in main thread
12 | pub struct Display {
13 | pub r_display: Rc>,
14 | }
15 |
16 | #[pymethods]
17 | impl Display {
18 | #[new]
19 | #[args(
20 | name = "\"\"",
21 | w = "0.0",
22 | h = "0.0",
23 | profile = "\"GLES\"",
24 | major = "2",
25 | minor = "0"
26 | )]
27 | fn new(name: &str, w: f32, h: f32, profile: &str, major: u8, minor: u8) -> Self {
28 | let (wnew, hnew, fullscreen) = if w <= 0.0 || h <= 0.0 {
29 | (100.0, 100.0, true)
30 | } else {
31 | (w, h, false)
32 | };
33 | /*let dispnew = Arc::new(Mutex::new(
34 | pi3d::display::create(name, wnew, hnew, profile, major, minor).unwrap()
35 | ));*/
36 | let dispnew = Rc::new(RefCell::new(
37 | pi3d::display::create(name, wnew, hnew, profile, major, minor).unwrap(),
38 | ));
39 | if fullscreen {
40 | dispnew.borrow_mut().set_fullscreen(true);
41 | }
42 | Display { r_display: dispnew }
43 | }
44 |
45 | #[staticmethod]
46 | #[args(
47 | name = "\"\"",
48 | w = "0.0",
49 | h = "0.0",
50 | profile = "\"GLES\"",
51 | major = "2",
52 | minor = "0"
53 | )]
54 | fn create(
55 | name: &str,
56 | w: f32,
57 | h: f32,
58 | profile: &str,
59 | major: u8,
60 | minor: u8,
61 | ) -> PyResult> {
62 | let gil = Python::acquire_gil();
63 | let py = gil.python();
64 | let (wnew, hnew, fullscreen) = if w <= 0.0 || h <= 0.0 {
65 | (100.0, 100.0, true)
66 | } else {
67 | (w, h, false)
68 | };
69 | let r_display = Rc::new(RefCell::new(
70 | pi3d::display::create(name, wnew, hnew, profile, major, minor).unwrap(),
71 | ));
72 | if fullscreen {
73 | r_display.borrow_mut().set_fullscreen(true);
74 | }
75 | r_display.borrow_mut().set_target_fps(1000.0); //TODO set to 60; testing run as fast as poss
76 | r_display.borrow_mut().set_mouse_relative(true);
77 | Py::new(py, Display { r_display })
78 | }
79 |
80 | fn loop_running(&mut self) -> PyResult {
81 | Ok(self.r_display.borrow_mut().loop_running())
82 | }
83 | }
84 |
85 | /// Camera stuff
86 | ///
87 | #[pyclass(unsendable)]
88 | pub struct Camera {
89 | pub r_camera: pi3d::camera::Camera,
90 | }
91 |
92 | #[pymethods]
93 | impl Camera {
94 | #[new]
95 | fn new(display: &Display) -> Self {
96 | Camera {
97 | r_camera: pi3d::camera::create(&display.r_display.borrow()),
98 | }
99 | }
100 | fn reset(&mut self) {
101 | self.r_camera.reset();
102 | }
103 | fn set_3d(&mut self, is_3d: bool) {
104 | self.r_camera.set_3d(is_3d);
105 | }
106 | fn position(&mut self, pos: Vec) {
107 | if pos.len() != 3 {
108 | return;
109 | }
110 | self.r_camera.position(&[pos[0], pos[1], pos[2]]);
111 | }
112 | fn rotate(&mut self, rot: Vec) {
113 | if rot.len() != 3 {
114 | return;
115 | }
116 | self.r_camera.rotate(&[rot[0], rot[1], rot[2]]);
117 | }
118 | fn get_direction(&mut self) -> Vec {
119 | self.r_camera.get_direction().to_vec()
120 | }
121 | }
122 |
123 | /// Shader stuff
124 | ///
125 | #[pyclass]
126 | pub struct Shader {
127 | pub r_shader: pi3d::shader::Program,
128 | }
129 |
130 | #[pymethods]
131 | impl Shader {
132 | #[new]
133 | fn new(name: &str) -> Self {
134 | Shader {
135 | r_shader: pi3d::shader::Program::from_res(name).unwrap(),
136 | }
137 | }
138 | }
139 |
140 | /// Keyboard stuff
141 | ///
142 | #[pyclass(unsendable)]
143 | struct Keyboard {
144 | r_display: Rc>,
145 | }
146 |
147 | #[pymethods]
148 | impl Keyboard {
149 | #[new]
150 | fn new(display: &Display) -> Self {
151 | Keyboard {
152 | r_display: display.r_display.clone(),
153 | }
154 | }
155 | /// crude char reading as per pi3d
156 | fn read_code(&self) -> String {
157 | let disp = self.r_display.borrow();
158 | if disp.keys_pressed.len() > 0 {
159 | return disp.keys_pressed.last().unwrap().name();
160 | }
161 | "".to_string()
162 | }
163 | }
164 |
165 | /// Mouse stuff
166 | ///
167 | #[pyclass(unsendable)]
168 | struct Mouse {
169 | r_display: Rc>,
170 | }
171 |
172 | #[pymethods]
173 | impl Mouse {
174 | #[new]
175 | fn new(display: &Display) -> Self {
176 | Mouse {
177 | r_display: display.r_display.clone(),
178 | }
179 | }
180 | /// also need velocity, values depend on mouse relative (also visibility of cursor)
181 | fn position(&self) -> (i32, i32) {
182 | let disp = self.r_display.borrow();
183 | (disp.mouse_x, disp.mouse_y)
184 | }
185 | }
186 |
187 | /// Texture stuff
188 | ///
189 | #[pyclass]
190 | pub struct Texture {
191 | pub r_texture: pi3d::texture::Texture,
192 | }
193 |
194 | #[pymethods]
195 | impl Texture {
196 | #[new]
197 | fn new(file_name: &str) -> Self {
198 | Texture {
199 | r_texture: pi3d::texture::create_from_file(file_name),
200 | }
201 | }
202 | fn print_id(&self) {
203 | println!("texid={}", self.r_texture.id);
204 | }
205 | #[getter]
206 | fn get_image(&mut self) -> PyResult>> {
207 | let gil = pyo3::Python::acquire_gil();
208 | let py = gil.python();
209 | Ok(self.r_texture.image.clone().into_pyarray(py).to_owned())
210 | }
211 | #[setter]
212 | fn set_image(&mut self, im_arr: &PyArray3) -> PyResult<()> {
213 | unsafe {
214 | let new_im_arr = im_arr.as_array().to_owned();
215 | let new_shape = new_im_arr.shape();
216 | let old_shape = self.r_texture.image.shape();
217 | if new_shape[0] != old_shape[0] || new_shape[1] != old_shape[1] {
218 | return Err(PyErr::new::(
219 | "array wrong shape",
220 | ));
221 | }
222 | //TODO fix different 3rd dim size (1,3,4)
223 | self.r_texture.image = new_im_arr;
224 | }
225 | self.r_texture.update_ndarray();
226 | Ok(())
227 | }
228 | }
229 |
230 | #[pymodule]
231 | fn rpi3d(_py: Python, m: &PyModule) -> PyResult<()> {
232 | m.add_class::()?;
233 | m.add_class::()?;
234 | m.add_class::()?;
235 | m.add_class::()?;
236 | m.add_class::()?;
237 | m.add_class::()?;
238 |
239 | m.add_class::()?;
240 | m.add_class::()?;
241 |
242 | m.add_class::()?;
243 | m.add_class::()?;
244 | m.add_class::()?;
245 | m.add_class::()?;
246 | m.add_class::()?;
247 | m.add_class::()?;
248 | m.add_class::()?;
249 | m.add_class::()?;
250 | m.add_class::()?;
251 | m.add_class::()?;
252 | m.add_class::()?;
253 | m.add_class::()?;
254 | m.add_class::()?;
255 | m.add_class::()?;
256 | m.add_class::()?;
257 | m.add_class::()?;
258 | m.add_class::()?;
259 |
260 | m.add_class::()?;
261 | Ok(())
262 | }
263 |
--------------------------------------------------------------------------------
/pyo3_module/src/lib.rs:
--------------------------------------------------------------------------------
1 | extern crate gl;
2 | extern crate numpy;
3 | extern crate pi3d;
4 | extern crate pyo3;
5 |
6 | pub mod core;
7 | pub mod shapes;
8 | pub mod util;
9 |
--------------------------------------------------------------------------------
/pyo3_module/src/util.rs:
--------------------------------------------------------------------------------
1 | use pyo3::prelude::*;
2 | use pyo3::PyObject;
3 | use crate::core;
4 |
5 | //use numpy::{IntoPyArray, PyArray3};
6 |
7 | /// Font stuff
8 | ///
9 | #[pyclass]
10 | pub struct Font {
11 | pub r_font: pi3d::util::font::TextureFont,
12 | }
13 |
14 | #[pymethods]
15 | impl Font {
16 | #[new]
17 | fn new(file_name: &str, glyphs: &str, add_glyphs: &str, size: f32) -> Self {
18 | Font {
19 | r_font: pi3d::util::font::create(file_name, glyphs, add_glyphs, size),
20 | }
21 | }
22 | }
23 | /// PostProcess stuff
24 | ///
25 | #[pyclass(unsendable)]
26 | pub struct PostProcess {
27 | pub r_postprocess: pi3d::util::post_process::PostProcess,
28 | }
29 |
30 | #[pymethods]
31 | impl PostProcess {
32 | #[new]
33 | fn new(
34 | camera: &mut core::Camera,
35 | display: &core::Display,
36 | shader: &core::Shader,
37 | add_tex: Vec>,
38 | scale: f32,
39 | ) -> Self {
40 | let texlist:Vec = add_tex.iter().map(|t| t.r_texture.id).collect();
41 | PostProcess {
42 | r_postprocess: pi3d::util::post_process::create(
43 | camera.r_camera.reference(),
44 | &display.r_display.borrow(),
45 | &shader.r_shader,
46 | &texlist,
47 | scale,
48 | ),
49 | }
50 | }
51 | pub fn start_capture(&mut self, clear: bool) {
52 | self.r_postprocess.start_capture(clear);
53 | }
54 | pub fn end_capture(&mut self) {
55 | self.r_postprocess.end_capture();
56 | }
57 | pub fn draw(&mut self, unif_vals: Vec<(usize, usize, f32)>) {
58 | self.r_postprocess.draw(unif_vals);
59 | }
60 | /*#[getter]//don't think this will work! Probably need gl::ReadPixels()
61 | fn get_image(&mut self) -> PyResult>> {
62 | let gil = pyo3::Python::acquire_gil();
63 | let py = gil.python();
64 | Ok(self.r_postprocess.offscreen_texture.tex.image
65 | .clone()
66 | .into_pyarray(py)
67 | .to_owned()
68 | )
69 | }*/
70 | }
71 |
--------------------------------------------------------------------------------
/pyo3_module/test/NotoSerif-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pyo3_module/test/NotoSerif-Regular.ttf
--------------------------------------------------------------------------------
/pyo3_module/test/floor_nm.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pyo3_module/test/floor_nm.jpg
--------------------------------------------------------------------------------
/pyo3_module/test/hornbeam2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pyo3_module/test/hornbeam2.png
--------------------------------------------------------------------------------
/pyo3_module/test/mountains3_512.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pyo3_module/test/mountains3_512.jpg
--------------------------------------------------------------------------------
/pyo3_module/test/mountainsHgt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pyo3_module/test/mountainsHgt.png
--------------------------------------------------------------------------------
/pyo3_module/test/pattern.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pyo3_module/test/pattern.png
--------------------------------------------------------------------------------
/pyo3_module/test/rpi3d.cpython-37m-arm-linux-gnueabihf.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pyo3_module/test/rpi3d.cpython-37m-arm-linux-gnueabihf.so
--------------------------------------------------------------------------------
/pyo3_module/test/rust_pi3d.mtl:
--------------------------------------------------------------------------------
1 | # Blender MTL File: 'pi3R.blend'
2 | # Material Count: 6
3 |
4 | newmtl None
5 | Ns 500
6 | Ka 0.8 0.8 0.8
7 | Kd 0.8 0.8 0.8
8 | Ks 0.8 0.8 0.8
9 | d 1
10 | illum 2
11 |
12 | newmtl black_rust
13 | Ns 225.000000
14 | Ka 1.000000 1.000000 1.000000
15 | Kd 0.009134 0.008023 0.007499
16 | Ks 0.500000 0.500000 0.500000
17 | Ke 0.0 0.0 0.0
18 | Ni 1.450000
19 | d 1.000000
20 | illum 3
21 |
22 | newmtl blue
23 | Ns 225.000000
24 | Ka 1.000000 1.000000 1.000000
25 | Kd 0.034340 0.061246 0.799103
26 | Ks 0.500000 0.500000 0.500000
27 | Ke 0.0 0.0 0.0
28 | Ni 1.450000
29 | d 1.000000
30 | illum 2
31 |
32 | newmtl green
33 | Ns 225.000000
34 | Ka 1.000000 1.000000 1.000000
35 | Kd 0.003347 0.309469 0.010330
36 | Ks 0.500000 0.500000 0.500000
37 | Ke 0.0 0.0 0.0
38 | Ni 1.450000
39 | d 1.000000
40 | illum 2
41 |
42 | newmtl red
43 | Ns 225.000000
44 | Ka 1.000000 1.000000 1.000000
45 | Kd 0.799103 0.000000 0.006512
46 | Ks 0.500000 0.500000 0.500000
47 | Ke 0.0 0.0 0.0
48 | Ni 1.450000
49 | d 1.000000
50 | illum 2
51 |
52 | newmtl yellow
53 | Ns 225.000000
54 | Ka 1.000000 1.000000 1.000000
55 | Kd 0.799103 0.391572 0.004025
56 | Ks 0.500000 0.500000 0.500000
57 | Ke 0.0 0.0 0.0
58 | Ni 1.450000
59 | d 1.000000
60 | illum 2
61 |
--------------------------------------------------------------------------------
/pyo3_module/test/sbox_back.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pyo3_module/test/sbox_back.jpg
--------------------------------------------------------------------------------
/pyo3_module/test/sbox_bottom.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pyo3_module/test/sbox_bottom.jpg
--------------------------------------------------------------------------------
/pyo3_module/test/sbox_front.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pyo3_module/test/sbox_front.jpg
--------------------------------------------------------------------------------
/pyo3_module/test/sbox_left.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pyo3_module/test/sbox_left.jpg
--------------------------------------------------------------------------------
/pyo3_module/test/sbox_right.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pyo3_module/test/sbox_right.jpg
--------------------------------------------------------------------------------
/pyo3_module/test/sbox_top.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/pyo3_module/test/sbox_top.jpg
--------------------------------------------------------------------------------
/pyo3_module/test/test1.py:
--------------------------------------------------------------------------------
1 | import rpi3d
2 | import os
3 | import time
4 | import numpy as np
5 | from PIL import Image
6 |
7 | display = rpi3d.Display.create("pyo3 minimal", w=1920, h=1080, profile="GLES", major=2, minor=0)
8 | shader = rpi3d.Shader("uv_light")
9 | shader_flat = rpi3d.Shader("uv_flat")
10 | shader_mat = rpi3d.Shader("mat_reflect")
11 | shader_post = rpi3d.Shader("post_base")
12 |
13 | keybd = rpi3d.Keyboard(display)
14 | mouse = rpi3d.Mouse(display)
15 | tex = rpi3d.Texture("pattern.png")
16 | tex2 = rpi3d.Texture("mountains3_512.jpg")
17 | ntex = tex.image.copy()
18 | ntex[:64,:,:2] += 64
19 | tex.image = ntex
20 |
21 | camera = rpi3d.Camera(display)
22 | camera2d = rpi3d.Camera(display)
23 | camera2d.set_3d(False)
24 |
25 | plane = rpi3d.Plane(camera, 300.0, 300.0) # NB camera has to be passed to Shape constructor
26 | plane.set_draw_details(shader_flat, [tex])
27 | plane.position_z(300.0)
28 |
29 | cube = rpi3d.Tube(camera)
30 | cube.set_draw_details(shader, [tex])
31 | cube.position([-2.0, 8.0, 5.0])
32 |
33 | sphere = rpi3d.Sphere(camera)
34 | sphere.set_draw_details(shader, [tex])
35 | sphere.position([0.0, 10.0, 4.0])
36 |
37 | verts = [[0.0, 2.0], [0.5, 1.9], [0.2, 1.8], [1.0, 0.5], [1.0, 0.4], [0.0, 0.0]]
38 | lathe = rpi3d.Lathe(camera, verts, 16, 0.0, 1.0)
39 | lathe.set_draw_details(shader, [tex])
40 | lathe.position([2.0, 8.0, 4.0])
41 |
42 | verts = [-1.0, 2.0, 1.0, -1.2, -0.5, 1.0, -0.2, -0.5, 1.0, 0.0, -1.0, 1.0, 1.5, 0.5, 1.0]
43 | lines = rpi3d.Lines(camera, verts, 5.0, True)
44 | lines.set_draw_details(shader, [tex])
45 | lines.position([2.0, 12.0, 5.0])
46 |
47 | points = rpi3d.Points(camera, verts, 40.0)
48 | points.set_draw_details(shader, [tex])
49 | points.position([-2.0, 12.0, 5.0])
50 |
51 | font = rpi3d.Font("NotoSerif-Regular.ttf", "", "", 64)
52 | string = rpi3d.PyString(camera2d, font, "Hello from rust pi3d", 0.0)
53 | string.set_shader(shader_flat)
54 | string.position([100.0, 100.0, 4.0])
55 |
56 | sphere.scale([0.5, 1.5, 0.5])
57 | sphere.position([1.0, 1.0, 1.0])
58 | child = rpi3d.RefShape(sphere)
59 | sphere.position([0.0, 10.0, 4.0])
60 | sphere.scale([0.7, 0.7, 0.7])
61 | cube.add_child(child)
62 |
63 | terrain = rpi3d.ElevationMap(camera, "mountainsHgt.png", 500.0, 500.0, 20.0, 32, 32, 1.0, "nothing")
64 | terrain.set_draw_details(shader, [tex2])
65 | terrain.position([0.0, -2.0, 0.0])
66 |
67 | tree_tex = rpi3d.Texture("hornbeam2.png")
68 | treeplane = rpi3d.Plane(camera, 2.0, 2.0)
69 | treemodel = rpi3d.MergeShape(camera)
70 | treemodel.add_shapes([treeplane, treeplane], [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]], [[0.0, 0.0, 0.0], [0.0, 1.5, 0.0]],
71 | [[1.0, 2.0, 1.0], [1.0, 2.0, 1.0]], [0, 0])
72 | trees = rpi3d.MergeShape(camera)
73 | trees.cluster(treemodel, terrain, 50.0, 50.0, 100.0, 50.0, 0.5, 7.5, 100)
74 | trees.set_draw_details(shader_flat, [tree_tex])
75 |
76 | normtex = rpi3d.Texture("floor_nm.jpg")
77 | model = rpi3d.Model(camera, "rust_pi3d.obj")
78 | model.set_shader(shader_mat)
79 | model.set_normal_shine(normtex=normtex, ntiles=4.0, shinetex=tree_tex, shiny=0.05, bump_factor=0.02)
80 | model.position([-30, 10, 30])
81 | model.scale([20, 20, 20])
82 | model.rotate_to_y(-2.5)
83 |
84 | ecube = rpi3d.EnvironmentCube(camera, 900, "sbox", "jpg")
85 | ecube.set_shader(shader_flat)
86 |
87 | n=0
88 | tm = time.time()
89 | (mx, my) = (0, 0)
90 | (rot, tilt) = (0, 0)
91 | (x, y, z) = (0, 0, 0)
92 | ds = 0.01
93 | while display.loop_running():
94 | string.draw()
95 | string.rotate_inc_z(0.001)
96 |
97 | plane.draw()
98 | plane.rotate_inc_z(0.001)
99 |
100 | cube.draw()
101 | child.rotate_inc_y(0.01)
102 | cube.rotate_inc_z(0.0017)
103 | cube.rotate_inc_x(0.0021)
104 | cube.rotate_inc_y(0.0001)
105 |
106 | sphere.draw()
107 | sphere.rotate_inc_z(0.001)
108 | sphere.rotate_inc_x(0.0021)
109 | sphere.rotate_inc_y(0.007)
110 | if n % 50 == 0:
111 | pb = sphere.array_buffer.copy()
112 | pb[:,:3] *= np.random.random((len(pb), 3)) * 0.01 + 0.995
113 | sphere.array_buffer = pb
114 |
115 | lathe.draw()
116 | lathe.rotate_inc_z(0.001)
117 | lathe.rotate_inc_x(0.0021)
118 | lathe.rotate_inc_y(0.0011)
119 |
120 | lines.draw()
121 | lines.rotate_inc_z(0.001)
122 | lines.rotate_inc_x(0.0021)
123 | lines.rotate_inc_y(0.0011)
124 |
125 | points.draw()
126 | points.rotate_inc_z(0.001)
127 | points.rotate_inc_x(0.0021)
128 | points.rotate_inc_y(0.0011)
129 |
130 | model.draw()
131 |
132 | trees.draw()
133 |
134 | terrain.draw()
135 |
136 | ecube.draw()
137 |
138 | n += 1
139 | k = keybd.read_code()
140 | if len(k) > 0:
141 | if k == 'W':
142 | ds = 0.25
143 | elif k == 'S':
144 | ds = -0.07
145 |
146 | (new_mx, new_my) = (mouse.position())
147 | if new_mx != mx or new_my != my or ds != 0.0:
148 | (mx, my) = (new_mx, new_my)
149 | tilt = (my - 300.0) * -0.004
150 | rot = (mx - 400.0) * -0.004
151 | camera.reset()
152 | camera.rotate([tilt, rot, 0.0])
153 |
154 | if ds != 0.0:
155 | cd = camera.get_direction()
156 | x += cd[0] * ds
157 | y += cd[1] * ds
158 | z += cd[2] * ds
159 | (newy, _mapnorm) = terrain.calc_height(x, z)
160 | y = newy + 0.0
161 | camera.position([x, y, z])
162 | ds = 0.0 ## to trick camera setting to terrail
163 |
164 | print("{:.1f} FPS".format(n / (time.time() - tm)))
165 |
--------------------------------------------------------------------------------
/pyo3_module/test/test2.py:
--------------------------------------------------------------------------------
1 | import rpi3d
2 | import os
3 | import time
4 | import numpy as np
5 | from PIL import Image
6 |
7 | display = rpi3d.Display.create("pyo3 minimal", w=800, h=600, profile="GLES", major=2, minor=0)
8 | shader = rpi3d.Shader("uv_light")
9 | shader_flat = rpi3d.Shader("uv_flat")
10 | shader_post = rpi3d.Shader("post_base")
11 |
12 | keybd = rpi3d.Keyboard(display)
13 | mouse = rpi3d.Mouse(display)
14 | tex = rpi3d.Texture("pattern.png")
15 | tex2 = rpi3d.Texture("mountains3_512.jpg")
16 |
17 | camera = rpi3d.Camera(display)
18 | camera2d = rpi3d.Camera(display)
19 | camera2d.set_3d(False)
20 |
21 | plane = rpi3d.Plane(camera, 300.0, 300.0) # NB camera has to be passed to Shape constructor
22 | plane.set_draw_details(shader_flat, [tex])
23 | plane.position_z(300.0)
24 |
25 | cube = rpi3d.Tube(camera)
26 | cube.set_draw_details(shader, [tex])
27 | cube.position([-2.0, 8.0, 5.0])
28 |
29 | sphere = rpi3d.Sphere(camera)
30 | sphere.set_draw_details(shader, [tex])
31 | sphere.position([0.0, 10.0, 4.0])
32 |
33 | verts = [[0.0, 2.0], [0.5, 1.9], [0.2, 1.8], [1.0, 0.5], [1.0, 0.4], [0.0, 0.0]]
34 | lathe = rpi3d.Lathe(camera, verts, 16, 0.0, 1.0)
35 | lathe.set_draw_details(shader, [tex])
36 | lathe.position([2.0, 8.0, 4.0])
37 |
38 | verts = [-1.0, 2.0, 1.0, -1.2, -0.5, 1.0, -0.2, -0.5, 1.0, 0.0, -1.0, 1.0, 1.5, 0.5, 1.0]
39 | lines = rpi3d.Lines(camera, verts, 5.0, True)
40 | lines.set_draw_details(shader, [tex])
41 | lines.position([2.0, 12.0, 5.0])
42 |
43 | points = rpi3d.Points(camera, verts, 40.0)
44 | points.set_draw_details(shader, [tex])
45 | points.position([-2.0, 12.0, 5.0])
46 |
47 | font = rpi3d.Font("NotoSerif-Regular.ttf", "", "", 64)
48 | string = rpi3d.PyString(camera2d, font, "Hello from rust pi3d", 0.0)
49 | string.set_shader(shader_flat)
50 | string.position([100.0, 100.0, 4.0])
51 |
52 | terrain = rpi3d.ElevationMap(camera, "mountainsHgt.png", 500.0, 500.0, 20.0, 32, 32, 1.0, "nothing")
53 | terrain.set_draw_details(shader, [tex2])
54 | terrain.position([0.0, -2.0, 0.0])
55 |
56 | post = rpi3d.PostProcess(camera2d, display, shader_post, [], 1.0)
57 |
58 | n=0
59 | tm = time.time()
60 | (mx, my) = (0, 0)
61 | (rot, tilt) = (0, 0)
62 | (x, y, z) = (0, 0, 0)
63 | ds = 0.01
64 | while display.loop_running():
65 | string.draw()
66 | string.rotate_inc_z(0.001)
67 |
68 | post.start_capture(True)
69 | plane.draw()
70 | plane.rotate_inc_z(0.001)
71 |
72 | cube.draw()
73 | cube.rotate_inc_z(0.0017)
74 | cube.rotate_inc_x(0.0021)
75 | cube.rotate_inc_y(0.0001)
76 |
77 | sphere.draw()
78 | sphere.rotate_inc_z(0.001)
79 | sphere.rotate_inc_x(0.0021)
80 | sphere.rotate_inc_y(0.007)
81 |
82 | lathe.draw()
83 | lathe.rotate_inc_z(0.001)
84 | lathe.rotate_inc_x(0.0021)
85 | lathe.rotate_inc_y(0.0011)
86 |
87 | lines.draw()
88 | lines.rotate_inc_z(0.001)
89 | lines.rotate_inc_x(0.0021)
90 | lines.rotate_inc_y(0.0011)
91 |
92 | points.draw()
93 | points.rotate_inc_z(0.001)
94 | points.rotate_inc_x(0.0021)
95 | points.rotate_inc_y(0.0011)
96 |
97 | terrain.draw()
98 |
99 | post.end_capture()
100 |
101 | n += 1
102 | k = keybd.read_code()
103 | if len(k) > 0:
104 | if k == 'W':
105 | ds = 0.25
106 | elif k == 'S':
107 | ds = -0.07
108 |
109 | (new_mx, new_my) = (mouse.position())
110 | if new_mx != mx or new_my != my or ds != 0.0:
111 | (mx, my) = (new_mx, new_my)
112 | tilt = (my - 300.0) * -0.004
113 | rot = (mx - 400.0) * -0.004
114 | camera.reset()
115 | camera.rotate([tilt, rot, 0.0])
116 |
117 | if ds != 0.0:
118 | cd = camera.get_direction()
119 | x += cd[0] * ds
120 | y += cd[1] * ds
121 | z += cd[2] * ds
122 | (newy, _mapnorm) = terrain.calc_height(x, z)
123 | y = newy + 0.0
124 | camera.position([x, y, z])
125 | ds = 0.0 ## to trick camera setting to terrail
126 | f = (tilt + rot) * 0.2 + (400 + x + y + z) * 0.01
127 | f = abs(f % 10.0 - 5.0) # triangular rather than saw-tooth
128 | post.draw([(16, 0, f), (16, 1, 0.0), (16, 2, 0.0)])
129 |
130 | print("{:.1f} FPS".format(n / (time.time() - tm)))
--------------------------------------------------------------------------------
/pyo3_module/test/test3.py:
--------------------------------------------------------------------------------
1 | import rpi3d
2 | import os
3 | import time
4 |
5 | display = rpi3d.Display.create("pyo3 minimal", w=800, h=600, profile="GLES", major=2, minor=0)
6 | shader = rpi3d.Shader("uv_light")
7 | shader_flat = rpi3d.Shader("uv_flat")
8 | shader_blur = rpi3d.Shader("defocus")
9 |
10 | keybd = rpi3d.Keyboard(display)
11 | mouse = rpi3d.Mouse(display)
12 | tex = rpi3d.Texture("pattern.png")
13 | tex2 = rpi3d.Texture("mountains3_512.jpg")
14 |
15 | camera = rpi3d.Camera(display)
16 | camera2d = rpi3d.Camera(display)
17 | camera2d.set_3d(False)
18 |
19 | cube = rpi3d.Tube(camera)
20 | cube.position([-4.0, 7.0, 2.0])
21 | cube.set_draw_details(shader, [tex])
22 |
23 | sphere = rpi3d.Sphere(camera)
24 | sphere.position([-3.0, 8.0, 3.0])
25 | sphere.set_draw_details(shader, [tex])
26 |
27 | font = rpi3d.Font("NotoSerif-Regular.ttf", "", "", 64)
28 | string = rpi3d.PyString(camera2d, font, "Hello from rust pi3d", 0.0)
29 | string.set_shader(shader_flat)
30 | string.position([100.0, 100.0, 4.0])
31 |
32 | terrain = rpi3d.ElevationMap(camera, "mountainsHgt.png", 500.0, 500.0, 20.0, 32, 32, 1.0, "nothing")
33 | terrain.set_draw_details(shader, [tex2])
34 | terrain.position([0.0, -2.0, 0.0])
35 |
36 | defocus = rpi3d.PostProcess(camera2d, display, shader_blur, [], 1.0)
37 |
38 | n=0
39 | tm = time.time()
40 | (mx, my) = (0, 0)
41 | (rot, tilt) = (0, 0)
42 | (x, y, z) = (0, 0, 0)
43 | ds = 0.01
44 | while display.loop_running():
45 |
46 | #string.draw()
47 | #string.rotate_inc_z(0.001)
48 |
49 | defocus.start_capture(True)
50 |
51 | terrain.draw()
52 |
53 | cube.draw()
54 | cube.rotate_inc_z(0.0017)
55 | cube.rotate_inc_x(0.0021)
56 | cube.rotate_inc_y(0.0001)
57 |
58 | sphere.draw()
59 | sphere.rotate_inc_z(0.001)
60 | sphere.rotate_inc_x(0.0021)
61 | sphere.rotate_inc_y(0.007)
62 |
63 | defocus.end_capture()
64 |
65 | n += 1
66 | k = keybd.read_code()
67 | if len(k) > 0:
68 | if k == 'W':
69 | ds = 0.25
70 | elif k == 'S':
71 | ds = -0.07
72 |
73 | (new_mx, new_my) = mouse.position()
74 | if new_mx != mx or new_my != my or ds != 0.0:
75 | (mx, my) = (new_mx, new_my)
76 | tilt = (my - 300.0) * -0.004
77 | rot = (mx - 400.0) * -0.004
78 | camera.reset()
79 | camera.rotate([tilt, rot, 0.0])
80 |
81 | if ds != 0.0:
82 | cd = camera.get_direction()
83 | x += cd[0] * ds
84 | y += cd[1] * ds
85 | z += cd[2] * ds
86 | (newy, _mapnorm) = terrain.calc_height(x, z)
87 | y = newy + 0.0
88 | camera.position([x, y, z])
89 | ds = 0.0 ## to trick camera setting to terrail
90 |
91 | defocus.draw([(14, 0, 0.7), (14, 1, 0.1), (14, 2, 0.003)])
92 |
93 |
94 | print("{:.1f} FPS".format(n / (time.time() - tm)))
--------------------------------------------------------------------------------
/rust_pi3d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddywwoof/rust_pi3d/de7e673c1c18751cf95a5bf48aeb74ca33d3fb47/rust_pi3d.png
--------------------------------------------------------------------------------