JNGL
Easy to use cross-platform 2D game library
Loading...
Searching...
No Matches
Sprite.hpp
Go to the documentation of this file.
1// Copyright 2012-2026 Jan Niklas Hasse <jhasse@bixense.com>
2// For conditions of distribution and use, see copyright notice in LICENSE.txt
5#pragma once
6
7#include "Drawable.hpp"
8#include "Finally.hpp"
9#include "Rgb.hpp"
10#include "Rgba.hpp"
11#include "ShaderProgram.hpp"
12#include "TextureFilter.hpp"
13#include "Vec2.hpp"
14
15#include <future>
16#include <optional>
17#include <vector>
18
19namespace jngl {
20
21class ImageData;
22class Mat3;
23class Texture;
24struct Vertex;
25
27class Sprite {
28public:
29 enum class LoadType : uint8_t {
30 NORMAL,
31 HALF,
32 THREADED,
33 };
34
58 explicit Sprite(const ImageData&, double scale,
59 std::optional<std::string_view> filename = std::nullopt, bool mipmap = false);
60
65 Sprite(const uint8_t* bytes, size_t width, size_t height, bool mipmap = false);
66
69 explicit Sprite(const std::string& filename, LoadType loadType = LoadType::NORMAL,
70 bool mipmap = false);
71
74 explicit Sprite(const std::string& filename, bool mipmap);
75
77 void step();
78
80 void draw() const;
81
99 class Loader {
100 public:
109 explicit Loader(std::string filename, bool mipmap = false) noexcept;
110
119 ~Loader() noexcept;
120
124 std::shared_ptr<Sprite> shared() const;
125
129 operator bool() const; // NOLINT
130
134 Sprite* operator->() const;
135
136 private:
137 mutable std::future<std::unique_ptr<ImageData>> imageDataFuture;
138 std::string filename;
139 bool mipmap = false;
140 };
141
145 void draw(const Mat3& modelview, const ShaderProgram* shaderProgram = nullptr) const;
146 void draw(Mat3 modelview, Alpha, const ShaderProgram* shaderProgram = nullptr) const;
147
152 void draw(Mat3 modelview, Rgba color) const;
153
171 void drawLerped(Mat3 modelview, Rgb color, float red, float green, float blue, Alpha) const;
172
176 void draw(const ShaderProgram* shaderProgram) const;
177
179 class Batch {
180 struct Impl;
182 friend class Sprite;
183
184 public:
186 ~Batch();
187 Batch(Batch&&) = default;
188 Batch& operator=(Batch&&) = default;
189 Batch(const Batch&) = delete;
190 Batch& operator=(const Batch&) = delete;
191
193 void draw(Mat3 modelview) const;
194 };
195
212 Batch batch(const ShaderProgram* shaderProgram = nullptr) const;
213
224 [[deprecated("Scale the modelview matrix instead using jngl::Mat3::scale")]]
225 void drawScaled(float xfactor, float yfactor,
226 const ShaderProgram* shaderProgram = nullptr) const;
227
229 [[deprecated("Use new drawClipped(Vec2, Vec2) method instead")]] void
230 drawClipped(float xstart, float xend, float ystart, float yend) const;
231
233 void drawClipped(Vec2 start, Vec2 end) const;
234
237 void drawMesh(const std::vector<Vertex>& vertexes, const ShaderProgram* = nullptr) const;
238
263 void drawMesh(const Mat3& modelview, const std::vector<Vertex>& vertexes,
264 const ShaderProgram* shaderProgram = nullptr) const;
265 void drawMesh(const Mat3& modelview, const std::vector<Vertex>& vertexes, jngl::Rgba color,
266 const ShaderProgram* = nullptr) const;
267
268 void setBytes(const unsigned char*);
269
271 static const Shader& vertexShader();
272
275
276 // Position and size member variables (from Drawable)
277 Vec2 getPos() const;
278 void setPos(double x, double y);
279 template <class Vect> void setPos(Vect p) {
280 setPos(p.x, p.y);
281 }
282
283 jngl::Vec2 getCenter() const;
284 void setCenter(double x, double y);
285 template <class Vect> void setCenter(Vect c) {
286 setCenter(c.x, c.y);
287 }
288
289 double getLeft() const;
290 void setLeft(double x);
291
292 double getTop() const;
293 void setTop(double y);
294
295 double getRight() const;
296 void setRight(double x);
297
298 double getBottom() const;
299 void setBottom(double y);
300
301 double getX() const;
302 void setX(double);
303
304 double getY() const;
305 void setY(double);
306
307 Vec2 getSize() const;
308
309 float getWidth() const;
310
311 float getHeight() const;
312
313 void drawBoundingBox() const;
314
315 bool contains(jngl::Vec2 point) const;
316
320 void setTextureFilter(TextureFilter minification, TextureFilter magnification);
321
322private:
323 void enableMipmaps();
324 static void cleanUpRowPointers(std::vector<unsigned char*>& buf);
325 void loadTexture(int scaledWidth, int scaledHeight, const std::string& filename, bool halfLoad,
326 unsigned int format, const unsigned char* const* rowPointers,
327 const unsigned char* data = nullptr, bool mipmap = false);
328 Finally LoadPNG(const std::string& filename, FILE* fp, bool halfLoad, bool mipmap);
329 struct BMPHeader {
330 unsigned int dataOffset;
331 unsigned int headerSize;
332 int width;
333 int height;
334 unsigned short planes;
335 unsigned short bpp;
336 unsigned int compression;
337 unsigned int dataSize;
338 };
339 Finally LoadBMP(const std::string& filename, FILE* fp, bool halfLoad, bool mipmap);
340#ifndef NOWEBP
341 Finally LoadWebP(const std::string& filename, FILE* file, bool halfLoad, bool mipmap);
342#endif
343
345
346 // Position in screen coordinates
347 Vec2 position;
348
349 // Width and height in pixel, NOT screen coordinates
350 float width = 0;
351 float height = 0;
352};
353
354void draw(const std::string& filename, double x, double y);
355
356template <class Vect> void draw(const std::string& filename, Vect pos) {
357 draw(filename, pos.x, pos.y);
358}
359
363Finally load(const std::string& filename);
364
365void unload(const std::string& filename);
366
367void unloadAll();
368
369void drawClipped(const std::string& filename, double xposition, double yposition, float xstart,
370 float xend, float ystart, float yend);
371
372void setSpriteColor(unsigned char red, unsigned char green, unsigned char blue,
373 unsigned char alpha);
374
375void setSpriteColor(unsigned char red, unsigned char green, unsigned char blue);
376
378void setSpriteColor(Rgb);
379
381void setSpriteColor(Rgba);
382
383void setSpriteAlpha(unsigned char alpha);
384
385void pushSpriteAlpha(unsigned char alpha = 255);
386
387void popSpriteAlpha();
388
389int getWidth(const std::string& filename);
390
391int getHeight(const std::string& filename);
392
393#if __cplusplus >= 201703L
394[[nodiscard]]
395#endif
396Finally disableBlending();
397
398Finally drawOnlyIntoAlphaChannel();
399
401enum class BlendMode : uint8_t {
407 Composite,
408
412
414 Additive,
415
418
421 Multiply,
422
424 Screen,
425};
426
431#if __cplusplus >= 201703L
432[[nodiscard]]
433#endif
435
436} // namespace jngl
Contains jngl::Drawable class.
Contains jngl::Finally class.
Contains jngl::Rgb class.
Contains jngl::Rgba class.
Contains jngl::ShaderProgram class.
Contains jngl::TextureFilter.
Contains jngl::Vec2 class.
Object representing only the Alpha Channel in an RGBA color, 0 meaning invisible, 1 fully visible.
Definition Alpha.hpp:12
Helper class which calls a function when being destroyed.
Definition Finally.hpp:22
Containing the pixel data of an image file.
Definition ImageData.hpp:14
3x3 matrix
Definition Mat3.hpp:18
Object representing a RGB color, new version of jngl::Color (which will be deprecated in the future)
Definition Rgb.hpp:21
Object representing a RGBA color.
Definition Rgba.hpp:22
Linked vertex and fragment shaders.
Fragment or vertex GLSL shader.
Definition Shader.hpp:13
While this object is alive, don't do any other draw calls. Should never outlive its Sprite.
Definition Sprite.hpp:179
void draw(Mat3 modelview) const
Draws the Sprite which created this Batch centered using modelview.
Use this class to load a Sprite asynchronously.
Definition Sprite.hpp:99
Loader(std::string filename, bool mipmap=false) noexcept
Starts a thread to load filename and returns instantly.
std::shared_ptr< Sprite > shared() const
Blocks until the Sprite has been loaded and returns a non-nullptr std::shared_ptr.
Higher-level representation of an image.
Definition Sprite.hpp:27
void setTextureFilter(TextureFilter minification, TextureFilter magnification)
Sets how the texture is sampled when the sprite is drawn smaller than its pixel size (minification) a...
void drawClipped(Vec2 start, Vec2 end) const
Draw a cutout of the sprite. drawClipped({0, 0}, {1, 1}) would draw it normally.
void draw() const
Draws the Sprite, centered by default.
Batch batch(const ShaderProgram *shaderProgram=nullptr) const
Allows to draw the Sprite multiple times at different locations in an efficient way.
void drawScaled(float xfactor, float yfactor, const ShaderProgram *shaderProgram=nullptr) const
Draws the image scaled by xfactor and yfactor
Sprite(const std::string &filename, LoadType loadType=LoadType::NORMAL, bool mipmap=false)
std::shared_ptr< Finally > loader
Function which actually loads the sprite.
Definition Sprite.hpp:274
void drawClipped(float xstart, float xend, float ystart, float yend) const
void drawMesh(const std::vector< Vertex > &vertexes, const ShaderProgram *=nullptr) const
Draws a list of triangles with the sprite's texture on it using the global modelview from jngl::model...
Sprite(const std::string &filename, bool mipmap)
Sprite(const ImageData &, double scale, std::optional< std::string_view > filename=std::nullopt, bool mipmap=false)
Creates a Sprite from ImageData and scales it by scale.
void step()
Does nothing.
static const Shader & vertexShader()
Returns a reference to JNGL's default vertex shader used to draw textures.
Sprite(const uint8_t *bytes, size_t width, size_t height, bool mipmap=false)
The sprite data is stored as packed RGBA bytes in an array, where the size of the array needs to be c...
void drawLerped(Mat3 modelview, Rgb color, float red, float green, float blue, Alpha) const
Draws the Sprite with each color channel linearly interpolated towards color.
void drawMesh(const Mat3 &modelview, const std::vector< Vertex > &vertexes, const ShaderProgram *shaderProgram=nullptr) const
Draws a list of triangles with the sprite's texture on it, ignores the Sprite's position.
Two-dimensional vector.
Definition Vec2.hpp:36
JNGL's main namespace.
BlendMode
How what's drawn is blended with what's already there, see setBlendMode()
Definition Sprite.hpp:401
@ Composite
Colours are blended by their alpha as usual, but alpha is composited too, rather than added up as it ...
@ PremultipliedAdditive
BlendMode::Additive for colors that already have their alpha multiplied in.
@ Screen
The opposite of Multiply: lightens what's there by the colors.
@ Premultiplied
For colours that already have their alpha multiplied in, e.g.
@ Additive
Adds the colors, by their alpha, to what's there, e.g. for something that glows.
@ Multiply
Multiplies what's there with the colors, darkening it, e.g.
Finally setBlendMode(BlendMode)
Sets how what's drawn is blended with what's already there, until the returned Finally object is dest...
void scale(double factor)
Multiplies the global ModelView matrix by a scaling matrix.
Finally load(const std::string &filename)
Starts a thread to load filename and returns a Finally which will join it.
TextureFilter
How a texture is sampled when it's drawn bigger or smaller than its pixel size.
jngl::Mat3 modelview()
Returns a copy of the global ModelView matrix.