three_d/
core.rs

1//!
2//! Mid-level modular abstractions of common graphics concepts such as buffer, texture, program, render target and so on.
3//! Can be combined with low-level calls in the [context](crate::context) module as well as high-level functionality in the [renderer](crate::renderer) module.
4//!
5#![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    //!
38    //! Basic types used throughout this crate, mostly basic math.
39    //!
40    pub use three_d_asset::prelude::*;
41}
42pub use prelude::*;
43pub use three_d_asset::Viewport;
44
45/// A result for this crate.
46use thiserror::Error;
47
48///
49/// Error in the [core](crate::core) module.
50///
51#[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 {
103        std::slice::from_raw_parts(
104            data.as_ptr() as *const _,
105            data.len() * std::mem::size_of::<T>(),
106        )
107    }
108}
109
110fn from_byte_slice<T: DataType>(data: &[u8]) -> &[T] {
111    unsafe {
112        let (_prefix, values, _suffix) = data.align_to::<T>();
113        values
114    }
115}
116
117fn format_from_data_type<T: DataType>() -> u32 {
118    match T::size() {
119        1 => crate::context::RED,
120        2 => crate::context::RG,
121        3 => crate::context::RGB,
122        4 => crate::context::RGBA,
123        _ => unreachable!(),
124    }
125}
126
127fn flip_y<T: TextureDataType>(pixels: &mut [T], width: usize, height: usize) {
128    for row in 0..height / 2 {
129        for col in 0..width {
130            let index0 = width * row + col;
131            let index1 = width * (height - row - 1) + col;
132            pixels.swap(index0, index1);
133        }
134    }
135}