SimpleGL  1.1.0
A framework for platform independent rendering
batching_gl.cpp
Go to the documentation of this file.
1 
9 
10 #include <glm/glm.hpp>
11 
12 #include <SimpleGL/logging.hpp>
13 
14 using namespace glm;
15 
16 namespace sgl {
17  std::string BatchGL::vertexSource =
18  "#version 150 core\n"
19 
20  "uniform mat4 model;"
21  "uniform mat4 view;"
22  "uniform mat4 projection;"
23 
24  "in vec3 position;"
25  "in vec4 color;"
26  "in vec2 texCoord;"
27 
28  "out vec4 vertexColor;"
29  "out vec2 textureCoord;"
30 
31  "void main() {"
32  " vertexColor = color;"
33  " textureCoord = texCoord;"
34  " mat4 mvp = projection * view * model;"
35  " gl_Position = mvp * vec4(position, 1.0f);"
36  "}";
37 
38  std::string BatchGL::fragmentSource =
39  "#version 150 core\n"
40 
41  "uniform sampler2D texImage;"
42 
43  "in vec4 vertexColor;"
44  "in vec2 textureCoord;"
45 
46  "out vec4 fragColor;"
47 
48  "void main() {"
49  " vec4 textureColor = texture(texImage, textureCoord);"
50  " fragColor = vertexColor * textureColor;"
51  "}";
52 
53  Texture* BatchGL::defaultTexture;
54 
55  ShaderProgram* BatchGL::defaultShaderProgram;
56 
57  BatchGL::BatchGL(int capacity) : Batch() {
58  /* Generate default texture, this texture contains 1 white pixel */
59  /* This texture will work like some kind of a bitmask */
60  BatchGL::defaultTexture = new Texture();
61  unsigned char data[] = {0xFF, 0xFF, 0xFF, 0xFF};
62  BatchGL::defaultTexture->bind();
63  BatchGL::defaultTexture->uploadImage(1, 1, data);
64 
65  /* Bind vertex array object */
66  vao = new VertexArray();
67  vao->bind();
68 
69  /* Upload null data to vertex buffer object */
70  vbo = new Buffer();
72  vbo->uploadData(BufferTarget::ARRAY_BUFFER, capacity * sizeof (vec3), BufferUsage::DYNAMIC_DRAW);
73 
74  /* Upload null data to color buffer object */
75  cbo = new Buffer();
77  cbo->uploadData(BufferTarget::ARRAY_BUFFER, capacity * sizeof (vec4), BufferUsage::DYNAMIC_DRAW);
78 
79  /* Upload null data to texture coordinates buffer object */
80  tbo = new Buffer();
82  tbo->uploadData(BufferTarget::ARRAY_BUFFER, capacity * sizeof (vec2), BufferUsage::DYNAMIC_DRAW);
83 
84  /* Upload null data to normal buffer object */
85  nbo = new Buffer();
87  nbo->uploadData(BufferTarget::ARRAY_BUFFER, capacity * sizeof (vec3), BufferUsage::DYNAMIC_DRAW);
88 
89  /* Compile Vertex Shader */
90  Shader vertexShader(ShaderType::VERTEX_SHADER);
91  vertexShader.source(BatchGL::vertexSource);
92  vertexShader.compile();
93 
94  /* Check if compiling was succesful */
95  if (!vertexShader.getCompileStatus()) {
96  Logger::logError(vertexShader.getInfoLog());
97  }
98 
99  /* Compile Fragment Shader */
100  Shader fragmentShader(ShaderType::FRAGMENT_SHADER);
101  fragmentShader.source(BatchGL::fragmentSource);
102  fragmentShader.compile();
103 
104  /* Check if compiling was succesful */
105  if (!fragmentShader.getCompileStatus()) {
106  Logger::logError(fragmentShader.getInfoLog());
107  }
108 
109  /* Link shader program */
110  shaderProgram = new ShaderProgram();
111  shaderProgram->attach(&vertexShader);
112  shaderProgram->attach(&fragmentShader);
113  shaderProgram->link();
114 
115  /* Check if linking was successful */
116  if (!shaderProgram->getLinkStatus()) {
117  Logger::logError(shaderProgram->getInfoLog());
118  }
119 
120  /* Store default shader program */
121  BatchGL::defaultShaderProgram = shaderProgram;
122 
123  /* Use shader program */
124  shaderProgram->use();
125 
126  /* Specify vertex attributes */
128 
129  /* Bind fragment out color */
130  shaderProgram->bindFragmentDataLocation(0, "fragColor");
131 
132  /* Set texture uniform */
133  shaderProgram->setUniform("texImage", 0);
134 
135  /* Apply default MVP */
136  applyTransform();
137  }
138 
140  /* Delete VAO */
141  delete vao;
142 
143  /* Delete VBOs */
144  delete vbo;
145  delete cbo;
146  delete tbo;
147  delete nbo;
148 
149  /* Delete program */
150  delete shaderProgram;
151  }
152 
153  void BatchGL::begin() {
155  }
156 
158  /* Start drawing only if the batch isn't already drawing */
159  if (!drawing) {
160  this->mode = mode;
161  drawing = true;
162  numVertices = 0;
163  }
164  }
165 
166  void BatchGL::flush() {
167  /* Only flush if there is at least one vertex */
168  if (numVertices > 0) {
169  /* Fill colors */
170  if (colors.size() == 0) {
171  /* No color: Fill with white */
172  while (colors.size() < vertices.size()) {
173  color(vec4(1.0f));
174  }
175  } else if (colors.size() < vertices.size()) {
176  /* Less colors than vertices: Fill with last color */
177  vec4 lastColor = colors.back();
178  while (colors.size() < vertices.size()) {
179  color(lastColor);
180  }
181  }
182 
183  /* Fill texCoords */
184  if (texCoords.size() == 0) {
185  /* No texture coordinates, bind mask texture */
186  BatchGL::defaultTexture->bind();
187  }
188  while (texCoords.size() < vertices.size()) {
189  texCoord(vec2(1.0f));
190  }
191 
192  /* Fill normals */
193  while (normals.size() < vertices.size()) {
194  normal(vec3(0.0f));
195  }
196 
197  /* Use shader program */
198  shaderProgram->use();
199 
200  /* Apply transformation */
201  applyTransform();
202 
203  /* Upload vertex data */
206 
207  /* Upload color data */
209  cbo->uploadSubData(BufferTarget::ARRAY_BUFFER, 0, numVertices * sizeof (vec4), colors);
210 
211  /* Upload texCoord data */
214 
215  /* Upload normal data */
217  nbo->uploadSubData(BufferTarget::ARRAY_BUFFER, 0, numVertices * sizeof (vec3), normals);
218 
219  /* Draw batch */
220  GL::drawArrays(mode, 0, numVertices);
221 
222  /* Clear lists */
223  vertices.clear();
224  colors.clear();
225  texCoords.clear();
226  normals.clear();
227  numVertices = 0;
228  }
229  }
230 
232  /* Specify vertex pointer, vertices are vec3 */
234  int positionAttribute = shaderProgram->getAttributeLocation("position");
235  vao->enableAttribute(positionAttribute);
236  vao->pointAttribute(positionAttribute, 3, ValueType::FLOAT, false, sizeof (vec3), 0);
237 
238  /* Specify color pointer, colors are vec4 */
240  int colorAttribute = shaderProgram->getAttributeLocation("color");
241  vao->enableAttribute(colorAttribute);
242  vao->pointAttribute(colorAttribute, 4, ValueType::FLOAT, false, sizeof (vec4), 0);
243 
244  /* Specify texCoord pointer, texCoords are vec2 */
246  int texCoordAttribute = shaderProgram->getAttributeLocation("texCoord");
247  vao->enableAttribute(texCoordAttribute);
248  vao->pointAttribute(texCoordAttribute, 2, ValueType::FLOAT, false, sizeof (vec2), 0);
249 
250  /* Specify normal pointer, normals are vec3 */
252  int normalAttribute = shaderProgram->getAttributeLocation("normal");
253  vao->enableAttribute(normalAttribute);
254  vao->pointAttribute(normalAttribute, 3, ValueType::FLOAT, false, sizeof (vec3), 0);
255  }
256 
258  /* Only change if transformation was changed */
259  if (transformation.changed) {
260  /* Set model matrix */
261  shaderProgram->setUniform("model", transformation.model);
262 
263  /* Set view matrix */
264  shaderProgram->setUniform("view", transformation.view);
265 
266  /* Set projection matrix */
267  shaderProgram->setUniform("projection", transformation.projection);
268 
269  /* Transformation applied */
270  transformation.changed = false;
271  }
272  }
273 
275  setShaderProgram(BatchGL::defaultShaderProgram);
276  }
277 
279  return shaderProgram;
280  }
281 
283  shaderProgram = program;
284 
285  /* Specify vertex attributes */
286  shaderProgram->use();
288 
289  /* Force applyTransform */
290  transformation.changed = true;
291  applyTransform();
292  }
293 }
Equivalent to GL_ARRAY_BUFFER.
void flush() override
Flushes the batch, could be used if the batch would overflow.
void specifyVertexAttributes()
Specifies the vertex attributes.
int getAttributeLocation(std::string name)
Gets the location of an attribute variable with specified name.
This class wraps an OpenGL shader object.
Primitive
This enum wraps Primitive types of OpenGL.
Definition: gl_general.hpp:60
void color(float r, float g, float b)
Defines a new color with specified components.
Definition: batching.cpp:64
void bind()
Binds the vertex array object.
Equivalent to GL_VERTEX_SHADER.
static void logError(std::string message)
Logs an error string to cerr.
Definition: logging.cpp:24
void compile()
Compiles the shader object.
void source(std::string source)
Sets the source code of the shader object.
glm::mat4 projection
The projection matrix.
Definition: transform.hpp:49
void pointAttribute(unsigned int index, int size, ValueType type, bool normalized, int stride, long offset)
Sets the vertex attribute pointer.
This class wraps an OpenGL vertex array object.
This class wraps an OpenGL shader program.
This class wraps an OpenGL buffer object.
Generic namespace for the SimpleGL framework.
Definition: application.hpp:18
glm::mat4 view
The view matrix.
Definition: transform.hpp:46
std::vector< glm::vec3 > vertices
The storage for vertices.
Definition: batching.hpp:39
bool drawing
Tells if the batch is drawing.
Definition: batching.hpp:33
static void drawArrays(Primitive mode, int first, int count)
Renders vertex data with the current bound VBO.
Definition: gl_general.cpp:75
This class wraps an OpenGL texture object.
void use()
Uses the shader program for the current rendering state.
void texCoord(float s, float t)
Defines a new texture coordinate with specified values.
Definition: batching.cpp:80
void resetShaderProgram()
Resets to the default shader program.
Equivalent to GL_DYNAMIC_DRAW.
void normal(float nx, float ny, float nz)
Defines a new normal with specified values.
Definition: batching.cpp:88
void begin() override
Starts drawing with TRIANGLES mode.
int numVertices
The counter for the number of vertices.
Definition: batching.hpp:36
void bind(BufferTarget target)
Binds the buffer object with the specified target.
std::vector< glm::vec2 > texCoords
The storage for texture coordinates.
Definition: batching.hpp:45
void uploadSubData(BufferTarget target, long offset, long size, float *data)
Uploads the specified data to the buffer object starting at the offset.
Equivalent to GL_FRAGMENT_SHADER.
This class defines methods for batch rendering.
Definition: batching.hpp:26
void enableAttribute(unsigned int index)
Enables a vertex attribute.
Transformation transformation
The transformation for the batch.
Definition: batching.hpp:30
void uploadData(BufferTarget target, long size, float *data, BufferUsage usage)
Uploads the specified data to the buffer object.
bool changed
Tells if the transformation has changed.
Definition: transform.hpp:58
void applyTransform()
Applies the MVP transformation if necessary.
void setUniform(int location, int value)
Sets the value of an uniform variable.
Equivalent to GL_FLOAT.
Equivalent to GL_TRIANGLES.
std::vector< glm::vec4 > colors
The storage for colors.
Definition: batching.hpp:42
bool getCompileStatus()
Checks the compile status of the shader object.
~BatchGL(void)
Destroys a batch.
void setShaderProgram(ShaderProgram *program)
Sets the current shader program of the batch.
glm::mat4 model
The model matrix.
Definition: transform.hpp:43
std::string getInfoLog()
Gets the info log of the shader object.
std::vector< glm::vec3 > normals
The storage for normals.
Definition: batching.hpp:48
ShaderProgram * getShaderProgram()
Gets the current shader program of the batch.