libosmscout 1.1.1
Loading...
Searching...
No Matches
OpenGLMapData.h
Go to the documentation of this file.
1#ifndef LIBOSMSCOUT_OPENGLMAPDATA_H
2#define LIBOSMSCOUT_OPENGLMAPDATA_H
3
4/*
5 This source is part of the libosmscout-map library
6 Copyright (C) 2017 Fanny Monori
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21*/
22
25
28
29#include <osmscout/io/File.h>
30
31#include <iostream>
32#include <fstream>
33
34#include <GL/glew.h>
35#include <glm/glm.hpp>
36#include <glm/gtc/matrix_transform.hpp>
37#include <glm/gtc/type_ptr.hpp>
38#include <glm/ext.hpp>
39
40namespace osmscout {
41
43 public:
44 size_t width=0;
45 size_t height=0;
46 size_t size=0;
47 unsigned char *data=nullptr; // owned, have to be allocated by new []
48
49 size_t fromOriginY=0;
50
51 OpenGLTexture() = default;
52
53 OpenGLTexture(const OpenGLTexture&) = delete;
57
59 if (data!=nullptr) {
60 delete[] data;
61 data=nullptr;
62 }
63 }
64
65 };
66
67 typedef std::shared_ptr<OpenGLTexture> OpenGLTextureRef;
68
74 template <int TexturePixelType, unsigned int TexturePixelSize>
76 private:
77
78 std::vector<GLfloat> vertices;
79 std::vector<GLfloat> verticesBuffer;
80 std::vector<GLuint> elements;
81 std::vector<GLuint> elementsBuffer;
82 unsigned char *textures=nullptr;
83 std::vector<OpenGLTextureRef> texturesBuffer;
84 int textureSize=0;
85 int textureSizeBuffer=0;
86 int textureWidth=0;
87 int textureWidthBuffer=0;
88 int textureHeight=14;
89
90 GLuint shaderProgram=0;
91 GLuint vao=0;
92 GLuint vbo=0;
93 GLuint ebo=0;
94 GLuint tex=0;
95
96 int verticesSize;
97 float zoom;
98
99 GLuint vertexShader=0;
100 GLuint fragmentShader=0;
101
102 glm::mat4 model;
103 glm::mat4 view;
104 glm::mat4 projection;
105
106 void LoadVBO() {
107 glBindBuffer(GL_ARRAY_BUFFER, vbo);
108 glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * vertices.size(), &vertices[0], GL_DYNAMIC_DRAW);
109 }
110
111 void LoadEBO() {
112 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
113 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLfloat) * elements.size(), &elements[0], GL_DYNAMIC_DRAW);
114 }
115
116 public:
117 OpenGLMapData() = default;
118
120 {
121 clearData();
122
123 if (shaderProgram!=0) {
124 glDeleteProgram(shaderProgram);
125 }
126 if (fragmentShader!=0) {
127 glDeleteShader(fragmentShader);
128 }
129 if (vertexShader!=0) {
130 glDeleteShader(vertexShader);
131 }
132
133 if (ebo!=0) {
134 glDeleteBuffers(1, &ebo);
135 }
136 if (vbo!=0) {
137 glDeleteBuffers(1, &vbo);
138 }
139
140 if (vao!=0) {
141 glDeleteVertexArrays(1, &vao);
142 }
143 }
144
145 OpenGLMapData(const OpenGLMapData&) = delete;
149
150 void SwapData() {
151 delete[] textures;
152 vertices = std::move(verticesBuffer);
153 verticesBuffer.clear();
154 elements = std::move(elementsBuffer);
155 elementsBuffer.clear();
156
157 textureSize = textureSizeBuffer;
158 textureSizeBuffer = 0;
159 textureWidth = textureWidthBuffer;
160 textureWidthBuffer = 0;
161
162 textures = new unsigned char[textureWidth * textureHeight * TexturePixelSize];
163
164 int index = 0;
165 for (int i = 0; i < textureHeight; i++) {
166 for (unsigned int j = 0; j < texturesBuffer.size(); j++) {
167 int start = i * texturesBuffer[j]->width * TexturePixelSize;
168 for (unsigned int k = start; k < start + (texturesBuffer[j]->width * TexturePixelSize); k++) {
169 textures[index] = (texturesBuffer[j]->data[k]);
170 index++;
171 }
172 }
173 }
174
175 texturesBuffer.clear();
176 }
177
178 void clearData() {
179 vertices.clear();
180 elements.clear();
181 if (textures != nullptr) {
182 delete[] textures;
183 textures = nullptr;
184 }
185 texturesBuffer.clear();
186 textureSize = 0;
187 textureWidth = 0;
188 }
189
190 void BindBuffers() {
191 glBindVertexArray(vao);
192 }
193
194 bool InitContext(const std::string &shaderDir,
195 const std::string &vertexShaderFileName,
196 const std::string &fragmentShaderFileName,
197 GLuint projectionShader) {
198 glGenVertexArrays(1, &vao);
199 glBindVertexArray(vao);
200 glGenBuffers(1, &vbo);
201 glGenBuffers(1, &ebo);
202 glGenTextures(1, &tex);
203
204 zoom = 45.0f;
205 model = glm::mat4(1.0f);
206 textureSize = 0;
207 textureSizeBuffer = 0;
208 textureWidth = 0;
209 textureWidthBuffer = 0;
210 textureHeight = 0;
211
212 if (std::string vertexShaderSource;
213 !(LoadShaderSource(shaderDir, vertexShaderFileName, vertexShaderSource) &&
214 LoadShader(vertexShader, GL_VERTEX_SHADER, "vertex", vertexShaderSource))) {
215 return false;
216 }
217
218 if (std::string fragmentShaderSource;
219 !(LoadShaderSource(shaderDir, fragmentShaderFileName, fragmentShaderSource) &&
220 LoadShader(fragmentShader, GL_FRAGMENT_SHADER, "fragment", fragmentShaderSource))) {
221 return false;
222 }
223
224 glEnable(GL_PROGRAM_POINT_SIZE);
225
226 shaderProgram = glCreateProgram();
227 glAttachShader(shaderProgram, vertexShader);
228 glAttachShader(shaderProgram, fragmentShader);
229 glAttachShader(shaderProgram, projectionShader);
230 glBindFragDataLocation(shaderProgram, 0, "outColor");
231 glLinkProgram(shaderProgram);
232
233 GLint isLinked = 0;
234 glGetProgramiv(shaderProgram, GL_LINK_STATUS, &isLinked);
235 if (isLinked == GL_FALSE) {
236 GLint maxLength = 0;
237 glGetProgramiv(shaderProgram, GL_INFO_LOG_LENGTH, &maxLength);
238
239 std::vector<GLchar> errorLog(maxLength);
240 glGetProgramInfoLog(shaderProgram, maxLength, &maxLength, errorLog.data());
241 assert(!errorLog.empty() && errorLog.back() == 0);
242 log.Error() << "Error while linking shader program: " << errorLog.data();
243
244 return false;
245 }
246
247 // Always detach shaders after a successful link.
248 glDetachShader(shaderProgram, vertexShader);
249 glDetachShader(shaderProgram, fragmentShader);
250 glDetachShader(shaderProgram, projectionShader);
251
252 return true;
253 }
254
256 glActiveTexture(GL_TEXTURE0);
257 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
258 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
259 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
260 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
261 glPixelStorei(GL_UNPACK_ALIGNMENT, TexturePixelSize);
262 glBindTexture(GL_TEXTURE_2D, tex);
263 glTexImage2D(GL_TEXTURE_2D, 0, TexturePixelType, textureWidth, textureHeight, 0, TexturePixelType, GL_UNSIGNED_BYTE, textures);
264 }
265
267 LoadVBO();
268 LoadEBO();
269 }
270
271 void AddNewVertex(GLfloat vertex) {
272 this->verticesBuffer.push_back(vertex);
273 }
274
275 void AddNewElement(GLuint element) {
276 this->elementsBuffer.push_back(element);
277 }
278
280 return (this->verticesBuffer.size()) / (this->verticesSize);
281 }
282
283 void UseProgram() {
284 glUseProgram(shaderProgram);
285 }
286
287 void SetVerticesSize(int size) {
288 this->verticesSize = size;
289 }
290
292 return this->verticesBuffer.size();
293 }
294
295 /*void AddNewTexture(OpenGLTexture *texture) {
296 TexturesBuffer.push_back(texture);
297
298 textureWidthBuffer += texture->width;
299
300 textureSizeBuffer++;
301 }*/
302
304 texturesBuffer.push_back(texture);
305
306 textureWidthBuffer += texture->width;
307
308 textureSizeBuffer++;
309 }
310
311
313 return textureWidth;
314 }
315
317 return textureHeight;
318 }
319
320 int GetTextureWidth(int index){
321 return texturesBuffer[index]->width;
322 }
323
324 int GetTextureWidthSum(int index){
325 int sum = 0;
326 for(int i = 0; i < index+1; i++)
327 sum += texturesBuffer[i]->width;
328
329 return sum;
330 }
331
332 void SetTextureHeight(int textheight){
333 textureHeight = textheight;
334 }
335
336 void SetModel() {
337 GLuint uniform = glGetUniformLocation(shaderProgram, "Model");
338 glUniformMatrix4fv(uniform, 1, GL_FALSE, glm::value_ptr(model));
339 }
340
341 void SetView(float /*lookX*/, float /*lookY*/) {
342 view = glm::lookAt(
343 glm::vec3(0.0, 0.0, 1.0f), //position
344 glm::vec3(0.0f, 0.0f, 0.0f), //look
345 glm::vec3(0.0f, 1.0f, 0.0f) //up
346 );
347 GLint uniView = glGetUniformLocation(shaderProgram, "View");
348 glUniformMatrix4fv(uniView, 1, GL_FALSE, glm::value_ptr(view));
349 }
350
351 void SetProjection(float width, float height) {
352 projection = glm::perspective(glm::radians(60.0f), (float) width / (float) height, 0.1f, 10.0f);
353 GLint uniProj = glGetUniformLocation(shaderProgram, "Projection");
354 glUniformMatrix4fv(uniProj, 1, GL_FALSE, glm::value_ptr(projection));
355 }
356
357 void AddAttrib(std::string attribName, GLint length, GLuint type, size_t positionOffset) {
358 GLint attrib = glGetAttribLocation(shaderProgram, attribName.c_str());
359 glEnableVertexAttribArray(attrib);
360 glVertexAttribPointer(attrib, length, type, GL_FALSE, verticesSize * sizeof(GLfloat), (void *) positionOffset);
361 }
362
363 void AddUniform(const char *uniformName, float value) {
364 GLuint uniform = glGetUniformLocation(shaderProgram, uniformName);
365 glUniform1f(uniform, value);
366 }
367
368 void SetMapProjection(const OpenGLProjection &mapProjection)
369 {
370 mapProjection.SetShaderUniforms(shaderProgram);
371 }
372
373 GLuint getVAO() {
374 return this->vao;
375 }
376
377 GLuint GetTexture() {
378 return this->tex;
379 }
380
382 return this->shaderProgram;
383 }
384
385 const glm::mat4 &GetModel() const {
386 return model;
387 }
388
389 const glm::mat4 &GetView() const {
390 return view;
391 }
392
393 const glm::mat4 &GetProjection() const {
394 return projection;
395 }
396
397 void Draw() {
398 glDrawElements(GL_TRIANGLES, (GLsizei) elements.size(), GL_UNSIGNED_INT, 0);
399 }
400
401 };
402}
403
404#endif //LIBOSMSCOUT_OPENGLMAPDATA_H
void AddUniform(const char *uniformName, float value)
Definition OpenGLMapData.h:363
OpenGLMapData & operator=(OpenGLMapData &&)=delete
const glm::mat4 & GetView() const
Definition OpenGLMapData.h:389
void AddNewElement(GLuint element)
Definition OpenGLMapData.h:275
int GetTextureHeight()
Definition OpenGLMapData.h:316
const glm::mat4 & GetProjection() const
Definition OpenGLMapData.h:393
void SetTextureHeight(int textheight)
Definition OpenGLMapData.h:332
int GetTextureWidth(int index)
Definition OpenGLMapData.h:320
void SetMapProjection(const OpenGLProjection &mapProjection)
Definition OpenGLMapData.h:368
int GetTextureWidthSum(int index)
Definition OpenGLMapData.h:324
void SetVerticesSize(int size)
Definition OpenGLMapData.h:287
int GetNumOfVertices()
Definition OpenGLMapData.h:291
void UseProgram()
Definition OpenGLMapData.h:283
void clearData()
Definition OpenGLMapData.h:178
void LoadTextures()
Definition OpenGLMapData.h:255
GLuint getVAO()
Definition OpenGLMapData.h:373
void SetModel()
Definition OpenGLMapData.h:336
void BindBuffers()
Definition OpenGLMapData.h:190
OpenGLMapData(const OpenGLMapData &)=delete
OpenGLMapData(OpenGLMapData &&)=delete
void AddNewVertex(GLfloat vertex)
Definition OpenGLMapData.h:271
~OpenGLMapData()
Definition OpenGLMapData.h:119
int GetVerticesNumber()
Definition OpenGLMapData.h:279
OpenGLMapData & operator=(const OpenGLMapData &)=delete
void SwapData()
Definition OpenGLMapData.h:150
int GetTextureWidth()
Definition OpenGLMapData.h:312
bool InitContext(const std::string &shaderDir, const std::string &vertexShaderFileName, const std::string &fragmentShaderFileName, GLuint projectionShader)
Definition OpenGLMapData.h:194
GLuint getShaderProgram()
Definition OpenGLMapData.h:381
const glm::mat4 & GetModel() const
Definition OpenGLMapData.h:385
void AddNewTexture(OpenGLTextureRef texture)
Definition OpenGLMapData.h:303
GLuint GetTexture()
Definition OpenGLMapData.h:377
void SetView(float, float)
Definition OpenGLMapData.h:341
void Draw()
Definition OpenGLMapData.h:397
void AddAttrib(std::string attribName, GLint length, GLuint type, size_t positionOffset)
Definition OpenGLMapData.h:357
void SetProjection(float width, float height)
Definition OpenGLMapData.h:351
void LoadVertices()
Definition OpenGLMapData.h:266
Definition OpenGLProjection.h:33
void SetShaderUniforms(GLuint shaderProgram) const
Definition OpenGLProjection.h:47
OpenGLTexture & operator=(OpenGLTexture &&)=delete
OpenGLTexture(OpenGLTexture &&)=delete
size_t fromOriginY
Definition OpenGLMapData.h:49
size_t width
Definition OpenGLMapData.h:44
size_t size
Definition OpenGLMapData.h:46
OpenGLTexture(const OpenGLTexture &)=delete
~OpenGLTexture()
Definition OpenGLMapData.h:58
OpenGLTexture & operator=(const OpenGLTexture &)=delete
size_t height
Definition OpenGLMapData.h:45
unsigned char * data
Definition OpenGLMapData.h:47
OSMSCOUT_API Log log
Definition LoggerImpl.h:95
Definition Area.h:39
bool OSMSCOUT_MAP_OPENGL_API LoadShader(GLuint &shader, GLenum type, const std::string &name, const std::string &shaderSource)
std::shared_ptr< OpenGLTexture > OpenGLTextureRef
Definition OpenGLMapData.h:67
bool OSMSCOUT_MAP_OPENGL_API LoadShaderSource(const std::string &dirPath, const std::string &name, std::string &result)