@@ -20,6 +20,7 @@ struct RenderChunk { | |||
struct RenderSprite { | |||
GLuint tex; | |||
SwanCommon::Vec2 scale; | |||
int frameCount; | |||
}; | |||
struct RenderCamera { | |||
@@ -62,7 +63,7 @@ private: | |||
struct DrawSprite { | |||
Mat3gf transform; | |||
int y; | |||
int frame; | |||
RenderSprite sprite; | |||
}; | |||
@@ -76,16 +77,16 @@ inline void Renderer::drawChunk(RenderChunk chunk, SwanCommon::Vec2 pos) { | |||
draw_chunks_.emplace_back(pos, chunk); | |||
} | |||
inline void Renderer::drawSprite(RenderSprite sprite, Mat3gf mat, int y) { | |||
draw_sprites_.emplace_back(mat, y, sprite); | |||
inline void Renderer::drawSprite(RenderSprite sprite, Mat3gf mat, int frame) { | |||
draw_sprites_.emplace_back(mat, frame, sprite); | |||
} | |||
inline void Renderer::drawSprite(RenderSprite sprite, SwanCommon::Vec2 pos, int y) { | |||
draw_sprites_.emplace_back(Mat3gf{}.translate(pos), y, sprite); | |||
inline void Renderer::drawSprite(RenderSprite sprite, SwanCommon::Vec2 pos, int frame) { | |||
draw_sprites_.emplace_back(Mat3gf{}.translate(pos), frame, sprite); | |||
} | |||
inline void Renderer::drawSpriteFlipped(RenderSprite sprite, SwanCommon::Vec2 pos, int y) { | |||
draw_sprites_.emplace_back(Mat3gf{}.translate(pos).scale({ -1, 1 }), y, sprite); | |||
inline void Renderer::drawSpriteFlipped(RenderSprite sprite, SwanCommon::Vec2 pos, int frame) { | |||
draw_sprites_.emplace_back(Mat3gf{}.translate(pos).scale({ -1, 1 }), frame, sprite); | |||
} | |||
} |
@@ -80,6 +80,7 @@ struct SpriteProg: public GlProgram { | |||
GLint camera = uniformLoc("camera"); | |||
GLint transform = uniformLoc("transform"); | |||
GLint frameInfo = uniformLoc("frameInfo"); | |||
GLint vertex = attribLoc("vertex"); | |||
GLint tex = uniformLoc("tex"); | |||
@@ -185,11 +186,10 @@ void Renderer::draw(const RenderCamera &cam) { | |||
glCheck(); | |||
glActiveTexture(GL_TEXTURE0); | |||
for (auto [mat, y, sprite]: draw_sprites_) { | |||
// TODO: Handle 'y' here | |||
for (auto [mat, frame, sprite]: draw_sprites_) { | |||
mat.scale(sprite.scale); | |||
glUniformMatrix3fv(spriteProg.transform, 1, GL_TRUE, mat.data()); | |||
glUniform3f(spriteProg.frameInfo, sprite.scale.y, sprite.frameCount, frame); | |||
glBindTexture(GL_TEXTURE_2D, sprite.tex); | |||
glDrawArrays(GL_TRIANGLES, 0, 6); | |||
glCheck(); | |||
@@ -294,6 +294,7 @@ RenderSprite Renderer::createSprite(void *data, int width, int height, int fh) { | |||
sprite.scale = { | |||
(float)width / SwanCommon::TILE_SIZE, | |||
(float)fh / SwanCommon::TILE_SIZE }; | |||
sprite.frameCount = height / fh; | |||
glGenTextures(1, &sprite.tex); | |||
glCheck(); | |||
@@ -5,13 +5,18 @@ namespace Cygnet::Shaders { | |||
const char *spriteVx = R"glsl( | |||
uniform mat3 camera; | |||
uniform mat3 transform; | |||
uniform vec3 frameInfo; // frame height, frame count, frame index | |||
attribute vec2 vertex; | |||
varying vec2 v_texCoord; | |||
void main() { | |||
v_texCoord = vec2( | |||
vertex.x, | |||
(frameInfo.x * frameInfo.z + (frameInfo.x * vertex.y)) / | |||
(frameInfo.x * frameInfo.y)); | |||
vec3 pos = camera * transform * vec3(vertex, 1); | |||
gl_Position = vec4(pos.xy, 0, 1); | |||
v_texCoord = vec2(vertex.x, vertex.y); | |||
} | |||
)glsl"; | |||