]> git.tdb.fi Git - libs/gl.git/blob - source/core/frameformat.cpp
Use standard fixed-size integer types
[libs/gl.git] / source / core / frameformat.cpp
1 #include "deviceinfo.h"
2 #include "error.h"
3 #include "frameformat.h"
4
5 using namespace std;
6
7 namespace Msp {
8 namespace GL {
9
10 FrameFormat::FrameFormat():
11         count(0),
12         samples(1)
13 { }
14
15 FrameFormat::FrameFormat(FrameAttachment fa):
16         count(1),
17         samples(1)
18 {
19         attachments[0] = fa;
20 }
21
22 FrameFormat FrameFormat::operator,(FrameAttachment fa) const
23 {
24         if(count>=MAX_ATTACHMENTS)
25                 throw invalid_operation("FrameFormat::operator,");
26
27         FrameFormat result = *this;
28         result.attachments[result.count++] = fa;
29
30         return result;
31 }
32
33 FrameFormat FrameFormat::operator,(PixelFormat pf) const
34 {
35         if(!count)
36                 throw invalid_operation("FrameFormat::operator,");
37
38         FrameFormat r = *this;
39         uint16_t &fa = r.attachments[r.count-1];
40         fa = make_typed_attachment(static_cast<FrameAttachment>(fa), pf);
41
42         return r;
43 }
44
45 FrameFormat FrameFormat::operator,(unsigned index) const
46 {
47         if(!count)
48                 throw invalid_operation("FrameFormat::operator,");
49
50         FrameFormat r = *this;
51         uint16_t &fa = r.attachments[r.count-1];
52         fa = make_indexed_attachment(static_cast<FrameAttachment>(fa), index);
53
54         return r;
55 }
56
57 FrameFormat &FrameFormat::set_samples(unsigned s)
58 {
59         samples = s;
60         return *this;
61 }
62
63 int FrameFormat::index(FrameAttachment fa) const
64 {
65         for(unsigned i=0; i<count; ++i)
66                 if(get_attach_point(attachments[i])==get_attach_point(fa))
67                         return i;
68         return -1;
69 }
70
71
72 FrameAttachment make_typed_attachment(FrameAttachment fa, PixelFormat pf)
73 {
74         PixelComponents comp = get_components(pf);
75         if(get_attach_point(fa)==get_attach_point(DEPTH_ATTACHMENT))
76         {
77                 if(comp!=DEPTH_COMPONENT)
78                         throw invalid_argument("make_typed_attachment");
79         }
80         else if(get_attach_point(fa)==get_attach_point(STENCIL_ATTACHMENT))
81         {
82                 if(comp!=STENCIL_INDEX)
83                         throw invalid_argument("make_typed_attachment");
84         }
85         else
86         {
87                 if(comp!=RED && comp!=RG && comp!=RGB && comp!=RGBA)
88                         throw invalid_argument("make_typed_attachment");
89         }
90
91         DataType type = get_component_type(pf);
92         return static_cast<FrameAttachment>((fa&0xFC00) | (is_float(type)*0x100) | get_type_size(type)<<4 | get_component_count(comp));
93 }
94
95 FrameAttachment make_indexed_attachment(FrameAttachment fa, unsigned i)
96 {
97         if(get_attach_point(fa)==get_attach_point(COLOR_ATTACHMENT))
98         {
99                 if(i>61)
100                         throw out_of_range("make_indexed_attachment");
101                 return static_cast<FrameAttachment>(fa+(i<<10));
102         }
103         else
104                 throw invalid_argument("make_indexed_attachment");
105 }
106
107 PixelFormat get_attachment_pixelformat(uint16_t fa)
108 {
109         PixelComponents comp;
110         if(get_attach_point(fa)==get_attach_point(DEPTH_ATTACHMENT))
111                 comp = DEPTH_COMPONENT;
112         else if(get_attach_point(fa)==get_attach_point(STENCIL_ATTACHMENT))
113                 comp = STENCIL_INDEX;
114         else
115                 comp = static_cast<PixelComponents>(fa&7);
116
117         DataType type;
118         if(fa&0x100)
119                 type = static_cast<DataType>((fa&0x70)>>4 | 0x300);
120         else
121                 type = static_cast<DataType>((fa&0x70)>>4);
122
123         return make_pixelformat(comp, type);
124 }
125
126 GLenum get_gl_attachment(FrameAttachment fa)
127 {
128         if(get_attach_point(fa)==get_attach_point(DEPTH_ATTACHMENT))
129                 return GL_DEPTH_ATTACHMENT;
130         else if(get_attach_point(fa)==get_attach_point(STENCIL_ATTACHMENT))
131                 return GL_STENCIL_ATTACHMENT;
132         else
133                 return GL_COLOR_ATTACHMENT0+get_attach_point(fa);
134 }
135
136 } // namespace GL
137 } // namespace Msp