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