1#![allow(unsafe_code)]
6
7mod context;
8#[doc(inline)]
9pub use context::*;
10
11pub mod buffer;
12pub use buffer::*;
13
14pub mod texture;
15pub use texture::*;
16
17pub mod render_states;
18pub use render_states::*;
19
20pub mod render_target;
21pub use render_target::*;
22
23mod uniform;
24#[doc(inline)]
25pub use uniform::*;
26
27mod program;
28#[doc(inline)]
29pub use program::*;
30
31mod scissor_box;
32#[doc(inline)]
33pub use scissor_box::*;
34
35pub mod prelude {
36
37 pub use three_d_asset::prelude::*;
41}
42pub use prelude::*;
43pub use three_d_asset::Viewport;
44
45use thiserror::Error;
47
48#[derive(Debug, Error)]
52#[allow(missing_docs)]
53pub enum CoreError {
54 #[error("failed creating context with error: {0}")]
55 ContextCreation(String),
56 #[error("failed rendering with error: {0}")]
57 ContextError(String),
58 #[error("failed compiling {0} shader\n\nsource:\n{1}\n\nlog:\n{2}")]
59 ShaderCompilation(String, String, String),
60 #[error("failed to link shader program: {0}")]
61 ShaderLink(String),
62 #[error(
63 "failed to compile a shader program, probably due to performance or memory constraints"
64 )]
65 ShaderCompilerError,
66}
67
68pub(crate) fn full_screen_draw(
69 context: &Context,
70 program: &Program,
71 render_states: RenderStates,
72 viewport: Viewport,
73) {
74 unsafe { context.bind_vertex_array(Some(context.vao)) };
75 program.draw_arrays(render_states, viewport, 3);
76}
77
78pub(crate) fn full_screen_vertex_shader_source() -> &'static str {
79 "
80 out vec2 uvs;
81 out vec4 col;
82 void main()
83 {
84 vec3 vertices[3] = vec3[3](
85 vec3(-3.0, -1.0, 0.0),
86 vec3(3.0, -1.0, 0.0),
87 vec3(0.0, 2.0, 0.0)
88 );
89
90 vec3 position = vertices[gl_VertexID];
91
92 uvs = 0.5 * position.xy + 0.5;
93 col = vec4(1.0);
94 gl_Position = vec4(position, 1.0);
95 }
96 "
97}
98
99mod data_type;
100use data_type::DataType;
101fn to_byte_slice<T: DataType>(data: &[T]) -> &[u8] {
102 unsafe { std::slice::from_raw_parts(data.as_ptr() as *const _, std::mem::size_of_val(data)) }
103}
104
105fn from_byte_slice<T: DataType>(data: &[u8]) -> &[T] {
106 unsafe {
107 let (_prefix, values, _suffix) = data.align_to::<T>();
108 values
109 }
110}
111
112fn format_from_data_type<T: DataType>() -> u32 {
113 match T::size() {
114 1 => crate::context::RED,
115 2 => crate::context::RG,
116 3 => crate::context::RGB,
117 4 => crate::context::RGBA,
118 _ => unreachable!(),
119 }
120}
121
122fn flip_y<T: TextureDataType>(pixels: &mut [T], width: usize, height: usize) {
123 for row in 0..height / 2 {
124 for col in 0..width {
125 let index0 = width * row + col;
126 let index1 = width * (height - row - 1) + col;
127 pixels.swap(index0, index1);
128 }
129 }
130}