Skip to content

Commit

Permalink
add sprite renderer
Browse files Browse the repository at this point in the history
  • Loading branch information
Jerboa-app committed Oct 31, 2023
1 parent d95c345 commit 768596a
Show file tree
Hide file tree
Showing 10 changed files with 290 additions and 84 deletions.
54 changes: 0 additions & 54 deletions include/jGL/OpenGL/glSprite.h

This file was deleted.

84 changes: 84 additions & 0 deletions include/jGL/OpenGL/glSpriteRenderer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#ifndef GLSPRITERENDERER
#define GLSPRITERENDERER

#include <jGL/OpenGL/Shader/glShader.h>
#include <jGL/OpenGL/gl.h>
#include <jGL/spriteRenderer.h>

namespace jGL::GL
{
class glSpriteRenderer : public SpriteRenderer
{
public:

glSpriteRenderer(size_t sizeHint)
: SpriteRenderer(sizeHint)
{
offsets = std::vector<float>(sizeHint*4+padSprites*4,0.0f);
initGL();
defaultShader = std::make_shared<glShader>(vertexShader, fragmentShader);
defaultShader->use();
}

~glSpriteRenderer()
{
freeGL();
}

void draw(std::shared_ptr<Shader> shader, std::vector<SpriteId> ids);
void draw(std::vector<SpriteId> ids) { draw(defaultShader, ids); }

private:

GLuint vao, a_position, a_offset;

float quad[6*4] =
{
// positions / texture coords
0.5f, 0.5f, 1.0f, 1.0f, // top right
0.5f, -0.5f, 1.0f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, 0.0f, // bottom left
-0.5f, 0.5f, 0.0f, 1.0f, // top left
-0.5f, -0.5f, 0.0f, 0.0f, // bottom left
0.5f, 0.5f, 1.0f, 1.0f // top right
};

std::vector<float> offsets; // offset x, y, theta, scale

size_t padSprites = 64;

void initGL();
void freeGL();

std::shared_ptr<Shader> defaultShader;

const char * vertexShader =
"#version " GLSL_VERSION "\n"
"precision lowp float;\n"
"in vec4 a_position;\n"
"in vec4 a_offset;\n"
"uniform mat4 proj;\n"
"out vec2 texCoord;\n"
"void main(void){"
"vec2 pos = a_position.xy*a_offset.w;\n"
"float ct = cos(a_offset.z); float st = sin(a_offset.z);\n"
"mat2 rot = mat2(ct, -st, st, ct);\n"
"pos = rot*pos + a_offset.xy;\n"
"gl_Position = proj*vec4(pos,0.0,1.0);\n"
"texCoord = a_position.zw;\n"
"}";

const char * fragmentShader =
"#version " GLSL_VERSION "\n"
"precision lowp float;\n"
"uniform sampler2D sampler;\n"
"in vec2 texCoord;\n"
"out vec4 colour;\n"
"void main(void){\n"
"colour = texture(sampler, texCoord);\n"
"}";

};
}

#endif /* GLSPRITERENDERER */
2 changes: 2 additions & 0 deletions include/jGL/Vulkan/Shader/vkShader.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ namespace jGL::Vulkan

std::vector<VkPipelineShaderStageCreateInfo> shaderStage() const;

void use(){}

private:

const VkDevice & device;
Expand Down
25 changes: 0 additions & 25 deletions include/jGL/Vulkan/vkSprite.h

This file was deleted.

22 changes: 22 additions & 0 deletions include/jGL/Vulkan/vkSpriteRenderer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#ifndef VKSPRITERENDERER
#define VKSPRITERENDERER

#include <jGL/Vulkan/Device/device.h>
#include <jGL/spriteRenderer.h>

namespace jGL::Vulkan
{
class vkSpriteRenderer : public SpriteRenderer
{
public:

vkSpriteRenderer(size_t sizeHint)
: SpriteRenderer(sizeHint)
{}

void draw(glm::mat4 proj) {TODO("jGL::Vulkan::vkSprite::draw");}

};
}

#endif /* VKSPRITERENDERER */
2 changes: 2 additions & 0 deletions include/jGL/shader.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ namespace jGL
return v;
}

virtual void use() = 0;

