extern crate neocogi;
use neocogi::glfw;
use neocogi::glfw::{Action, Context, Key};
use neocogi::rs_math3d::*;
use neocogi::*;
use neocogi::renderer::*;
use std::sync::*;
static VERTEX_SHADER: &'static str = "
#version 300 es
in highp vec4 position;
in highp vec4 color;
out highp vec4 v_color;
void main() {
gl_Position = position;
v_color = color;
}";
static PIXEL_SHADER: &'static str = "
#version 300 es
precision mediump float;
in highp vec4 v_color;
layout(location = 0) out lowp vec4 color_buffer;
void main() {
highp vec4 col = v_color;
color_buffer = col;
}";
render_data! {
vertex Vertex {
position: Vec4f,
color : Vec4f,
}
}
fn init_render_objects(driver: &mut DriverPtr) -> PipelinePtr {
let mut model_attribs = Vec::new();
model_attribs.push(Vertex::get_attribute_names());
let model_shader_desc = ShaderDesc {
vertex_shader: String::from(VERTEX_SHADER),
pixel_shader: String::from(PIXEL_SHADER),
vertex_attributes: model_attribs,
vertex_uniforms: Vec::new(),
vertex_surfaces: Vec::new(),
pixel_uniforms: Vec::new(),
pixel_surfaces: Vec::new(),
};
let model_program = driver.create_shader(model_shader_desc).unwrap();
let vertex_layout = VertexBufferLayout {
buffer_id: 0,
vertex_attributes: Vertex::get_attribute_descriptors(),
stride: Vertex::stride(),
divisor: 0,
};
let tri_pipeline_desc = PipelineDesc {
primitive_type: PrimitiveType::Triangles,
shader: model_program.clone(),
buffer_layouts: vec![vertex_layout.clone()],
uniform_descs: Vec::new(),
index_type: IndexType::None,
face_winding: FaceWinding::CCW,
cull_mode: CullMode::None,
depth_write: true,
depth_test: true,
blend: BlendOp::None,
polygon_offset: PolygonOffset::None,
};
driver.create_pipeline(tri_pipeline_desc).unwrap()
}
fn main() {
let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();
glfw.window_hint(glfw::WindowHint::ContextCreationApi(
glfw::ContextCreationApi::Egl,
));
glfw.window_hint(glfw::WindowHint::ClientApi(glfw::ClientApiHint::OpenGlEs));
glfw.window_hint(glfw::WindowHint::ContextVersion(3, 0));
glfw.window_hint(glfw::WindowHint::OpenGlProfile(
glfw::OpenGlProfileHint::Core,
));
glfw.window_hint(glfw::WindowHint::DoubleBuffer(true));
glfw.window_hint(glfw::WindowHint::Resizable(true));
glfw.window_hint(glfw::WindowHint::Floating(true));
let (mut window, events) = glfw
.create_window(1024, 900, "Triangle", glfw::WindowMode::Windowed)
.expect("Failed to create GLFW window.");
window.set_char_polling(true);
window.set_cursor_pos_polling(true);
window.set_key_polling(true);
window.set_mouse_button_polling(true);
window.make_current();
glfw.set_swap_interval(glfw::SwapInterval::Sync(1));
let mut driver = renderer::get_driver();
let vertices = vec![
Vertex {
position: Vec4f::new(-0.5, -0.5, 0.0, 1.0),
color: Vec4f::new(1.0, 0.0, 0.0, 1.0),
},
Vertex {
position: Vec4f::new(0.5, -0.5, 0.0, 1.0),
color: Vec4f::new(0.0, 0.0, 1.0, 1.0),
},
Vertex {
position: Vec4f::new(0.0, 0.5, 0.0, 1.0),
color: Vec4f::new(0.0, 1.0, 0.0, 1.0),
},
];
let mut vertex_buffer = driver
.create_device_buffer(DeviceBufferDesc::Vertex(Usage::Dynamic(
3 * std::mem::size_of::<Vertex>(),
)))
.unwrap();
let pipeline = init_render_objects(&mut driver);
let mut quit = false;
while !window.should_close() {
let (width, height) = window.get_framebuffer_size();
let mut pass = Pass::new(
width as usize,
height as usize,
None,
[
ColorPassAction::Clear(color4b(0x00, 0x00, 0x00, 0x00)),
ColorPassAction::Previous,
ColorPassAction::Previous,
ColorPassAction::Previous,
],
DepthPassAction::Clear(1.0),
);
let bindings = Bindings {
vertex_buffers: vec![vertex_buffer.clone()],
index_buffer: None,
vertex_images: Vec::new(),
pixel_images: Vec::new(),
};
pass.update_device_buffer(&mut vertex_buffer, 0, Arc::new(vertices.to_vec()));
pass.draw(&pipeline, &bindings, Arc::new(Vec::<Vec3f>::new()), 1, 1);
driver.render_pass(&mut pass);
window.swap_buffers();
glfw.poll_events();
for (_, event) in glfw::flush_messages(&events) {
match event {
glfw::WindowEvent::Key(glfw::Key::Escape, _, _, _) | glfw::WindowEvent::Close => {
quit = true
}
_ => (),
}
}
if quit {
window.set_should_close(true)
}
}
}