]> git.tdb.fi Git - libs/gl.git/blob - source/core/pipelinestate.cpp
15de0b4dce3e91f39bc1aea641a0a6d32da7979a
[libs/gl.git] / source / core / pipelinestate.cpp
1 #include <stdexcept>
2 #include <msp/core/algorithm.h>
3 #include "pipelinestate.h"
4
5 using namespace std;
6
7 namespace Msp {
8 namespace GL {
9
10 PipelineState::PipelineState():
11         framebuffer(0),
12         viewport(0),
13         scissor(0),
14         shprog(0),
15         vertex_setup(0),
16         front_face(COUNTERCLOCKWISE),
17         face_cull(NO_CULL),
18         enabled_clip_planes(0),
19         depth_test(0),
20         stencil_test(0),
21         blend(0),
22         changes(0)
23 { }
24
25 template<typename T>
26 void PipelineState::set(T &target, T value, unsigned flag)
27 {
28         if(value!=target)
29         {
30                 target = value;
31                 changes |= flag;
32         }
33 }
34
35 void PipelineState::set_framebuffer(const Framebuffer *f)
36 {
37         set(framebuffer, f, FRAMEBUFFER);
38 }
39
40 void PipelineState::set_viewport(const Rect *v)
41 {
42         set(viewport, v, VIEWPORT);
43 }
44
45 void PipelineState::set_scissor(const Rect *s)
46 {
47         set(scissor, s, SCISSOR);
48 }
49
50 void PipelineState::set_shader_program(const Program *p)
51 {
52         set(shprog, p, SHPROG);
53 }
54
55 void PipelineState::set_vertex_setup(const VertexSetup *s)
56 {
57         set(vertex_setup, s, VERTEX_SETUP);
58 }
59
60 void PipelineState::set_front_face(FaceWinding w)
61 {
62         set(front_face, w, FACE_CULL);
63 }
64
65 void PipelineState::set_face_cull(CullMode c)
66 {
67         set(face_cull, c, FACE_CULL);
68 }
69
70 void PipelineState::set_enabled_clip_planes(unsigned p)
71 {
72         set(enabled_clip_planes, p, CLIP_PLANES);
73 }
74
75 void PipelineState::set_texture(unsigned binding, const Texture *tex, const Sampler *samp)
76 {
77         if((tex!=0)!=(samp!=0))
78                 throw invalid_argument("PipelineState::set_texture");
79
80         auto i = lower_bound_member(textures, binding, &BoundTexture::binding);
81         if(i==textures.end() || i->binding!=binding)
82                 i = textures.insert(i, BoundTexture(binding));
83         if(tex!=i->texture || samp!=i->sampler)
84         {
85                 i->texture = tex;
86                 i->sampler = samp;
87                 i->changed = true;
88                 changes |= TEXTURES;
89         }
90 }
91
92 void PipelineState::set_uniform_block(int binding, const UniformBlock *block)
93 {
94         auto i = lower_bound_member(uniform_blocks, binding, &BoundUniformBlock::binding);
95         if(i==uniform_blocks.end() || i->binding!=binding)
96                 i = uniform_blocks.insert(i, BoundUniformBlock(binding));
97         if(block!=i->block || binding<0)
98         {
99                 i->block = block;
100                 i->changed = true;
101                 changes |= UNIFORMS;
102         }
103 }
104
105 void PipelineState::set_depth_test(const DepthTest *dt)
106 {
107         set(depth_test, dt, DEPTH_TEST);
108 }
109
110 void PipelineState::set_stencil_test(const StencilTest *st)
111 {
112         set(stencil_test, st, STENCIL_TEST);
113 }
114
115 void PipelineState::set_blend(const Blend *b)
116 {
117         set(blend, b, BLEND);
118 }
119
120
121 PipelineState::BoundTexture::BoundTexture(unsigned b):
122         binding(b),
123         changed(false),
124         texture(0),
125         sampler(0)
126 { }
127
128
129 PipelineState::BoundUniformBlock::BoundUniformBlock(int b):
130         binding(b),
131         changed(false),
132         block(0)
133 { }
134
135 } // namespace GL
136 } // namespace Msp