Browse Source

make everything work with proper matrix stuff

feature/replace-renderer
Martin Dørum 3 years ago
parent
commit
b04d30022a

+ 9
- 2
core.mod/src/entities/PlayerEntity.cc View File

} }


void PlayerEntity::draw(const Swan::Context &ctx, Cygnet::Renderer &rnd) { void PlayerEntity::draw(const Swan::Context &ctx, Cygnet::Renderer &rnd) {
// body_.outline(win); TODO
anims_[(int)state_].draw(body_.pos - Swan::Vec2(0.2, 0.1), rnd);
Cygnet::Mat3gf mat;

// Currently, there is no sprite for running left.
// Running left is just running right but flipped.
if (state_ == State::RUNNING_L) {
mat.translate({-0.5, 0}).scale({-1, 1}).translate({0.5, 0});
}

anims_[(int)state_].draw(rnd, mat.translate(body_.pos));
} }


void PlayerEntity::update(const Swan::Context &ctx, float dt) { void PlayerEntity::update(const Swan::Context &ctx, float dt) {

+ 1
- 3
core.mod/src/entities/PlayerEntity.h View File

PhysicsEntity(SIZE), PhysicsEntity(SIZE),
anims_{ anims_{
Swan::Animation(ctx.world.getSprite("core::entity/player-still"), 0.8), Swan::Animation(ctx.world.getSprite("core::entity/player-still"), 0.8),
Swan::Animation(
ctx.world.getSprite("core::entity/player-running"),
1, Cygnet::Mat3gf{}.scale({-1, 1}).translate({1, 0})),
Swan::Animation(ctx.world.getSprite("core::entity/player-running"), 1),
Swan::Animation(ctx.world.getSprite("core::entity/player-running"), 1), Swan::Animation(ctx.world.getSprite("core::entity/player-running"), 1),
} {} } {}



+ 1
- 1
include/swan-common/Matrix3.h View File

#pragma once #pragma once


#include <iostream>
#include <ostream>
#include <cmath> #include <cmath>
#include <array> #include <array>



+ 0
- 11
libcygnet/include/cygnet/Renderer.h View File



void drawChunk(RenderChunk chunk, SwanCommon::Vec2 pos); void drawChunk(RenderChunk chunk, SwanCommon::Vec2 pos);
void drawSprite(RenderSprite sprite, Mat3gf mat, int y = 0); void drawSprite(RenderSprite sprite, Mat3gf mat, int y = 0);
void drawSprite(RenderSprite sprite, SwanCommon::Vec2 pos, int y = 0);
void drawSpriteFlipped(RenderSprite chunk, SwanCommon::Vec2 pos, int y = 0);


void draw(const RenderCamera &cam); void draw(const RenderCamera &cam);


drawSprites_.push_back({mat, frame, sprite}); drawSprites_.push_back({mat, frame, sprite});
} }


inline void Renderer::drawSprite(RenderSprite sprite, SwanCommon::Vec2 pos, int frame) {
drawSprites_.push_back({Mat3gf{}.translate(pos), frame, sprite});
}

inline void Renderer::drawSpriteFlipped(RenderSprite sprite, SwanCommon::Vec2 pos, int frame) {
// TODO: Translate X by sprite.scale.x?
drawSprites_.push_back({Mat3gf{}.translate(pos).scale({-1, 1}), frame, sprite});
}

} }

+ 5
- 4
libcygnet/src/Renderer.cc View File



GLint camera = uniformLoc("camera"); GLint camera = uniformLoc("camera");
GLint transform = uniformLoc("transform"); GLint transform = uniformLoc("transform");
GLint frameSize = uniformLoc("frameSize");
GLint frameInfo = uniformLoc("frameInfo"); GLint frameInfo = uniformLoc("frameInfo");
GLint vertex = attribLoc("vertex"); GLint vertex = attribLoc("vertex");
GLint tex = uniformLoc("tex"); GLint tex = uniformLoc("tex");
// Make the matrix translate to { -camX, -camY }, fix up the aspect ratio, // Make the matrix translate to { -camX, -camY }, fix up the aspect ratio,
// flip the Y axis so that positive Y direction is down, and scale according to zoom. // flip the Y axis so that positive Y direction is down, and scale according to zoom.
float ratio = (float)cam.size.y / (float)cam.size.x; float ratio = (float)cam.size.y / (float)cam.size.x;
camMat.translate(cam.pos.scale(-ratio, 1) * cam.zoom);
camMat.scale({ cam.zoom * ratio, -cam.zoom });
camMat.translate(-cam.pos);
camMat.scale({cam.zoom * ratio, -cam.zoom});


auto &chunkProg = state_->chunkProg; auto &chunkProg = state_->chunkProg;
auto &spriteProg = state_->spriteProg; auto &spriteProg = state_->spriteProg;


glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
for (auto [mat, frame, sprite]: drawSprites_) { for (auto [mat, frame, sprite]: drawSprites_) {
mat.scale(sprite.scale);
glUniformMatrix3fv(spriteProg.transform, 1, GL_TRUE, mat.data()); glUniformMatrix3fv(spriteProg.transform, 1, GL_TRUE, mat.data());
glUniform3f(spriteProg.frameInfo, sprite.scale.y, sprite.frameCount, frame);
glUniform2f(spriteProg.frameSize, sprite.scale.x, sprite.scale.y);
glUniform2f(spriteProg.frameInfo, sprite.frameCount, frame);
glBindTexture(GL_TEXTURE_2D, sprite.tex); glBindTexture(GL_TEXTURE_2D, sprite.tex);
glDrawArrays(GL_TRIANGLES, 0, 6); glDrawArrays(GL_TRIANGLES, 0, 6);
glCheck(); glCheck();

+ 6
- 5
libcygnet/src/shaders.cc View File



uniform mat3 camera; uniform mat3 camera;
uniform mat3 transform; uniform mat3 transform;
uniform vec3 frameInfo; // frame height, frame count, frame index
uniform vec2 frameSize;
uniform vec2 frameInfo; // frame count, frame index
attribute vec2 vertex; attribute vec2 vertex;
varying vec2 v_texCoord; varying vec2 v_texCoord;


// It's just an arbitrary small number, but it works as an offset to make sure // It's just an arbitrary small number, but it works as an offset to make sure
// neighbouring parts of the atlas don't bleed into the frame we actually // neighbouring parts of the atlas don't bleed into the frame we actually
// want to draw due to (nearest neighbour) interpolation. // want to draw due to (nearest neighbour) interpolation.
float pixoffset = (1.0 - vertex.y * 2.0) / (frameInfo.x * TILE_SIZE * 16.0);
float pixoffset = (1.0 - vertex.y * 2.0) / (frameSize.y * TILE_SIZE * 16.0);
v_texCoord = vec2( v_texCoord = vec2(
vertex.x, vertex.x,
(frameInfo.x * frameInfo.z + (frameInfo.x * vertex.y)) /
(frameInfo.x * frameInfo.y) + pixoffset);
(frameSize.y * frameInfo.y + (frameSize.y * vertex.y)) /
(frameSize.y * frameInfo.x) + pixoffset);


vec3 pos = camera * transform * vec3(vertex, 1);
vec3 pos = camera * transform * vec3(vertex * frameSize, 1);
gl_Position = vec4(pos.xy, 0, 1); gl_Position = vec4(pos.xy, 0, 1);
} }
)glsl"; )glsl";

+ 8
- 3
libswan/include/swan/Animation.h View File

class Animation { class Animation {
public: public:
Animation(Cygnet::RenderSprite sprite, float interval, Cygnet::Mat3gf mat = {}): Animation(Cygnet::RenderSprite sprite, float interval, Cygnet::Mat3gf mat = {}):
sprite_(sprite), interval_(interval), timer_(interval), mat_(mat) {}
sprite_(sprite), interval_(interval), timer_(interval) {}


void tick(float dt); void tick(float dt);
void draw(const Vec2 &pos, Cygnet::Renderer &rnd);
void reset(); void reset();
void draw(Cygnet::Renderer &rnd, Cygnet::Mat3gf mat);


private: private:
Cygnet::RenderSprite sprite_; Cygnet::RenderSprite sprite_;
float interval_; float interval_;
float timer_; float timer_;
Cygnet::Mat3gf mat_;
int frame_ = 0; int frame_ = 0;
}; };


inline void Animation::draw(Cygnet::Renderer &rnd, Cygnet::Mat3gf mat) {
rnd.drawSprite(sprite_, mat, frame_);
} }

}



+ 0
- 4
libswan/src/Animation.cc View File

} }
} }


void Animation::draw(const Vec2 &pos, Cygnet::Renderer &rnd) {
rnd.drawSprite(sprite_, Cygnet::Mat3gf(mat_).translate(pos), frame_);
}

void Animation::reset() { void Animation::reset() {
timer_ = interval_; timer_ = interval_;
frame_ = 0; frame_ = 0;

+ 1
- 1
libswan/src/World.cc View File

for (auto &plane: planes_) for (auto &plane: planes_)
plane->update(dt); plane->update(dt);


game_->cam_.pos = player_->pos + Vec2{0.5, 0.5}; // - (win.getSize() / 2) + (player_->size / 2); TODO
game_->cam_.pos = player_->pos + Vec2{0.5, 0.5};
} }


void World::tick(float dt) { void World::tick(float dt) {

+ 1
- 1
src/cygnet-test.cc View File



rnd.drawChunk(chunk, {0, 0}); rnd.drawChunk(chunk, {0, 0});


rnd.drawSprite(playerSprite, {x, y}, (int)animAcc % 2);
rnd.drawSprite(playerSprite, Cygnet::Mat3gf{}.translate({x, y}), (int)animAcc % 2);
cam.pos = {x + 0.5f, y + 0.5f}; cam.pos = {x + 0.5f, y + 0.5f};


win.clear(); win.clear();

Loading…
Cancel
Save