Fillwave  10.0.0
TVertexBuffer.h
1 #pragma once
2 
3 /*
4  * The MIT License (MIT)
5  *
6  * Copyright (c) 2018 Filip Wasil and Fillwave community members
7  *
8  * Permission is hereby granted, free of charge, to any person
9  * obtaining a copy of this software and associated documentation files (the "Software"),
10  * to deal in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
12  * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included
15  * in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
18  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
20  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 #include <flw/flc/buffers/IBuffer.h>
24 #include <flw/flc/pipeline/Attribute.h>
25 
26 #include <flw/flf/models/shapes/Shape.h>
27 
28 #include <flw/cmn/Containers.h>
29 
30 #include <algorithm>
31 
32 namespace flw {
33 namespace flc {
34 
35 class Attribute;
36 
41 template <class T>
42 class TVertexBuffer : public IBuffer {
43 public:
44  /* Notice
45  * In this constructor one should initialize:
46  * - mDataVertices -> vector of <T> data
47  *
48  * mData = mDataVertices.data();
49  * mTotalElements = mDataVertices.size();
50  * mSize = mTotalElements*sizeof(<T>);
51  */
52 
53  TVertexBuffer(GLuint dataStoreModification = GL_STATIC_DRAW)
54  : IBuffer(GL_ARRAY_BUFFER, dataStoreModification) {
55  // nothing
56  }
57 
58  TVertexBuffer(const std::vector<T> &vertices, GLuint dataStoreModification = GL_STATIC_DRAW)
59  : IBuffer(GL_ARRAY_BUFFER, dataStoreModification) {
60  mDataVertices = vertices;
61  mTotalElements = mDataVertices.size();
62  mData = mDataVertices.data();
63  mSize = mTotalElements * sizeof(T);
64  }
65 
66  TVertexBuffer(flf::Shape<T> &shape, GLuint dataStoreModification = GL_STATIC_DRAW)
67  : IBuffer(GL_ARRAY_BUFFER, dataStoreModification) {
68  mDataVertices = shape.getVertices();
69  mSize = mTotalElements * sizeof(T);
70  mData = mDataVertices.data();
71  }
72 
73  ~TVertexBuffer() override = default;
74 
75  void load(T element) {
76  mDataVertices.push_back(element);
77  mTotalElements++;
78  mSize = mTotalElements * sizeof(T);
79  mData = mDataVertices.data();
80  }
81 
82  void initAttributes(GLint programHandle) {
83  if (mAttributes.empty()) {
84  getAttributes(programHandle);
85  }
86  }
87 
88  void attributesSetForVAO() {
89  std::for_each(mAttributes.begin(), mAttributes.end(), [](Attribute &a) {
90  a.arrayEnable();
91  });
92  std::for_each(mAttributes.begin(), mAttributes.end(), [](Attribute &a) {
93  a.arraySet();
94  });
95  }
96 
97  void attributesEnable() {
98  std::for_each(mAttributes.begin(), mAttributes.end(), [](Attribute &a) {
99  a.arrayEnable();
100  });
101  }
102 
103  void reload() {
104  IBuffer::reload();
105  }
106 
107  void attributesSetPointer() {
108  std::for_each(mAttributes.begin(), mAttributes.end(), [](Attribute &a) {
109  a.arraySet();
110  });
111  }
112 
113  T *getDataInternal() {
114  if (mDataVertices.empty()) {
115  std::cout << "Not cpu data in this buffer" << std::endl;
116  return nullptr;
117  }
118  return mDataVertices.data();
119  }
120 
121  void emptyCPU() override {
122  mDataVertices.clear();
123  mData = nullptr;
124  mTotalElements = 0;
125  }
126 
127  void emptyGPU() override {
128  std::cout << "Not gpu data clear is possible in this buffer" << std::endl;
129  }
130 
131  virtual void log() const = 0;
132 
133 protected:
134  std::vector<T> mDataVertices;
135 
136  inline void getAttributes(GLint programHandle) {
137  int howMany = -1;
138  glGetProgramiv(programHandle, GL_ACTIVE_ATTRIBUTES, &howMany);
139  mAttributes.reserve(howMany);
140  for (int i = 0; i < howMany; ++i) {
141  int name_len = -1, num = -1;
142  GLenum type = GL_ZERO;
143  char name[200];
144  glGetActiveAttrib(programHandle, GLuint(i), sizeof(name) - 1, &name_len, &num, &type, name);
145  name[name_len] = 0;
146  GLuint location = glGetAttribLocation(programHandle, name);
147  GLuint size = 0;
148  switch (type) {
149  case GL_UNSIGNED_INT:
150  case GL_FLOAT:
151  case GL_INT:
152  case GL_BOOL:
153  size = 1;
154  break;
155  case GL_FLOAT_VEC2:
156  case GL_INT_VEC2:
157  case GL_BOOL_VEC2:
158  size = 2;
159  break;
160  case GL_FLOAT_VEC3:
161  case GL_INT_VEC3:
162  case GL_BOOL_VEC3:
163  size = 3;
164  break;
165  case GL_FLOAT_VEC4:
166  case GL_INT_VEC4:
167  case GL_BOOL_VEC4:
168  case GL_FLOAT_MAT2:
169  size = 4;
170  break;
171  case GL_FLOAT_MAT3:
172  size = 9;
173  break;
174  case GL_FLOAT_MAT4:
175  size = 16;
176  break;
177 #if defined(FILLWAVE_BACKEND_OPENGL_ES_20) || defined(FILLWAVE_BACKEND_OPENGL_ES_30)
178 #else
179  case GL_UNSIGNED_INT_VEC3:
180  size = 3;
181  break;
182  case GL_UNSIGNED_INT_VEC2:
183  size = 2;
184  break;
185  case GL_UNSIGNED_INT_VEC4:
186  size = 4;
187  break;
188 #endif
189  default:
190  std::cout << "Not supported type of attribute" << std::endl;
191  size = 0;
192  break;
193  }
194  //std::string n(name);
195  Attribute a(name, location, size, sizeof(T), type);
196  mAttributes.push_back(a);
197  }
198 
199  unsigned long long pointer = 0;
200  for (GLuint i = 0; i < mAttributes.size(); i++) {
201  for (auto &it : mAttributes) {
202  if (it.getIndex() == i) {
203  it.setOffsetPointer((GLvoid *) pointer);
204  pointer += it.getSize() * it.getTypeSize();
205  }
206  }
207  }
208  }
209 
210  inline void attributesBind(GLint programHandle) {
211  std::for_each(mAttributes.begin(), mAttributes.end(), [programHandle](Attribute &a) {
212  a.bindLocation(programHandle);
213  });
214  }
215 
216 private:
217  vecStack<Attribute> mAttributes;
218 };
219 
220 } /* flc */
221 } /* flw */
Definition: Aliases.h:30
Template for all vertex buffers.
Definition: TVertexBuffer.h:42
VertexAttribute to be kept within the VertexBuffer.
Definition: Attribute.h:33
Base for all buffer types.
Definition: IBuffer.h:33
Base class for every shape. Specialized with Vertex data structure.
Definition: Shape.h:37