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