protected:

std::string vertex;
Expand Down
16 changes: 11 additions & 5 deletions include/jGL/sprite.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,29 @@ namespace jGL
{
public:

Sprite(std::shared_ptr<Texture> tex, Transform tra)
Sprite()
{}

Sprite
(
std::shared_ptr<Texture> tex,
Transform tra
)
: texture(tex), transform(tra)
{}

virtual void update(Transform tra) { transform = tra; }

virtual void draw(glm::vec4 projection) = 0;

void setTexture(std::shared_ptr<Texture> tex) { texture = tex; }

const Transform & getTransform() const { return transform; }

protected:

std::shared_ptr<Texture> texture;

Transform transform;

glm::vec4 model;

};
}

Expand Down
41 changes: 41 additions & 0 deletions include/jGL/spriteRenderer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#ifndef SPRITERENDERER
#define SPRITERENDERER

#include <jGL/sprite.h>
#include <jGL/shader.h>

#include <unordered_map>
#include <string>
#include <iterator>
#include <vector>

namespace jGL
{
typedef std::string SpriteId;

class SpriteRenderer
{

public:

SpriteRenderer(size_t sizeHint = 64)
{
sprites.reserve(sizeHint);
}

virtual void update(Transform tra, SpriteId id);

virtual void setTexture(std::shared_ptr<Texture> tex, SpriteId id);

virtual void draw(std::shared_ptr<Shader> shader, std::vector<SpriteId> ids) = 0;

virtual void add(Sprite s, SpriteId id) { sprites[id] = s;}

protected:

std::unordered_map<SpriteId, Sprite> sprites;

};
}

#endif /* SPRITERENDERER */
108 changes: 108 additions & 0 deletions src/jGL/OpenGL/glSpriteRenderer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#include <jGL/OpenGL/glSpriteRenderer.h>

namespace jGL::GL
{
void glSpriteRenderer::draw(std::shared_ptr<Shader> shader, std::vector<SpriteId> ids)
{
uint32_t n = ids.size();

if (offsets.size() < 4*n)
{
offsets.resize(4*n+padSprites*4);
freeGL();
initGL();
}

for (unsigned i = 0; i < n; i++)
{
const Transform & trans = sprites[ids[i]].getTransform();
offsets[i*4] = trans.x;
offsets[i*4+1] = trans.y;
offsets[i*4+2] = trans.theta;
offsets[i*4+3] = trans.scale;
}

shader->use();

glBindVertexArray(vao);

glBufferSubData
(
GL_ARRAY_BUFFER,
0,
4*n*sizeof(float),
&offsets[0]
);

glDrawArraysInstanced(GL_TRIANGLES, 0, 6, n);

glBindVertexArray(0);

}

void glSpriteRenderer::freeGL()
{
glDeleteBuffers(1, &a_position);
glDeleteBuffers(1, &a_offset);
glDeleteVertexArrays(1, &vao);
}

void glSpriteRenderer::initGL()
{
glGenVertexArrays(1, &vao);
glGenBuffers(1, &a_position);
glGenBuffers(1, &a_offset);

glBindVertexArray(vao);

glBindBuffer(GL_ARRAY_BUFFER, a_position);

glBufferData
(
GL_ARRAY_BUFFER,
sizeof(quad),
&quad[0],
GL_STATIC_DRAW
);
glEnableVertexAttribArray(0);
glVertexAttribPointer
(
0,
4,
GL_FLOAT,
false,
4*sizeof(float),
0
);
glVertexAttribDivisor(0,0);

glBindBuffer(GL_ARRAY_BUFFER, 0);

glBindBuffer(GL_ARRAY_BUFFER, a_offset);

glBufferData
(
GL_ARRAY_BUFFER,
sizeof(float)*offsets.size(),
offsets.data(),
GL_DYNAMIC_DRAW
);

glEnableVertexAttribArray(1);
glVertexAttribPointer
(
1,
4,
GL_FLOAT,
false,
4*sizeof(float),
0
);
glVertexAttribDivisor(1, 1);

glBindBuffer(GL_ARRAY_BUFFER, 0);


glBindVertexArray(0);
}
}
Loading

0 comments on commit 768596a

Please sign in to comment.