triangle/
triangle.rs

1//
2// Copyright 2021-Present (c) Raja Lehtihet & Wael El Oraiby
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are met:
6//
7// 1. Redistributions of source code must retain the above copyright notice,
8// this list of conditions and the following disclaimer.
9//
10// 2. Redistributions in binary form must reproduce the above copyright notice,
11// this list of conditions and the following disclaimer in the documentation
12// and/or other materials provided with the distribution.
13//
14// 3. Neither the name of the copyright holder nor the names of its contributors
15// may be used to endorse or promote products derived from this software without
16// specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28// POSSIBILITY OF SUCH DAMAGE.
29//
30extern crate neocogi;
31
32use neocogi::glfw;
33use neocogi::glfw::{Action, Context, Key};
34
35use neocogi::rs_math3d::*;
36use neocogi::*;
37
38use neocogi::renderer::*;
39
40use std::sync::*;
41
42static VERTEX_SHADER: &'static str = "
43#version 300 es
44in  highp   vec4        position;
45in  highp   vec4        color;
46out highp   vec4        v_color;
47void main() {
48    gl_Position = position;
49    v_color     = color;
50}";
51
52static PIXEL_SHADER: &'static str = "
53#version 300 es
54precision mediump float;
55        in highp    vec4        v_color;
56layout(location = 0) out lowp  vec4     color_buffer;
57void main() {
58    highp vec4 col  = v_color;
59    color_buffer    = col;
60}";
61
62render_data! {
63    vertex Vertex {
64        position: Vec4f,
65        color   : Vec4f,
66    }
67}
68
69fn init_render_objects(driver: &mut DriverPtr) -> PipelinePtr {
70    let mut model_attribs = Vec::new();
71    model_attribs.push(Vertex::get_attribute_names());
72
73    let model_shader_desc = ShaderDesc {
74        vertex_shader: String::from(VERTEX_SHADER),
75        pixel_shader: String::from(PIXEL_SHADER),
76
77        vertex_attributes: model_attribs,
78        vertex_uniforms: Vec::new(),
79        vertex_surfaces: Vec::new(),
80
81        pixel_uniforms: Vec::new(),
82        pixel_surfaces: Vec::new(),
83    };
84
85    let model_program = driver.create_shader(model_shader_desc).unwrap();
86
87    let vertex_layout = VertexBufferLayout {
88        buffer_id: 0,
89        vertex_attributes: Vertex::get_attribute_descriptors(),
90        stride: Vertex::stride(),
91        divisor: 0,
92    };
93
94    let tri_pipeline_desc = PipelineDesc {
95        primitive_type: PrimitiveType::Triangles,
96        shader: model_program.clone(),
97        buffer_layouts: vec![vertex_layout.clone()],
98        uniform_descs: Vec::new(),
99        index_type: IndexType::None,
100        face_winding: FaceWinding::CCW,
101        cull_mode: CullMode::None,
102        depth_write: true,
103        depth_test: true,
104        blend: BlendOp::None,
105        polygon_offset: PolygonOffset::None,
106    };
107
108    driver.create_pipeline(tri_pipeline_desc).unwrap()
109}
110
111fn main() {
112    // initialize GLFW3 with OpenGL ES 3.0
113    let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();
114    glfw.window_hint(glfw::WindowHint::ContextCreationApi(
115        glfw::ContextCreationApi::Egl,
116    ));
117    glfw.window_hint(glfw::WindowHint::ClientApi(glfw::ClientApiHint::OpenGlEs));
118    glfw.window_hint(glfw::WindowHint::ContextVersion(3, 0));
119    glfw.window_hint(glfw::WindowHint::OpenGlProfile(
120        glfw::OpenGlProfileHint::Core,
121    ));
122    glfw.window_hint(glfw::WindowHint::DoubleBuffer(true));
123    glfw.window_hint(glfw::WindowHint::Resizable(true));
124    glfw.window_hint(glfw::WindowHint::Floating(true));
125
126    let (mut window, events) = glfw
127        .create_window(1024, 900, "Triangle", glfw::WindowMode::Windowed)
128        .expect("Failed to create GLFW window.");
129
130    window.set_char_polling(true);
131    window.set_cursor_pos_polling(true);
132    window.set_key_polling(true);
133    window.set_mouse_button_polling(true);
134    window.make_current();
135    glfw.set_swap_interval(glfw::SwapInterval::Sync(1));
136
137    let mut driver = renderer::get_driver();
138
139    let vertices = vec![
140        Vertex {
141            position: Vec4f::new(-0.5, -0.5, 0.0, 1.0),
142            color: Vec4f::new(1.0, 0.0, 0.0, 1.0),
143        },
144        Vertex {
145            position: Vec4f::new(0.5, -0.5, 0.0, 1.0),
146            color: Vec4f::new(0.0, 0.0, 1.0, 1.0),
147        },
148        Vertex {
149            position: Vec4f::new(0.0, 0.5, 0.0, 1.0),
150            color: Vec4f::new(0.0, 1.0, 0.0, 1.0),
151        },
152    ];
153
154    let mut vertex_buffer = driver
155        .create_device_buffer(DeviceBufferDesc::Vertex(Usage::Dynamic(
156            3 * std::mem::size_of::<Vertex>(),
157        )))
158        .unwrap();
159    let pipeline = init_render_objects(&mut driver);
160
161    let mut quit = false;
162    while !window.should_close() {
163        let (width, height) = window.get_framebuffer_size();
164
165        let mut pass = Pass::new(
166            width as usize,
167            height as usize,
168            None,
169            [
170                ColorPassAction::Clear(color4b(0x00, 0x00, 0x00, 0x00)),
171                ColorPassAction::Previous,
172                ColorPassAction::Previous,
173                ColorPassAction::Previous,
174            ],
175            DepthPassAction::Clear(1.0),
176        );
177
178        let bindings = Bindings {
179            vertex_buffers: vec![vertex_buffer.clone()],
180            index_buffer: None,
181
182            vertex_images: Vec::new(),
183            pixel_images: Vec::new(),
184        };
185
186        pass.update_device_buffer(&mut vertex_buffer, 0, Arc::new(vertices.to_vec()));
187        pass.draw(&pipeline, &bindings, Arc::new(Vec::<Vec3f>::new()), 1, 1);
188        driver.render_pass(&mut pass);
189        window.swap_buffers();
190
191        glfw.poll_events();
192        for (_, event) in glfw::flush_messages(&events) {
193            match event {
194                glfw::WindowEvent::Key(glfw::Key::Escape, _, _, _) | glfw::WindowEvent::Close => {
195                    quit = true
196                }
197                _ => (),
198            }
199        }
200
201        if quit {
202            window.set_should_close(true)
203        }
204    }
205}