1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
use super::*;
use super::errors::*;

use std::os::raw::c_void;

#[repr(C, packed)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct DrawElementsIndirectCommand {
    pub count: u32,
    pub instance_count: u32,
    pub first_index: u32,
    pub base_vertex: u32,
    pub base_instance: u32,
}

#[repr(C, packed)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct DrawArraysIndirectCommand {
    pub count: u32,
    pub instance_count: u32,
    pub first: u32,
    pub base_instance: u32,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum DrawMode {
    Points,
    LineStrip,
    LineLoop,
    Lines,
    LineStripAdjacency,
    LinesAdjacency,
    TriangleStrip,
    TriangleFan,
    Triangles,
    TriangleStripAdjacency,
    TrianglesAdjacency,
    Patches,
}

impl From<DrawMode> for gl::types::GLenum {
    fn from(draw_mode: DrawMode) -> gl::types::GLenum {
        match draw_mode {
            DrawMode::Points => gl::POINTS,
            DrawMode::LineStrip => gl::LINE_STRIP,
            DrawMode::LineLoop => gl::LINE_LOOP,
            DrawMode::Lines => gl::LINES,
            DrawMode::LineStripAdjacency => gl::LINE_STRIP_ADJACENCY,
            DrawMode::LinesAdjacency => gl::LINES_ADJACENCY,
            DrawMode::TriangleStrip => gl::TRIANGLE_STRIP,
            DrawMode::TriangleFan => gl::TRIANGLE_FAN,
            DrawMode::Triangles => gl::TRIANGLES,
            DrawMode::TriangleStripAdjacency => gl::TRIANGLE_STRIP_ADJACENCY,
            DrawMode::TrianglesAdjacency => gl::TRIANGLES_ADJACENCY,
            DrawMode::Patches => gl::PATCHES,
        }
    }
}

pub unsafe fn draw_arrays(mode: DrawMode, first: usize, count: usize) -> Result<()> {
    gl::DrawArrays(mode.into(), first as i32, count as i32);

    get_error(())
}

pub unsafe fn draw_arrays_indirect(mode: DrawMode, offset: usize) -> Result<()> {
    gl::DrawArraysIndirect(mode.into(), offset as *const usize as *const c_void);

    get_error(())
}

pub unsafe fn draw_arrays_instanced(mode: DrawMode, first: usize, count: usize, primitive_count: usize) -> Result<()> {
    gl::DrawArraysInstanced(
        mode.into(),
        first as i32,
        count as i32,
        primitive_count as i32,
    );

    get_error(())
}

pub unsafe fn draw_arrays_instanced_base_instace(
    mode: DrawMode,
    first: usize,
    count: usize,
    primitive_count: usize,
    base_instance: usize,
) -> Result<()> {
    gl::DrawArraysInstancedBaseInstance(
        mode.into(),
        first as i32,
        count as i32,
        primitive_count as i32,
        base_instance as u32,
    );

    get_error(())
}

pub unsafe fn multi_draw_arrays(mode: DrawMode, first: &[u32], count: &[u32], draw_count: usize) -> Result<()> {
    gl::MultiDrawArrays(
        mode.into(),
        first.as_ptr() as *const i32,
        count.as_ptr() as *const i32,
        draw_count as i32,
    );

    get_error(())
}

pub unsafe fn multi_draw_arrays_indirect(mode: DrawMode, draw_count: usize, stride: usize) -> Result<()> {
    gl::MultiDrawArraysIndirect(
        mode.into(),
        0 as *const ::std::os::raw::c_void,
        draw_count as i32,
        stride as i32,
    );

    get_error(())
}

pub unsafe fn multi_draw_elements_indirect(mode: DrawMode, draw_count: usize, stride: usize) -> Result<()> {
    gl::MultiDrawElementsIndirect(
        mode.into(),
        gl::UNSIGNED_INT,
        0 as *const ::std::os::raw::c_void,
        draw_count as i32,
        stride as i32,
    );

    get_error(())
}