OpenCores
URL https://opencores.org/ocsvn/pdp1/pdp1/trunk

Subversion Repositories pdp1

[/] [pdp1/] [trunk/] [sw/] [src/] [main.rs] - Blame information for rev 18

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 13 yannv
#[macro_use]
2
extern crate glium;
3
extern crate rand;
4 14 yannv
extern crate time;
5 13 yannv
 
6
fn main() {
7
    use rand::Rng;
8
    let mut rng = rand::thread_rng();
9
    use glium::DisplayBuild;
10
    let builder = glium::glutin::WindowBuilder::new();
11
    let window = builder
12
        .with_dimensions(1024,1024)
13
        .with_title("GLscope")
14
        .with_vsync()
15
        .build_glium()
16
        .unwrap();
17 14 yannv
    let mut now: f32;
18 13 yannv
 
19
    // 2D vertex type for plot points
20 18 yannv
    #[derive(Copy, Clone, Debug)]
21 13 yannv
    struct Vertex {
22
        position: [f32; 2],
23 14 yannv
        time: f32  // Suggest using microseconds
24 13 yannv
    }
25
    implement_vertex!(Vertex, position, time);
26
    // Note: need to transform -1023..1023 to -1..1
27
    // Could extend PDP-1 display instruction to 18 bit
28
 
29
    // TODO: Set up OpenGL stuff to draw something
30
    //window.make_current().expect("Couldn't make context current");
31
    let mut frame = window.draw();
32
    use glium::Surface;
33
    // So far, so good. I can clear the image.
34
    // I can also plot points, using two shaders.
35
    // Those can be blended (additive in this case).
36
    // Time to extend the vertices with a timestamp for age?
37
 
38
    // Set up a random array of points
39 14 yannv
    /*
40 13 yannv
    let mut shape: Vec = Vec::new();
41
    for t in 0..20000 {
42
        shape.push(Vertex {
43
            position: [rng.next_f32()*2.0-1.0,
44
                       rng.next_f32()*2.0-1.0],
45
            time: t as f32 });
46 14 yannv
    }*/
47
    let vbmax = 20000;
48
    let mut vbindex = 0;
49
    // TODO: streaming suited vertexbuffer.
50
    // Docs say to use dynamic, persistent might be GL4?
51
    let mut vertex_buffer : glium::VertexBuffer =
52
        glium::VertexBuffer::empty_dynamic(&window, vbmax).unwrap();
53 15 yannv
    // Possible todo: add line support, perhaps modulated
54
    // by beam trace speed.
55 13 yannv
    let indices = glium::index::NoIndices(
56
        glium::index::PrimitiveType::Points);
57
 
58
    let vertex_shader_src = r#"
59
        #version 140
60
        in vec2 position;
61
        in float time;
62
        out float age;
63
        uniform float now;
64
        void main() {
65
            age = now-time;
66
            if (age >= 0) {
67
                gl_Position = vec4(position, 0.0, 1.0);
68
            }
69
        }
70
    "#;
71
 
72
    // Should use a uniform to indicate current time
73
    // Possibly add a timestamp per lit dot?
74
    let fragment_shader_src = r#"
75
        #version 140
76
        in float age;
77
        out vec4 color;
78
        void main() {
79 14 yannv
            float intensity = 1e1*exp(-8e-6*age);
80 13 yannv
            color = vec4(intensity, intensity, intensity, 1.0);
81
        }
82
    "#;
83
    let program =
84
       glium::Program::from_source(&window,
85
                                   vertex_shader_src,
86
                                   fragment_shader_src,
87
                                   None).unwrap();
88
    let drawparams = glium::DrawParameters {
89
        blend: glium::Blend {
90
            color: glium::BlendingFunction::Addition {
91
                source: glium::LinearBlendingFactor::One,
92
                destination: glium::LinearBlendingFactor::One },
93
            .. Default::default() },
94
        .. Default::default()
95
    };
96 14 yannv
 
97
    let t0 = time::get_time();
98 15 yannv
 
99
    use std::sync::mpsc::{channel, Receiver};
100 18 yannv
    let verts : Receiver = {
101 15 yannv
        use std::thread::spawn;
102
 
103
        let (tx, rx) = channel();
104
        spawn(move || {
105
            loop {
106 18 yannv
                let mut str = String::new();
107
                std::io::stdin().read_line(&mut str).unwrap();
108 15 yannv
                let now = (time::get_time() - t0)
109
                    .num_microseconds().unwrap() as f32;
110
                // FIXME: Parse line.
111
                let mut words = str.split_whitespace();
112
                let x = words.next().unwrap().parse().unwrap();
113
                let y = words.next().unwrap().parse().unwrap();
114
                let v = Vertex {position: [x, y], time: now };
115
                tx.send(v).unwrap();
116 18 yannv
                //println!("Vertex: {:?}", v);
117 15 yannv
            }
118
        });
119
        rx
120 18 yannv
    };
121 14 yannv
 
122 13 yannv
    loop {
123
        for event in window.poll_events() {
124
            // Simplest nowait: use poll_events()
125
            match event {
126
                glium::glutin::Event::Closed => {
127
                    frame.finish().unwrap();
128
                    return;
129
                },
130
                _ => ()
131
            }
132
        }
133 14 yannv
 
134
        now = (time::get_time() - t0).num_microseconds().unwrap()
135
            as f32;
136
 
137
        // Inject new points
138
        {
139
            let mut wvb = vertex_buffer.map_write();
140
            // Add 21 random points per frame
141
            for _ in 0..20 {
142
                wvb.set(vbindex, Vertex {
143
                    position: [rng.next_f32()*2.0-1.0,
144
                               rng.next_f32()*2.0-1.0],
145
                    time: now });
146
                vbindex = (vbindex+1) % vbmax;
147
            }
148
            // TODO: Read points from e.g. stdin
149 15 yannv
            for v in verts.try_iter() {
150
                //println!("Vertex: {:?} {} {}",
151
                //         v.position, v.time, now);
152
                wvb.set(vbindex, v);
153 14 yannv
                vbindex = (vbindex+1) % vbmax;
154
            }
155
        }
156
 
157 13 yannv
        // Closing the window closes the program.
158
        frame.clear_color(0.0, 0.0, 0.0, 1.0);
159
        frame.draw(&vertex_buffer, &indices, &program,
160
                   //&glium::uniforms::EmptyUniforms,
161
                   &uniform! { now: now },
162
                   &drawparams).unwrap();
163
 
164
        window.swap_buffers().unwrap();
165
    }
166
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.