1 /*
2 * GLClientAndServerBuffer.cpp
3 * FreeOrion
4 *
5 * Created by Rainer Kupke on 06.02.11.
6 * Copyright 2011. All rights reserved.
7 *
8 */
9
10 #include <GG/GLClientAndServerBuffer.h>
11
12 namespace GG {
13
14 ///////////////////////////////////////////////////////////////////////////
15 // GLBufferBase
16 ///////////////////////////////////////////////////////////////////////////
GLBufferBase()17 GLBufferBase::GLBufferBase() :
18 b_name(0)
19 {}
20
~GLBufferBase()21 GLBufferBase::~GLBufferBase()
22 { dropServerBuffer(); }
23
dropServerBuffer()24 void GLBufferBase::dropServerBuffer()
25 {
26 if (b_name) {
27 glDeleteBuffers(1, &b_name);
28 b_name = 0;
29 }
30 }
31
harmonizeBufferType(GLBufferBase & other)32 void GLBufferBase::harmonizeBufferType(GLBufferBase& other)
33 {
34 if (b_name && other.b_name) return; // OK, both have server buffer
35
36 if (b_name || other.b_name) { // NOT OK, only one has server buffer, drop buffer
37 dropServerBuffer();
38 other.dropServerBuffer();
39 }
40 }
41
42 ///////////////////////////////////////////////////////////////////////////
43 // GLClientAndServerBufferBase<vtype> template
44 ///////////////////////////////////////////////////////////////////////////
45 template <typename vtype>
GLClientAndServerBufferBase(std::size_t elementsPerItem)46 GLClientAndServerBufferBase<vtype>::GLClientAndServerBufferBase(std::size_t elementsPerItem) :
47 GLBufferBase(),
48 b_data(),
49 b_size(0),
50 b_elements_per_item(elementsPerItem)
51 {}
52
53 template <typename vtype>
size() const54 std::size_t GLClientAndServerBufferBase<vtype>::size() const
55 { return b_size; }
56
57 template <typename vtype>
empty() const58 bool GLClientAndServerBufferBase<vtype>::empty() const
59 { return b_size == 0; }
60
61 template <typename vtype>
reserve(std::size_t num_items)62 void GLClientAndServerBufferBase<vtype>::reserve(std::size_t num_items)
63 { b_data.reserve(num_items * b_elements_per_item); }
64
65 template <typename vtype>
store(vtype item)66 void GLClientAndServerBufferBase<vtype>::store(vtype item)
67 {
68 b_data.push_back(item);
69 b_size=b_data.size() / b_elements_per_item;
70 }
71
72 template <typename vtype>
store(vtype item1,vtype item2)73 void GLClientAndServerBufferBase<vtype>::store(vtype item1, vtype item2)
74 {
75 b_data.push_back(item1);
76 b_data.push_back(item2);
77 b_size=b_data.size() / b_elements_per_item;
78 }
79
80 template <typename vtype>
store(vtype item1,vtype item2,vtype item3)81 void GLClientAndServerBufferBase<vtype>::store(vtype item1, vtype item2, vtype item3)
82 {
83 b_data.push_back(item1);
84 b_data.push_back(item2);
85 b_data.push_back(item3);
86 b_size=b_data.size() / b_elements_per_item;
87 }
88
89 template <typename vtype>
store(vtype item1,vtype item2,vtype item3,vtype item4)90 void GLClientAndServerBufferBase<vtype>::store(vtype item1, vtype item2, vtype item3, vtype item4)
91 {
92 b_data.push_back(item1);
93 b_data.push_back(item2);
94 b_data.push_back(item3);
95 b_data.push_back(item4);
96 b_size=b_data.size() / b_elements_per_item;
97 }
98
99 template <typename vtype>
createServerBuffer()100 void GLClientAndServerBufferBase<vtype>::createServerBuffer()
101 {
102 glGenBuffers(1, &b_name);
103 if (!b_name)
104 return;
105 glBindBuffer(GL_ARRAY_BUFFER, b_name);
106 glBufferData(GL_ARRAY_BUFFER,
107 b_data.size() * sizeof(vtype),
108 b_data.empty() ? nullptr : &b_data[0],
109 GL_STATIC_DRAW);
110 glBindBuffer(GL_ARRAY_BUFFER, 0);
111 }
112
113 template <typename vtype>
clear()114 void GLClientAndServerBufferBase<vtype>::clear()
115 {
116 dropServerBuffer();
117 b_size = 0;
118 b_data.clear();
119 }
120
121 ///////////////////////////////////////////////////////////////////////////
122 // GLRGBAColorBuffer
123 ///////////////////////////////////////////////////////////////////////////
124 template class GLClientAndServerBufferBase<unsigned char>;
125
GLRGBAColorBuffer()126 GLRGBAColorBuffer::GLRGBAColorBuffer() :
127 GLClientAndServerBufferBase<unsigned char>(4)
128 {}
129
store(const Clr & color)130 void GLRGBAColorBuffer::store(const Clr& color)
131 { GLClientAndServerBufferBase::store(color.r, color.g, color.b, color.a); }
132
activate() const133 void GLRGBAColorBuffer::activate() const
134 {
135 if (b_name) {
136 glBindBuffer(GL_ARRAY_BUFFER, b_name);
137 glColorPointer(4, GL_UNSIGNED_BYTE, 0, nullptr);
138 glBindBuffer(GL_ARRAY_BUFFER, 0);
139 } else {
140 glColorPointer(4, GL_UNSIGNED_BYTE, 0, b_data.empty() ? nullptr: &b_data[0]);
141 }
142 }
143
144 ///////////////////////////////////////////////////////////////////////////
145 // GL2DVertexBuffer
146 ///////////////////////////////////////////////////////////////////////////
147 template class GLClientAndServerBufferBase<float>;
148
GL2DVertexBuffer()149 GL2DVertexBuffer::GL2DVertexBuffer() :
150 GLClientAndServerBufferBase<float>(2)
151 {}
152
store(const Pt & pt)153 void GL2DVertexBuffer::store(const Pt& pt)
154 { store(pt.x, pt.y); }
155
store(X x,Y y)156 void GL2DVertexBuffer::store(X x, Y y)
157 { GLClientAndServerBufferBase::store(Value(x), Value(y)); }
158
store(X x,float y)159 void GL2DVertexBuffer::store(X x, float y)
160 { GLClientAndServerBufferBase::store(Value(x), y); }
161
store(float x,Y y)162 void GL2DVertexBuffer::store(float x, Y y)
163 { GLClientAndServerBufferBase::store(x, Value(y)); }
164
store(float x,float y)165 void GL2DVertexBuffer::store(float x, float y)
166 { GLClientAndServerBufferBase::store(x, y); }
167
activate() const168 void GL2DVertexBuffer::activate() const
169 {
170 if (b_name) {
171 glBindBuffer(GL_ARRAY_BUFFER, b_name);
172 glVertexPointer(2, GL_FLOAT, 0, nullptr);
173 glBindBuffer(GL_ARRAY_BUFFER, 0);
174 } else {
175 glVertexPointer(2, GL_FLOAT, 0, b_data.empty() ? nullptr: &b_data[0]);
176 }
177 }
178
179
180 ///////////////////////////////////////////////////////////////////////////
181 // GLTexCoordBuffer
182 ///////////////////////////////////////////////////////////////////////////
GLTexCoordBuffer()183 GLTexCoordBuffer::GLTexCoordBuffer() :
184 GLClientAndServerBufferBase<float>(2)
185 {}
186
activate() const187 void GLTexCoordBuffer::activate() const
188 {
189 if (b_name) {
190 glBindBuffer(GL_ARRAY_BUFFER, b_name);
191 glTexCoordPointer(2, GL_FLOAT, 0, nullptr);
192 glBindBuffer(GL_ARRAY_BUFFER, 0);
193 } else {
194 glTexCoordPointer(2, GL_FLOAT, 0, b_data.empty() ? nullptr: &b_data[0]);
195 }
196 }
197
198
199 ///////////////////////////////////////////////////////////////////////////
200 // GL3DVertexBuffer
201 ///////////////////////////////////////////////////////////////////////////
GL3DVertexBuffer()202 GL3DVertexBuffer::GL3DVertexBuffer() :
203 GLClientAndServerBufferBase<float>(3)
204 {}
205
store(float x,float y,float z)206 void GL3DVertexBuffer::store(float x, float y, float z)
207 { GLClientAndServerBufferBase::store(x, y, z); }
208
activate() const209 void GL3DVertexBuffer::activate() const
210 {
211 if (b_name) {
212 glBindBuffer(GL_ARRAY_BUFFER, b_name);
213 glVertexPointer(3, GL_FLOAT, 0, nullptr);
214 glBindBuffer(GL_ARRAY_BUFFER, 0);
215 } else {
216 glVertexPointer(3, GL_FLOAT, 0, b_data.empty() ? nullptr: &b_data[0]);
217 }
218 }
219
220
221 ///////////////////////////////////////////////////////////////////////////
222 // GLNormalBuffer
223 ///////////////////////////////////////////////////////////////////////////
GLNormalBuffer()224 GLNormalBuffer::GLNormalBuffer() :
225 GLClientAndServerBufferBase<float>(3)
226 {}
227
activate() const228 void GLNormalBuffer::activate() const
229 {
230 if (b_name) {
231 glBindBuffer(GL_ARRAY_BUFFER, b_name);
232 glNormalPointer(GL_FLOAT, 0, nullptr);
233 glBindBuffer(GL_ARRAY_BUFFER, 0);
234 } else {
235 glNormalPointer(GL_FLOAT, 0, b_data.empty() ? nullptr: &b_data[0]);
236 }
237 }
238
239 }
240