CUGL
Cornell University Game Library
CUSpriteBatch.h
1 //
2 // CUSpriteBatch.h
3 // Cornell University Game Library (CUGL)
4 //
5 // This module provides one-stop shopping for basic 2d graphics. Despite the
6 // name, it is also capable of drawing solid shapes, as well as wireframes.
7 // The only time you might want a separate class is when you need another
8 // shader. And even then, you can swap out the shader for this class.
9 //
10 // This class uses our standard shared-pointer architecture.
11 //
12 // 1. The constructor does not perform any initialization; it just sets all
13 // attributes to their defaults.
14 //
15 // 2. All initialization takes place via init methods, which can fail if an
16 // object is initialized more than once.
17 //
18 // 3. All allocation takes place via static constructors which return a shared
19 // pointer.
20 //
21 // CUGL zlib License:
22 // This software is provided 'as-is', without any express or implied
23 // warranty. In no event will the authors be held liable for any damages
24 // arising from the use of this software.
25 //
26 // Permission is granted to anyone to use this software for any purpose,
27 // including commercial applications, and to alter it and redistribute it
28 // freely, subject to the following restrictions:
29 //
30 // 1. The origin of this software must not be misrepresented; you must not
31 // claim that you wrote the original software. If you use this software
32 // in a product, an acknowledgment in the product documentation would be
33 // appreciated but is not required.
34 //
35 // 2. Altered source versions must be plainly marked as such, and must not
36 // be misrepresented as being the original software.
37 //
38 // 3. This notice may not be removed or altered from any source distribution.
39 //
40 // Author: Walker White
41 // Version: 6/23/16
42 
43 #ifndef __CU_SPRITE_BATCH_H__
44 #define __CU_SPRITE_BATCH_H__
45 
46 #include <SDL/SDL.h>
47 #include "../math/CUMathBase.h"
48 #include "../math/CUMat4.h"
49 #include "CUVertex.h"
50 #include <vector>
51 
52 #define DEFAULT_CAPACITY 8192
53 
54 namespace cugl {
55 
57 class SpriteShader;
58 class Affine2;
59 class Texture;
60 class Rect;
61 class Poly2;
62 
78 class SpriteBatch {
79 #pragma mark Values
80 private:
82  std::shared_ptr<SpriteShader> _shader;
84  unsigned int _capacity;
85 
87  GLuint _vertArray;
89  GLuint _vertBuffer;
91  GLuint _indxBuffer;
92 
94  Vertex2* _vertData;
96  GLuint* _indxData;
97 
99  unsigned int _vertMax;
101  unsigned int _vertSize;
102 
104  unsigned int _indxMax;
106  unsigned int _indxSize;
107 
109  std::shared_ptr<Texture> _texture;
111  Color4 _color;
113  GLenum _command;
115  Mat4 _perspective;
116 
118  GLenum _blendEquation;
120  GLenum _srcFactor;
122  GLenum _dstFactor;
123 
125  unsigned int _vertTotal;
127  unsigned int _callTotal;
128 
130  bool _initialized;
132  bool _active;
133 
135  static std::shared_ptr<Texture> _blank;
136 
137 
138 #pragma mark -
139 #pragma mark Constructors
140 public:
146  SpriteBatch();
147 
152 
158  void dispose();
159 
173  bool init();
174 
188  bool init(std::shared_ptr<SpriteShader> shader) {
189  return init(DEFAULT_CAPACITY,shader);
190  }
191 
209  bool init(unsigned int capacity);
210 
228  bool init(unsigned int capacity, std::shared_ptr<SpriteShader> shader);
229 
230 #pragma mark -
231 #pragma mark Static Constructors
232 
245  static std::shared_ptr<SpriteBatch> alloc() {
246  std::shared_ptr<SpriteBatch> result = std::make_shared<SpriteBatch>();
247  return (result->init() ? result : nullptr);
248  }
249 
267  static std::shared_ptr<SpriteBatch> alloc(unsigned int capacity) {
268  std::shared_ptr<SpriteBatch> result = std::make_shared<SpriteBatch>();
269  return (result->init(capacity) ? result : nullptr);
270  }
271 
272 #pragma mark -
273 #pragma mark Attributes
274 
279  bool isReady() const { return _initialized; }
280 
289  bool isDrawing() const { return _active; }
290 
298  unsigned int getVerticesDrawn() const { return _vertTotal; }
299 
307  unsigned int getCallsMade() const { return _callTotal; }
308 
316  void setShader(const std::shared_ptr<SpriteShader>& shader);
317 
325  const std::shared_ptr<SpriteShader>& getShader() const { return _shader; }
326 
337  void setColor(Color4 color) { _color = color; }
338 
347  Color4 getColor() const { return _color; }
348 
362  void setTexture(const std::shared_ptr<Texture>& texture);
363 
373  const std::shared_ptr<Texture>& getTexture() const { return _texture; }
374 
384  static const std::shared_ptr<Texture>& getBlankTexture();
385 
386  // TODO: Orthographic support from query
396  void setPerspective(const Mat4& perspective);
397 
406  const Mat4& getPerspective() const { return _perspective; }
407 
425  void setBlendFunc(GLenum srcFactor, GLenum dstFactor);
426 
436  GLenum getSourceBlendFactor() const { return _srcFactor; }
437 
447  GLenum getDestinationBlendFactor() const { return _srcFactor; }
448 
463  void setBlendEquation(GLenum equation);
464 
474  GLenum getBlendEquation() const { return _blendEquation; }
475 
476 #pragma mark -
477 #pragma mark Rendering
478 
486  void begin();
487 
498  void begin(const Mat4& perspective) {
499  setPerspective(perspective); begin();
500  }
501 
508  void end();
509 
517  void flush();
518 
519 #pragma mark -
520 #pragma mark Solid Shapes
521 
532  void fill(const Rect& rect);
533 
555  void fill(const Rect& rect, const Vec2& origin, const Vec2& scale, float angle, const Vec2& offset);
556 
575  void fill(const Rect& rect, const Vec2& origin, const Mat4& transform);
576 
595  void fill(const Rect& rect, const Vec2& origin, const Affine2& transform);
596 
619  void fill(const Poly2& poly);
620 
646  void fill(const Poly2& poly, const Vec2& offset);
647 
680  void fill(const Poly2& poly, const Vec2& origin, const Vec2& scale, float angle, const Vec2& offset);
681 
711  void fill(const Poly2& poly, const Vec2& origin, const Mat4& transform);
712 
742  void fill(const Poly2& poly, const Vec2& origin, const Affine2& transform);
743 
764  void fill(const std::vector<Vertex2>& vertices, const std::vector<unsigned short>& indices,
765  const Mat4& transform, bool tint = true) {
766  fill(vertices.data(),(unsigned int)vertices.size(),0,indices.data(),(unsigned int)indices.size(),0,transform,tint);
767  }
768 
789  void fill(const std::vector<Vertex2>& vertices, const std::vector<unsigned short>& indices,
790  const Affine2& transform, bool tint = true) {
791  fill(vertices.data(),(unsigned int)vertices.size(),0,indices.data(),(unsigned int)indices.size(),0,transform,tint);
792  }
793 
818  void fill(const Vertex2* vertices, unsigned int vsize, unsigned int voffset,
819  const unsigned short* indices, unsigned int isize, unsigned int ioffset,
820  const Mat4& transform, bool tint = true);
821 
846  void fill(const Vertex2* vertices, unsigned int vsize, unsigned int voffset,
847  const unsigned short* indices, unsigned int isize, unsigned int ioffset,
848  const Affine2& transform, bool tint = true);
849 
850 #pragma mark -
851 #pragma mark Outlines
852 
864  void outline(const Rect& rect);
865 
888  void outline(const Rect& rect, const Vec2& origin, const Vec2& scale, float angle, const Vec2& offset);
889 
909  void outline(const Rect& rect, const Vec2& origin, const Mat4& transform);
910 
930  void outline(const Rect& rect, const Vec2& origin, const Affine2& transform);
931 
954  void outline(const Poly2& poly);
955 
981  void outline(const Poly2& poly, const Vec2& offset);
982 
1015  void outline(const Poly2& poly, const Vec2& origin, const Vec2& scale, float angle, const Vec2& offset);
1016 
1046  void outline(const Poly2& poly, const Vec2& origin, const Mat4& transform);
1047 
1077  void outline(const Poly2& poly, const Vec2& origin, const Affine2& transform);
1078 
1099  void outline(const std::vector<Vertex2>& vertices, const std::vector<unsigned short>& indices,
1100  const Mat4& transform, bool tint = true) {
1101  outline(vertices.data(),(unsigned int)vertices.size(),0,indices.data(),(unsigned int)indices.size(),0,transform,tint);
1102  }
1103 
1124  void outline(const std::vector<Vertex2>& vertices, const std::vector<unsigned short>& indices,
1125  const Affine2& transform, bool tint = true) {
1126  outline(vertices.data(),(unsigned int)vertices.size(),0,indices.data(),(unsigned int)indices.size(),0,transform,tint);
1127  }
1128 
1153  void outline(const Vertex2* vertices, unsigned int vsize, unsigned int voffset,
1154  const unsigned short* indices, unsigned int isize, unsigned int ioffset,
1155  const Mat4& transform, bool tint = true);
1156 
1181  void outline(const Vertex2* vertices, unsigned int vsize, unsigned int voffset,
1182  const unsigned short* indices, unsigned int isize, unsigned int ioffset,
1183  const Affine2& transform, bool tint = true);
1184 
1185 #pragma mark -
1186 #pragma mark Convenience Methods
1187 
1198  void draw(const std::shared_ptr<Texture>& texture, const Vec2& position);
1199 
1212  void draw(const std::shared_ptr<Texture>& texture, Color4 color, const Vec2& position);
1213 
1224  void draw(const std::shared_ptr<Texture>& texture, const Rect& bounds) {
1225  setTexture(texture); setColor(Color4::WHITE);
1226  fill(bounds);
1227  }
1228 
1240  void draw(const std::shared_ptr<Texture>& texture, Color4 color, const Rect& bounds) {
1241  setTexture(texture); setColor(color);
1242  fill(bounds);
1243  }
1244 
1265  void draw(const std::shared_ptr<Texture>& texture,
1266  const Vec2& origin, const Vec2& scale, float angle, const Vec2& offset);
1267 
1289  void draw(const std::shared_ptr<Texture>& texture, Color4 color,
1290  const Vec2& origin, const Vec2& scale, float angle, const Vec2& offset);
1291 
1313  void draw(const std::shared_ptr<Texture>& texture, const Rect& bounds,
1314  const Vec2& origin, const Vec2& scale, float angle, const Vec2& offset) {
1315  setTexture(texture); setColor(Color4::WHITE);
1316  fill(bounds, origin, scale, angle, offset);
1317  }
1318 
1341  void draw(const std::shared_ptr<Texture>& texture, Color4 color, const Rect& bounds,
1342  const Vec2& origin, const Vec2& scale, float angle, const Vec2& offset) {
1343  setTexture(texture); setColor(color);
1344  fill(bounds, origin, scale, angle, offset);
1345  }
1346 
1363  void draw(const std::shared_ptr<Texture>& texture, const Vec2& origin, const Mat4& transform);
1364 
1382  void draw(const std::shared_ptr<Texture>& texture, Color4 color, const Vec2& origin, const Mat4& transform);
1383 
1401  void draw(const std::shared_ptr<Texture>& texture, const Rect& bounds,
1402  const Vec2& origin, const Mat4& transform) {
1403  setTexture(texture); setColor(Color4::WHITE);
1404  fill(bounds, origin, transform);
1405  }
1406 
1425  void draw(const std::shared_ptr<Texture>& texture, Color4 color, const Rect& bounds,
1426  const Vec2& origin, const Mat4& transform) {
1427  setTexture(texture); setColor(color);
1428  fill(bounds, origin, transform);
1429  }
1430 
1447  void draw(const std::shared_ptr<Texture>& texture, const Vec2& origin, const Affine2& transform);
1448 
1466  void draw(const std::shared_ptr<Texture>& texture, Color4 color,
1467  const Vec2& origin, const Affine2& transform);
1468 
1486  void draw(const std::shared_ptr<Texture>& texture, const Rect& bounds,
1487  const Vec2& origin, const Affine2& transform) {
1488  setTexture(texture); setColor(Color4::WHITE);
1489  fill(bounds, origin, transform);
1490  }
1491 
1510  void draw(const std::shared_ptr<Texture>& texture, Color4 color, const Rect& bounds,
1511  const Vec2& origin, const Affine2& transform) {
1512  setTexture(texture); setColor(color);
1513  fill(bounds, origin, transform);
1514  }
1515 
1544  void draw(const std::shared_ptr<Texture>& texture, const Poly2& poly, const Vec2& offset) {
1545  setTexture(texture); setColor(Color4::WHITE);
1546  fill(poly, offset);
1547  }
1548 
1578  void draw(const std::shared_ptr<Texture>& texture, Color4 color, const Poly2& poly, const Vec2& offset) {
1579  setTexture(texture); setColor(color);
1580  fill(poly, offset);
1581  }
1582 
1620  void draw(const std::shared_ptr<Texture>& texture, const Poly2& poly,
1621  const Vec2& origin, const Vec2& scale, float angle, const Vec2& offset) {
1622  setTexture(texture); setColor(Color4::WHITE);
1623  fill(poly, origin, scale, angle, offset);
1624  }
1625 
1664  void draw(const std::shared_ptr<Texture>& texture, Color4 color, const Poly2& poly,
1665  const Vec2& origin, const Vec2& scale, float angle, const Vec2& offset) {
1666  setTexture(texture); setColor(color);
1667  fill(poly, origin, scale, angle, offset);
1668  }
1669 
1703  void draw(const std::shared_ptr<Texture>& texture, const Poly2& poly,
1704  const Vec2& origin, const Mat4& transform) {
1705  setTexture(texture); setColor(Color4::WHITE);
1706  fill(poly, origin, transform);
1707  }
1708 
1743  void draw(const std::shared_ptr<Texture>& texture, Color4 color, const Poly2& poly,
1744  const Vec2& origin, const Mat4& transform) {
1745  setTexture(texture); setColor(color);
1746  fill(poly, origin, transform);
1747  }
1748 
1782  void draw(const std::shared_ptr<Texture>& texture, const Poly2& poly,
1783  const Vec2& origin, const Affine2& transform) {
1784  setTexture(texture); setColor(Color4::WHITE);
1785  fill(poly, origin, transform);
1786  }
1787 
1822  void draw(const std::shared_ptr<Texture>& texture, Color4 color, const Poly2& poly,
1823  const Vec2& origin, const Affine2& transform) {
1824  setTexture(texture); setColor(color);
1825  fill(poly, origin, transform);
1826  }
1827 
1828 #pragma mark -
1829 #pragma mark Internal Helpers
1830 private:
1839  void setCommand(GLenum command);
1840 
1849  GLenum getCommand() const { return _command; }
1850 
1861  bool validateBuffer(GLuint buffer, const char* message);
1862 
1874  unsigned int prepare(const Rect& rect, bool solid);
1875 
1887  unsigned int prepare(const Poly2& poly, bool solid);
1888 
1906  unsigned int prepare(const Vertex2* vertices, unsigned int vsize, unsigned int voffset,
1907  const unsigned short* indices, unsigned int isize, unsigned int ioffset,
1908  bool solid, bool tint = true);
1909 
1910 };
1911 
1912 }
1913 
1914 #endif /* __CU_SPRITE_BATCH_H__ */
void setBlendFunc(GLenum srcFactor, GLenum dstFactor)
void setColor(Color4 color)
Definition: CUSpriteBatch.h:337
Definition: CUSpriteBatch.h:78
Definition: CUPoly2.h:115
void fill(const std::vector< Vertex2 > &vertices, const std::vector< unsigned short > &indices, const Mat4 &transform, bool tint=true)
Definition: CUSpriteBatch.h:764
GLenum getSourceBlendFactor() const
Definition: CUSpriteBatch.h:436
Definition: CUVec2.h:61
void draw(const std::shared_ptr< Texture > &texture, Color4 color, const Rect &bounds, const Vec2 &origin, const Mat4 &transform)
Definition: CUSpriteBatch.h:1425
Definition: CUAffine2.h:63
void draw(const std::shared_ptr< Texture > &texture, Color4 color, const Rect &bounds)
Definition: CUSpriteBatch.h:1240
unsigned int getVerticesDrawn() const
Definition: CUSpriteBatch.h:298
bool init(std::shared_ptr< SpriteShader > shader)
Definition: CUSpriteBatch.h:188
static std::shared_ptr< SpriteBatch > alloc()
Definition: CUSpriteBatch.h:245
static std::shared_ptr< SpriteBatch > alloc(unsigned int capacity)
Definition: CUSpriteBatch.h:267
static const std::shared_ptr< Texture > & getBlankTexture()
void draw(const std::shared_ptr< Texture > &texture, const Rect &bounds, const Vec2 &origin, const Affine2 &transform)
Definition: CUSpriteBatch.h:1486
unsigned int getCallsMade() const
Definition: CUSpriteBatch.h:307
void draw(const std::shared_ptr< Texture > &texture, const Poly2 &poly, const Vec2 &origin, const Mat4 &transform)
Definition: CUSpriteBatch.h:1703
static const Color4 WHITE
Definition: CUColor4.h:1126
void begin(const Mat4 &perspective)
Definition: CUSpriteBatch.h:498
bool isReady() const
Definition: CUSpriteBatch.h:279
void draw(const std::shared_ptr< Texture > &texture, Color4 color, const Rect &bounds, const Vec2 &origin, const Affine2 &transform)
Definition: CUSpriteBatch.h:1510
void draw(const std::shared_ptr< Texture > &texture, Color4 color, const Rect &bounds, const Vec2 &origin, const Vec2 &scale, float angle, const Vec2 &offset)
Definition: CUSpriteBatch.h:1341
void fill(const Rect &rect)
void draw(const std::shared_ptr< Texture > &texture, Color4 color, const Poly2 &poly, const Vec2 &offset)
Definition: CUSpriteBatch.h:1578
void setShader(const std::shared_ptr< SpriteShader > &shader)
const std::shared_ptr< Texture > & getTexture() const
Definition: CUSpriteBatch.h:373
Definition: CUVertex.h:46
Color4 getColor() const
Definition: CUSpriteBatch.h:347
void fill(const std::vector< Vertex2 > &vertices, const std::vector< unsigned short > &indices, const Affine2 &transform, bool tint=true)
Definition: CUSpriteBatch.h:789
Definition: CURect.h:45
void draw(const std::shared_ptr< Texture > &texture, Color4 color, const Poly2 &poly, const Vec2 &origin, const Mat4 &transform)
Definition: CUSpriteBatch.h:1743
void draw(const std::shared_ptr< Texture > &texture, const Rect &bounds, const Vec2 &origin, const Vec2 &scale, float angle, const Vec2 &offset)
Definition: CUSpriteBatch.h:1313
void draw(const std::shared_ptr< Texture > &texture, const Rect &bounds, const Vec2 &origin, const Mat4 &transform)
Definition: CUSpriteBatch.h:1401
void setTexture(const std::shared_ptr< Texture > &texture)
const Mat4 & getPerspective() const
Definition: CUSpriteBatch.h:406
void outline(const Rect &rect)
bool isDrawing() const
Definition: CUSpriteBatch.h:289
void setBlendEquation(GLenum equation)
void outline(const std::vector< Vertex2 > &vertices, const std::vector< unsigned short > &indices, const Affine2 &transform, bool tint=true)
Definition: CUSpriteBatch.h:1124
void draw(const std::shared_ptr< Texture > &texture, Color4 color, const Poly2 &poly, const Vec2 &origin, const Vec2 &scale, float angle, const Vec2 &offset)
Definition: CUSpriteBatch.h:1664
~SpriteBatch()
Definition: CUSpriteBatch.h:151
void draw(const std::shared_ptr< Texture > &texture, const Rect &bounds)
Definition: CUSpriteBatch.h:1224
Definition: CUColor4.h:1104
void draw(const std::shared_ptr< Texture > &texture, Color4 color, const Poly2 &poly, const Vec2 &origin, const Affine2 &transform)
Definition: CUSpriteBatch.h:1822
void draw(const std::shared_ptr< Texture > &texture, const Poly2 &poly, const Vec2 &origin, const Vec2 &scale, float angle, const Vec2 &offset)
Definition: CUSpriteBatch.h:1620
GLenum getBlendEquation() const
Definition: CUSpriteBatch.h:474
void outline(const std::vector< Vertex2 > &vertices, const std::vector< unsigned short > &indices, const Mat4 &transform, bool tint=true)
Definition: CUSpriteBatch.h:1099
Definition: CUAnimationNode.h:52
const std::shared_ptr< SpriteShader > & getShader() const
Definition: CUSpriteBatch.h:325
Definition: CUMat4.h:92
void setPerspective(const Mat4 &perspective)
void draw(const std::shared_ptr< Texture > &texture, const Vec2 &position)
GLenum getDestinationBlendFactor() const
Definition: CUSpriteBatch.h:447
void draw(const std::shared_ptr< Texture > &texture, const Poly2 &poly, const Vec2 &origin, const Affine2 &transform)
Definition: CUSpriteBatch.h:1782
void draw(const std::shared_ptr< Texture > &texture, const Poly2 &poly, const Vec2 &offset)
Definition: CUSpriteBatch.h:1544