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