libosmscout  1.1.1
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 
23 
24 #include <GL/glew.h>
25 #include <glm/glm.hpp>
26 #include <glm/gtc/matrix_transform.hpp>
27 #include <glm/gtc/type_ptr.hpp>
28 #include <glm/ext.hpp>
29 #include <osmscout/MapParameter.h>
30 #include <osmscout/MapPainter.h>
31 #include <iostream>
32 #include <fstream>
33 
34 namespace osmscout {
35 
36  class OpenGLTexture {
37  public:
38  size_t width;
39  size_t height;
40  size_t size;
41  unsigned char *data;
42 
43  size_t fromOriginY;
44 
46  delete []data;
47  }
48 
49  };
50 
51  typedef std::shared_ptr<OpenGLTexture> OpenGLTextureRef;
52 
53  class OpenGLMapData {
54  private:
55 
56  std::vector<GLfloat> Vertices;
57  std::vector<GLfloat> VerticesBuffer;
58  std::vector<GLuint> Elements;
59  std::vector<GLuint> ElementsBuffer;
60  unsigned char *Textures;
61  std::vector<OpenGLTextureRef> TexturesBuffer;
62  int textureSize;
63  int textureSizeBuffer;
64  int textureWidth;
65  int textureWidthBuffer;
66  int textureHeight;
67 
68  GLuint shaderProgram;
69  GLuint VAO;
70  GLuint VBO;
71  GLuint EBO;
72  GLuint Tex;
73 
74  int VerticesSize;
75  float zoom;
76 
77  GLuint VertexShader;
78  GLuint FragmentShader;
79 
80  std::string VertexShaderSource;
81  std::string FragmentShaderSource;
82  int VertexShaderLength;
83  int FragmentShaderLength;
84 
85  glm::mat4 Model;
86  glm::mat4 View;
87  glm::mat4 Projection;
88 
89  std::string LoadShader(std::string name) {
90  std::string result;
91  std::string line;
92  std::string filePath = std::string(__FILE__);
93 
94 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__)
95  std::string dirPath = filePath.substr(0, filePath.rfind("\\"));
96 #else
97  std::string dirPath = filePath.substr(0, filePath.rfind("/"));
98 #endif
99 
100  std::ifstream myfile(dirPath + "/private/" + name);
101  if (myfile.is_open()) {
102  while (getline(myfile, line)) {
103  result.append(line + "\n");
104  }
105  myfile.close();
106  }
107 
108  return result;
109 
110  }
111 
112  void LoadVBO() {
113  glBindBuffer(GL_ARRAY_BUFFER, VBO);
114  glBufferData(GL_ARRAY_BUFFER, sizeof(std::vector<GLfloat>) + (sizeof(GLfloat) * Vertices.size()), &Vertices[0],
115  GL_DYNAMIC_DRAW);
116  }
117 
118  void LoadEBO() {
119  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
120  glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(std::vector<GLfloat>) + (sizeof(GLfloat) * Elements.size()),
121  &Elements[0], GL_DYNAMIC_DRAW);
122  }
123 
124  public:
125 
126  void SwapData() {
127  delete[] Textures;
128  this->Vertices.clear();
129  this->Vertices = this->VerticesBuffer;
130  this->VerticesBuffer.clear();
131  this->Elements.clear();
132  this->Elements = this->ElementsBuffer;
133  this->ElementsBuffer.clear();
134 
135  textureSize = textureSizeBuffer;
136  textureSizeBuffer = 0;
137  textureWidth = textureWidthBuffer;
138  textureWidthBuffer = 0;
139 
140  textureHeight = 14;
141 
142  this->Textures = new unsigned char[textureWidth*textureHeight*4];
143 
144  int index = 0;
145  for (int i = 0; i < textureHeight; i++) {
146  for (unsigned int j = 0; j < TexturesBuffer.size(); j++) {
147  int start = i * TexturesBuffer[j]->width * 4;
148  for (unsigned int k = start; k < start + (TexturesBuffer[j]->width * 4); k++) {
149  Textures[index] = (TexturesBuffer[j]->data[k]);
150  index++;
151  }
152  }
153  }
154 
155  TexturesBuffer.clear();
156  }
157 
158  void SwapData(int stride) {
159  delete[] Textures;
160  this->Vertices.clear();
161  this->Vertices = this->VerticesBuffer;
162  this->VerticesBuffer.clear();
163  this->Elements.clear();
164  this->Elements = this->ElementsBuffer;
165  this->ElementsBuffer.clear();
166 
167  textureSize = textureSizeBuffer;
168  textureSizeBuffer = 0;
169  textureWidth = textureWidthBuffer;
170  textureWidthBuffer = 0;
171 
172  this->Textures = new unsigned char[textureWidth*textureHeight*stride];
173 
174  int index = 0;
175  for (int i = 0; i < textureHeight; i++) {
176  for (unsigned int j = 0; j < TexturesBuffer.size(); j++) {
177  int start = i * TexturesBuffer[j]->width * stride;
178  for (unsigned int k = start; k < start + (TexturesBuffer[j]->width * stride); k++) {
179  Textures[index] = (TexturesBuffer[j]->data[k]);
180  index++;
181  }
182  }
183  }
184 
185  TexturesBuffer.clear();
186  }
187 
188  void clearData() {
189  Vertices.clear();
190  Elements.clear();
191  Textures = nullptr;
192  TexturesBuffer.clear();
193  textureSize = 0;
194  textureWidth = 0;
195  }
196 
197  void BindBuffers() {
198  glBindVertexArray(VAO);
199  }
200 
201  bool InitContext() {
202  glGenVertexArrays(1, &VAO);
203  glBindVertexArray(VAO);
204  glGenBuffers(1, &VBO);
205  glGenBuffers(1, &EBO);
206  glGenTextures(1, &Tex);
207 
208  zoom = 45.0f;
209  Model = glm::mat4(1.0f);
210  textureSize = 0;
211  textureSizeBuffer = 0;
212  textureWidth = 0;
213  textureWidthBuffer = 0;
214  textureHeight = 0;
215 
216  VertexShader = glCreateShader(GL_VERTEX_SHADER);
217  const char *VertexSourceC = VertexShaderSource.c_str();
218  glShaderSource(VertexShader, 1, &VertexSourceC, &VertexShaderLength);
219  glCompileShader(VertexShader);
220 
221  GLint isCompiled = 0;
222  glGetShaderiv(VertexShader, GL_COMPILE_STATUS, &isCompiled);
223  if (isCompiled == GL_FALSE) {
224  GLint maxLength = 0;
225  glGetShaderiv(VertexShader, GL_INFO_LOG_LENGTH, &maxLength);
226 
227  std::vector<GLchar> errorLog(maxLength);
228  glGetShaderInfoLog(VertexShader, maxLength, &maxLength, &errorLog[0]);
229 
230  for (glm::uint i = 0; i < errorLog.size(); i++)
231  std::cout << errorLog.at(i);
232 
233  std::cout << std::endl;
234 
235  return false;
236  }
237 
238  FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
239  const char *FragmentSourceC = FragmentShaderSource.c_str();
240  glShaderSource(FragmentShader, 1, &FragmentSourceC, &FragmentShaderLength);
241  glCompileShader(FragmentShader);
242 
243  isCompiled = 0;
244  glGetShaderiv(FragmentShader, GL_COMPILE_STATUS, &isCompiled);
245  if (isCompiled == GL_FALSE) {
246  GLint maxLength = 0;
247  glGetShaderiv(FragmentShader, GL_INFO_LOG_LENGTH, &maxLength);
248 
249  std::vector<GLchar> errorLog(maxLength);
250  glGetShaderInfoLog(FragmentShader, maxLength, &maxLength, &errorLog[0]);
251 
252  for (glm::uint i = 0; i < errorLog.size(); i++)
253  std::cout << errorLog.at(i);
254 
255  std::cout << std::endl;
256 
257  return false;
258  }
259 
260  glEnable(GL_PROGRAM_POINT_SIZE);
261 
262  return true;
263 
264  }
265 
266  void LoadTextures() {
267  glActiveTexture(GL_TEXTURE0);
268  glBindTexture(GL_TEXTURE_2D, Tex);
269  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, Textures);
270  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
271  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
272  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
273  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
274  }
275 
277  glActiveTexture(GL_TEXTURE0);
278  glBindTexture(GL_TEXTURE_2D, Tex);
279  glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, textureWidth, textureHeight, 0, GL_RED, GL_UNSIGNED_BYTE, Textures);
280  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
281  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
282  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
283  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
284  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
285  }
286 
287  void LoadFragmentShader(std::string fileName) {
288  FragmentShaderSource = this->LoadShader(fileName);
289  FragmentShaderLength = FragmentShaderSource.length();
290  }
291 
292  void LoadVertexShader(std::string fileName) {
293  VertexShaderSource = this->LoadShader(fileName);
294  VertexShaderLength = VertexShaderSource.length();
295  }
296 
297  void LoadVertices() {
298  LoadVBO();
299  LoadEBO();
300  }
301 
302  void AddNewVertex(GLfloat vertex) {
303  this->VerticesBuffer.push_back(vertex);
304  }
305 
306  void AddNewElement(GLuint element) {
307  this->ElementsBuffer.push_back(element);
308  }
309 
311  return (this->VerticesBuffer.size()) / (this->VerticesSize);
312  }
313 
314  void LoadProgram() {
315  shaderProgram = glCreateProgram();
316  glAttachShader(shaderProgram, VertexShader);
317  glAttachShader(shaderProgram, FragmentShader);
318  glBindFragDataLocation(shaderProgram, 0, "outColor");
319  glLinkProgram(shaderProgram);
320  glUseProgram(shaderProgram);
321  }
322 
323  void SetVerticesSize(int size) {
324  this->VerticesSize = size;
325  }
326 
328  return this->VerticesBuffer.size();
329  }
330 
331  /*void AddNewTexture(OpenGLTexture *texture) {
332  TexturesBuffer.push_back(texture);
333 
334  textureWidthBuffer += texture->width;
335 
336  textureSizeBuffer++;
337  }*/
338 
340  TexturesBuffer.push_back(texture);
341 
342  textureWidthBuffer += texture->width;
343 
344  textureSizeBuffer++;
345  }
346 
347 
349  return textureWidth;
350  }
351 
353  return textureHeight;
354  }
355 
356  int GetTextureWidth(int index){
357  return TexturesBuffer[index]->width;
358  }
359 
360  int GetTextureWidthSum(int index){
361  int sum = 0;
362  for(int i = 0; i < index+1; i++)
363  sum += TexturesBuffer[i]->width;
364 
365  return sum;
366  }
367 
368  void SetTextureHeight(int textheight){
369  textureHeight = textheight;
370  }
371 
372  void SetModel() {
373  GLuint uniform = glGetUniformLocation(shaderProgram, "Model");
374  glUniformMatrix4fv(uniform, 1, GL_FALSE, glm::value_ptr(Model));
375  }
376 
377  void SetView(float /*lookX*/, float /*lookY*/) {
378  View = glm::lookAt(
379  glm::vec3(0.0, 0.0, 1.0f), //position
380  glm::vec3(0.0f, 0.0f, 0.0f), //look
381  glm::vec3(0.0f, 1.0f, 0.0f) //up
382  );
383  GLint uniView = glGetUniformLocation(shaderProgram, "View");
384  glUniformMatrix4fv(uniView, 1, GL_FALSE, glm::value_ptr(View));
385  }
386 
387  void SetProjection(float width, float height) {
388  Projection = glm::perspective(glm::radians(60.0f), (float) width / (float) height, 0.1f, 10.0f);
389  GLint uniProj = glGetUniformLocation(shaderProgram, "Projection");
390  glUniformMatrix4fv(uniProj, 1, GL_FALSE, glm::value_ptr(Projection));
391  }
392 
393  void AddAttrib(std::string attribName, GLint length, GLuint type, size_t positionOffset) {
394  GLint attrib = glGetAttribLocation(shaderProgram, attribName.c_str());
395  glEnableVertexAttribArray(attrib);
396  glVertexAttribPointer(attrib, length, type, GL_FALSE, VerticesSize * sizeof(GLfloat), (void *) positionOffset);
397  }
398 
399  void AddUniform(std::string uniformName, float value) {
400  GLuint uniform = glGetUniformLocation(shaderProgram, uniformName.c_str());
401  glUniform1f(uniform, value);
402  }
403 
404  GLuint getVAO() {
405  return this->VAO;
406  }
407 
408  GLuint GetTexture() {
409  return this->Tex;
410  }
411 
412  GLuint getShaderProgram() {
413  return this->shaderProgram;
414  }
415 
416  const glm::mat4 &GetModel() const {
417  return Model;
418  }
419 
420  const glm::mat4 &GetView() const {
421  return View;
422  }
423 
424  const glm::mat4 &GetProjection() const {
425  return Projection;
426  }
427 
428  void Draw() {
429  glDrawElements(GL_TRIANGLES, (GLsizei) Elements.size(), GL_UNSIGNED_INT, 0);
430  }
431 
433  glDeleteProgram(shaderProgram);
434  glDeleteShader(FragmentShader);
435  glDeleteShader(VertexShader);
436 
437  glDeleteBuffers(1, &EBO);
438  glDeleteBuffers(1, &VBO);
439 
440  glDeleteVertexArrays(1, &VAO);
441  }
442 
443  };
444 }
445 
446 #endif //LIBOSMSCOUT_OPENGLMAPDATA_H
void BindBuffers()
Definition: OpenGLMapData.h:197
const glm::mat4 & GetView() const
Definition: OpenGLMapData.h:420
~OpenGLTexture()
Definition: OpenGLMapData.h:45
Definition: OpenGLMapData.h:53
void LoadProgram()
Definition: OpenGLMapData.h:314
void LoadGreyTextures()
Definition: OpenGLMapData.h:276
Definition: OpenGLMapData.h:36
void SwapData(int stride)
Definition: OpenGLMapData.h:158
size_t width
Definition: OpenGLMapData.h:38
void SetModel()
Definition: OpenGLMapData.h:372
GLuint getShaderProgram()
Definition: OpenGLMapData.h:412
size_t size
Definition: OpenGLMapData.h:40
GLuint GetTexture()
Definition: OpenGLMapData.h:408
void Draw()
Definition: OpenGLMapData.h:428
size_t height
Definition: OpenGLMapData.h:39
void AddNewElement(GLuint element)
Definition: OpenGLMapData.h:306
void LoadVertexShader(std::string fileName)
Definition: OpenGLMapData.h:292
Definition: Projection.h:43
Definition: Area.h:38
~OpenGLMapData()
Definition: OpenGLMapData.h:432
int GetTextureWidth()
Definition: OpenGLMapData.h:348
int GetTextureHeight()
Definition: OpenGLMapData.h:352
int GetVerticesNumber()
Definition: OpenGLMapData.h:310
void AddUniform(std::string uniformName, float value)
Definition: OpenGLMapData.h:399
void SwapData()
Definition: OpenGLMapData.h:126
void clearData()
Definition: OpenGLMapData.h:188
void LoadFragmentShader(std::string fileName)
Definition: OpenGLMapData.h:287
void SetProjection(float width, float height)
Definition: OpenGLMapData.h:387
void SetVerticesSize(int size)
Definition: OpenGLMapData.h:323
int GetNumOfVertices()
Definition: OpenGLMapData.h:327
void SetView(float, float)
Definition: OpenGLMapData.h:377
const glm::mat4 & GetModel() const
Definition: OpenGLMapData.h:416
size_t fromOriginY
Definition: OpenGLMapData.h:43
int GetTextureWidthSum(int index)
Definition: OpenGLMapData.h:360
void AddNewVertex(GLfloat vertex)
Definition: OpenGLMapData.h:302
void SetTextureHeight(int textheight)
Definition: OpenGLMapData.h:368
void LoadVertices()
Definition: OpenGLMapData.h:297
void LoadTextures()
Definition: OpenGLMapData.h:266
void AddNewTexture(OpenGLTextureRef texture)
Definition: OpenGLMapData.h:339
const glm::mat4 & GetProjection() const
Definition: OpenGLMapData.h:424
bool InitContext()
Definition: OpenGLMapData.h:201
std::shared_ptr< OpenGLTexture > OpenGLTextureRef
Definition: OpenGLMapData.h:51
void AddAttrib(std::string attribName, GLint length, GLuint type, size_t positionOffset)
Definition: OpenGLMapData.h:393
GLuint getVAO()
Definition: OpenGLMapData.h:404
int GetTextureWidth(int index)
Definition: OpenGLMapData.h:356
unsigned char * data
Definition: OpenGLMapData.h:41