Skip to main content

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 { 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}