1 /*
2  Copyright (C) 2010-2014 Kristian Duske
3 
4  This file is part of TrenchBroom.
5 
6  TrenchBroom is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  TrenchBroom is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with TrenchBroom. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef TrenchBroom_AttributeSpec_h
21 #define TrenchBroom_AttributeSpec_h
22 
23 namespace TrenchBroom {
24     namespace Renderer {
25         typedef enum {
26             AttributeType_User,
27             AttributeType_Position,
28             AttributeType_Normal,
29             AttributeType_Color,
30             AttributeType_TexCoord0,
31             AttributeType_TexCoord1,
32             AttributeType_TexCoord2,
33             AttributeType_TexCoord3
34         } AttributeType;
35 
36         template <AttributeType type, GLenum D, size_t S>
37         class AttributeSpec {
38         public:
39             typedef typename GLType<D>::Type DataType;
40             typedef Vec<DataType, S> ElementType;
41             static const size_t Size = sizeof(DataType) * S;
42 
setup(const size_t index,const size_t stride,const size_t offset)43             static void setup(const size_t index, const size_t stride, const size_t offset) {}
cleanup(const size_t index)44             static void cleanup(const size_t index) {}
45         };
46 
47         template <GLenum D, size_t S>
48         class AttributeSpec<AttributeType_User, D, S> {
49         public:
50             typedef typename GLType<D>::Type DataType;
51             typedef Vec<DataType, S> ElementType;
52             static const size_t Size = sizeof(DataType) * S;
53 
setup(const size_t index,const size_t stride,const size_t offset)54             static void setup(const size_t index, const size_t stride, const size_t offset) {
55                 glAssert(glEnableVertexAttribArray(static_cast<GLuint>(index)));
56                 glAssert(glVertexAttribPointer(static_cast<GLuint>(index), S, D, true, static_cast<GLsizei>(stride), reinterpret_cast<GLvoid*>(offset)));
57             }
58 
cleanup(const size_t index)59             static void cleanup(const size_t index) {
60                 glAssert(glDisableVertexAttribArray(static_cast<GLuint>(index)));
61             }
62         };
63 
64         template <GLenum D, size_t S>
65         class AttributeSpec<AttributeType_Position, D, S> {
66         public:
67             typedef typename GLType<D>::Type DataType;
68             typedef Vec<DataType, S> ElementType;
69             static const size_t Size = sizeof(DataType) * S;
70 
setup(const size_t index,const size_t stride,const size_t offset)71             static void setup(const size_t index, const size_t stride, const size_t offset) {
72                 glAssert(glEnableClientState(GL_VERTEX_ARRAY));
73                 glAssert(glVertexPointer(S, D, static_cast<GLsizei>(stride), reinterpret_cast<GLvoid*>(offset)));
74             }
75 
cleanup(const size_t index)76             static void cleanup(const size_t index) {
77                 glAssert(glDisableClientState(GL_VERTEX_ARRAY));
78             }
79         };
80 
81         template <GLenum D, const size_t S>
82         class AttributeSpec<AttributeType_Normal, D, S> {
83         public:
84             typedef typename GLType<D>::Type DataType;
85             typedef Vec<DataType, S> ElementType;
86             static const size_t Size = sizeof(DataType) * S;
87 
setup(const size_t index,const size_t stride,const size_t offset)88             static void setup(const size_t index, const size_t stride, const size_t offset) {
89                 assert(S == 3);
90                 glAssert(glEnableClientState(GL_NORMAL_ARRAY));
91                 glAssert(glNormalPointer(D, static_cast<GLsizei>(stride), reinterpret_cast<GLvoid*>(offset)));
92             }
93 
cleanup(const size_t index)94             static void cleanup(const size_t index) {
95                 glAssert(glDisableClientState(GL_NORMAL_ARRAY));
96             }
97         };
98 
99         template <GLenum D, size_t S>
100         class AttributeSpec<AttributeType_Color, D, S> {
101         public:
102             typedef typename GLType<D>::Type DataType;
103             typedef Vec<DataType, S> ElementType;
104             static const size_t Size = sizeof(DataType) * S;
105 
setup(const size_t index,const size_t stride,const size_t offset)106             static void setup(const size_t index, const size_t stride, const size_t offset) {
107                 glAssert(glEnableClientState(GL_COLOR_ARRAY));
108                 glAssert(glColorPointer(S, D, static_cast<GLsizei>(stride), reinterpret_cast<GLvoid*>(offset)));
109             }
110 
cleanup(const size_t index)111             static void cleanup(const size_t index) {
112                 glAssert(glDisableClientState(GL_COLOR_ARRAY));
113             }
114         };
115 
116         template <GLenum D, size_t S>
117         class AttributeSpec<AttributeType_TexCoord0, D, S> {
118         public:
119             typedef typename GLType<D>::Type DataType;
120             typedef Vec<DataType, S> ElementType;
121             static const size_t Size = sizeof(DataType) * S;
122 
setup(const size_t index,const size_t stride,const size_t offset)123             static void setup(const size_t index, const size_t stride, const size_t offset) {
124                 glAssert(glClientActiveTexture(GL_TEXTURE0));
125                 glAssert(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
126                 glAssert(glTexCoordPointer(S, D, static_cast<GLsizei>(stride), reinterpret_cast<GLvoid*>(offset)));
127             }
128 
cleanup(const size_t index)129             static void cleanup(const size_t index) {
130                 glAssert(glClientActiveTexture(GL_TEXTURE0));
131                 glAssert(glDisableClientState(GL_TEXTURE_COORD_ARRAY));
132             }
133         };
134 
135         template <GLenum D, size_t S>
136         class AttributeSpec<AttributeType_TexCoord1, D, S> {
137         public:
138             typedef typename GLType<D>::Type DataType;
139             typedef Vec<DataType, S> ElementType;
140             static const size_t Size = sizeof(DataType) * S;
141 
setup(const size_t index,const size_t stride,const size_t offset)142             static void setup(const size_t index, const size_t stride, const size_t offset) {
143                 glAssert(glClientActiveTexture(GL_TEXTURE1));
144                 glAssert(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
145                 glAssert(glTexCoordPointer(S, D, static_cast<GLsizei>(stride), reinterpret_cast<GLvoid*>(offset)));
146             }
147 
cleanup(const size_t index)148             static void cleanup(const size_t index) {
149                 glAssert(glClientActiveTexture(GL_TEXTURE1));
150                 glAssert(glDisableClientState(GL_TEXTURE_COORD_ARRAY));
151                 glAssert(glClientActiveTexture(GL_TEXTURE0));
152             }
153         };
154 
155         template <GLenum D, size_t S>
156         class AttributeSpec<AttributeType_TexCoord2, D, S> {
157         public:
158             typedef typename GLType<D>::Type DataType;
159             typedef Vec<DataType, S> ElementType;
160             static const size_t Size = sizeof(DataType) * S;
161 
setup(const size_t index,const size_t stride,const size_t offset)162             static void setup(const size_t index, const size_t stride, const size_t offset) {
163                 glAssert(glClientActiveTexture(GL_TEXTURE2));
164                 glAssert(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
165                 glAssert(glTexCoordPointer(S, D, static_cast<GLsizei>(stride), reinterpret_cast<GLvoid*>(offset)));
166             }
167 
cleanup(const size_t index)168             static void cleanup(const size_t index) {
169                 glAssert(glClientActiveTexture(GL_TEXTURE2));
170                 glAssert(glDisableClientState(GL_TEXTURE_COORD_ARRAY));
171                 glAssert(glClientActiveTexture(GL_TEXTURE0));
172             }
173         };
174 
175         template <GLenum D, size_t S>
176         class AttributeSpec<AttributeType_TexCoord3, D, S> {
177         public:
178             typedef typename GLType<D>::Type DataType;
179             typedef Vec<DataType, S> ElementType;
180             static const size_t Size = sizeof(DataType) * S;
181 
setup(const size_t index,const size_t stride,const size_t offset)182             static void setup(const size_t index, const size_t stride, const size_t offset) {
183                 glAssert(glClientActiveTexture(GL_TEXTURE3));
184                 glAssert(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
185                 glAssert(glTexCoordPointer(S, D, static_cast<GLsizei>(stride), reinterpret_cast<GLvoid*>(offset)));
186             }
187 
cleanup(const size_t index)188             static void cleanup(const size_t index) {
189                 glAssert(glClientActiveTexture(GL_TEXTURE3));
190                 glAssert(glDisableClientState(GL_TEXTURE_COORD_ARRAY));
191                 glAssert(glClientActiveTexture(GL_TEXTURE0));
192             }
193         };
194 
195         namespace AttributeSpecs {
196             typedef AttributeSpec<AttributeType_Position, GL_FLOAT, 2> P2;
197             typedef AttributeSpec<AttributeType_Position, GL_FLOAT, 3> P3;
198             typedef AttributeSpec<AttributeType_Normal, GL_FLOAT, 3> N;
199             typedef AttributeSpec<AttributeType_TexCoord0, GL_FLOAT, 2> T02;
200             typedef AttributeSpec<AttributeType_TexCoord1, GL_FLOAT, 2> T12;
201             typedef AttributeSpec<AttributeType_Color, GL_FLOAT, 4> C4;
202         }
203     }
204 }
205 
206 #endif
207