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
use super::*;
use super::errors::*;

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct ProgramPipelineId(u32);

impl ProgramPipelineId {
    pub fn empty() -> ProgramPipelineId {
        ProgramPipelineId(0)
    }
}

impl From<ProgramPipelineId> for u32 {
    fn from(program_id: ProgramPipelineId) -> Self {
        program_id.0
    }
}

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum PipelineShaderStage {
    Vertex,
    Fragment,
    Geometry,
    TessellationEvaluation,
    TessellationControl,
    Compute,
}

impl From<PipelineShaderStage> for u32 {
    fn from(shader_stage: PipelineShaderStage) -> Self {
        match shader_stage {
            PipelineShaderStage::Vertex => gl::VERTEX_SHADER_BIT,
            PipelineShaderStage::Fragment => gl::FRAGMENT_SHADER_BIT,
            PipelineShaderStage::Geometry => gl::GEOMETRY_SHADER_BIT,
            PipelineShaderStage::TessellationEvaluation => gl::TESS_EVALUATION_SHADER_BIT,
            PipelineShaderStage::TessellationControl => gl::TESS_CONTROL_SHADER_BIT,
            PipelineShaderStage::Compute => gl::COMPUTE_SHADER_BIT,
        }
    }
}

pub unsafe fn create_program_pipeline() -> ProgramPipelineId {
    let mut pipeline_id: u32 = 0;
    let pipeline_id_ptr: *mut u32 = &mut pipeline_id;

    gl::CreateProgramPipelines(1, pipeline_id_ptr);

    ProgramPipelineId(pipeline_id)
}

pub unsafe fn delete_program_pipeline(id: ProgramPipelineId) {
    let pipeline_id_ptr: *const u32 = &id.into();

    gl::DeleteProgramPipelines(1, pipeline_id_ptr);
}

pub unsafe fn use_program_stage(
    pipeline: ProgramPipelineId,
    stage: PipelineShaderStage,
    program: ShaderProgramId,
) -> Result<()> {
    gl::UseProgramStages(pipeline.into(), stage.into(), program.into());

    get_error(())
}

pub unsafe fn bind_program_pipeline(pipeline: ProgramPipelineId) {
    gl::BindProgramPipeline(pipeline.into());
}