Browse Source

draw rect

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

+ 5
- 1
core.mod/src/entities/PlayerEntity.cc View File

@@ -23,7 +23,11 @@ void PlayerEntity::draw(const Swan::Context &ctx, Cygnet::Renderer &rnd) {
mat.translate({-0.5, 0}).scale({-1, 1}).translate({0.5, 0});
}

anims_[(int)state_].draw(rnd, mat.translate(body_.pos));
anims_[(int)state_].draw(rnd, mat.translate(
body_.pos - Swan::Vec2{0.2, 0.1}));

rnd.drawRect(mouseTile_, {1, 1});
rnd.drawRect(body_.pos, body_.size);
}

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

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

@@ -23,10 +23,6 @@ struct RenderSprite {
int frameCount;
};

struct RenderTile {
uint16_t id;
};

struct RenderCamera {
SwanCommon::Vec2 pos = {0, 0};
SwanCommon::Vec2i size = {1, 1};
@@ -42,6 +38,7 @@ public:

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

void draw(const RenderCamera &cam);

@@ -71,12 +68,18 @@ private:
RenderSprite sprite;
};

struct DrawRect {
SwanCommon::Vec2 pos;
SwanCommon::Vec2 size;
};

SwanCommon::Vec2 winScale_ = {1, 1};

std::unique_ptr<RendererState> state_;

std::vector<DrawChunk> drawChunks_;
std::vector<DrawSprite> drawSprites_;
std::vector<DrawRect> drawRects_;
};

inline void Renderer::drawChunk(RenderChunk chunk, SwanCommon::Vec2 pos) {
@@ -87,4 +90,8 @@ inline void Renderer::drawSprite(RenderSprite sprite, Mat3gf mat, int frame) {
drawSprites_.push_back({mat, frame, sprite});
}

inline void Renderer::drawRect(SwanCommon::Vec2 pos, SwanCommon::Vec2 size) {
drawRects_.push_back({pos, size});
}

}

+ 1
- 1
libcygnet/include/cygnet/ResourceManager.h View File

@@ -48,7 +48,7 @@ public:

Renderer &rnd_;
std::unordered_map<std::string, RenderSprite> sprites_;
std::unordered_map<std::string, RenderTile> tiles_;
std::unordered_map<std::string, Renderer::TileID> tiles_;
std::vector<ResourceTileAnimation> tileAnims_;
};


+ 5
- 2
libcygnet/include/cygnet/shaders.h View File

@@ -2,10 +2,13 @@

namespace Cygnet::Shaders {

extern const char *chunkVx;
extern const char *chunkFr;

extern const char *spriteVx;
extern const char *spriteFr;

extern const char *chunkVx;
extern const char *chunkFr;
extern const char *rectVx;
extern const char *rectFr;

}

+ 69
- 0
libcygnet/src/Renderer.cc View File

@@ -73,6 +73,55 @@ struct ChunkProg: public GlProgram {
}
};

struct RectProg: public GlProgram {
template<typename... T>
RectProg(const T &... shaders): GlProgram(shaders...) { init(); }
~RectProg() { deinit(); }

GLint camera = uniformLoc("camera");
GLint pos = uniformLoc("pos");
GLint size = uniformLoc("size");
GLint vertex = attribLoc("vertex");

GLuint vbo;

static constexpr GLfloat vertexes[] = {
0.0f, 0.0f, // pos 0: top left
0.0f, 1.0f, // pos 1: bottom left
1.0f, 1.0f, // pos 2: bottom right
1.0f, 1.0f, // pos 2: bottom right
1.0f, 0.0f, // pos 3: top right
0.0f, 0.0f, // pos 0: top left
};

void enable() {
glUseProgram(id());
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(vertex, 2, GL_FLOAT, GL_FALSE, 0, (void *)0);
glEnableVertexAttribArray(vertex);
glCheck();
}

void disable() {
glDisableVertexAttribArray(vertex);
glCheck();
}

void init() {
glGenBuffers(1, &vbo);
glCheck();

glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexes), vertexes, GL_STATIC_DRAW);
glCheck();
}

void deinit() {
glDeleteBuffers(1, &vbo);
glCheck();
}
};

struct SpriteProg: public GlProgram {
template<typename... T>
SpriteProg(const T &... shaders): GlProgram(shaders...) { init(); }
@@ -131,9 +180,12 @@ struct RendererState {
GlFrShader spriteFr{Shaders::spriteFr};
GlVxShader chunkVx{Shaders::chunkVx};
GlFrShader chunkFr{Shaders::chunkFr};
GlVxShader rectVx{Shaders::rectVx};
GlFrShader rectFr{Shaders::rectFr};

SpriteProg spriteProg{spriteVx, spriteFr};
ChunkProg chunkProg{chunkVx, chunkFr};
RectProg rectProg{rectVx, rectFr};

GLuint atlasTex;
SwanCommon::Vec2 atlasTexSize;
@@ -163,6 +215,7 @@ void Renderer::draw(const RenderCamera &cam) {

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

{
chunkProg.enable();
@@ -206,6 +259,22 @@ void Renderer::draw(const RenderCamera &cam) {
drawSprites_.clear();
spriteProg.disable();
}

{
rectProg.enable();
glUniformMatrix3fv(rectProg.camera, 1, GL_TRUE, camMat.data());
glCheck();

for (auto [pos, size]: drawRects_) {
glUniform2f(rectProg.pos, pos.x, pos.y);
glUniform2f(rectProg.size, size.x, size.y);
glDrawArrays(GL_TRIANGLES, 0, 6);
glCheck();
}

drawRects_.clear();
rectProg.disable();
}
}

void Renderer::uploadTileAtlas(const void *data, int width, int height) {

+ 57
- 24
libcygnet/src/shaders.cc View File

@@ -2,6 +2,46 @@

namespace Cygnet::Shaders {

const char *chunkVx = R"glsl(
uniform mat3 camera;
uniform vec2 pos;
attribute vec2 vertex;
varying vec2 v_tileCoord;

void main() {
vec3 pos = camera * vec3(pos + vertex, 1);
gl_Position = vec4(pos.xy, 0, 1);
v_tileCoord = vertex;
}
)glsl";

const char *chunkFr = R"glsl(
precision mediump float;
#define TILE_SIZE 32.0
#define CHUNK_WIDTH 64
#define CHUNK_HEIGHT 64

varying vec2 v_tileCoord;
uniform sampler2D tileAtlas;
uniform vec2 tileAtlasSize;
uniform sampler2D tiles;

void main() {
vec2 tilePos = floor(vec2(v_tileCoord.x, v_tileCoord.y));
vec4 tileColor = texture2D(tiles, tilePos / vec2(CHUNK_WIDTH, CHUNK_HEIGHT));
float tileID = floor((tileColor.r * 256.0 + tileColor.a) * 256.0);

// 1/(TILE_SIZE*16) plays the same role here as in the sprite vertex shader.
vec2 offset = v_tileCoord - tilePos;
vec2 pixoffset = (1.0 - offset * 2.0) / (TILE_SIZE * 16.0);
vec2 atlasPos = vec2(
pixoffset.x + tileID + offset.x,
pixoffset.y + floor(tileID / tileAtlasSize.x) + offset.y);

gl_FragColor = texture2D(tileAtlas, atlasPos / tileAtlasSize);
}
)glsl";

const char *spriteVx = R"glsl(
#define TILE_SIZE 32.0

@@ -38,43 +78,36 @@ const char *spriteFr = R"glsl(
}
)glsl";

const char *chunkVx = R"glsl(
const char *rectVx = R"glsl(
uniform mat3 camera;
uniform vec2 pos;
uniform vec2 size;
attribute vec2 vertex;
varying vec2 v_tileCoord;
varying vec2 v_coord;

void main() {
vec3 pos = camera * vec3(pos + vertex, 1);
vec3 pos = camera * vec3(pos + vertex * size, 1);
gl_Position = vec4(pos.xy, 0, 1);
v_tileCoord = vec2(vertex.x, vertex.y);
v_coord = vertex * size;
}
)glsl";

const char *chunkFr = R"glsl(
const char *rectFr = R"glsl(
precision mediump float;
#define TILE_SIZE 32.0
#define CHUNK_WIDTH 64
#define CHUNK_HEIGHT 64
#define THICKNESS 0.02

varying vec2 v_tileCoord;
uniform sampler2D tileAtlas;
uniform vec2 tileAtlasSize;
uniform sampler2D tiles;
varying vec2 v_coord;
uniform vec2 size;

void main() {
vec2 tilePos = floor(vec2(v_tileCoord.x, v_tileCoord.y));
vec4 tileColor = texture2D(tiles, tilePos / vec2(CHUNK_WIDTH, CHUNK_HEIGHT));
float tileID = floor((tileColor.r * 256.0 + tileColor.a) * 256.0);

// 1/(TILE_SIZE*16) plays the same role here as in the sprite vertex shader.
vec2 offset = v_tileCoord - tilePos;
vec2 pixoffset = (1.0 - offset * 2.0) / (TILE_SIZE * 16.0);
vec2 atlasPos = vec2(
pixoffset.x + tileID + offset.x,
pixoffset.y + floor(tileID / tileAtlasSize.x) + offset.y);

gl_FragColor = texture2D(tileAtlas, atlasPos / tileAtlasSize);
// TODO: This probably shouldn't be an if?
if (
v_coord.x < THICKNESS || v_coord.x > size.x - THICKNESS ||
v_coord.y < THICKNESS || v_coord.y > size.y - THICKNESS) {
gl_FragColor = vec4(0.6, 0.6, 0.6, 0.8);
} else {
gl_FragColor = vec4(0, 0, 0, 0);
}
}
)glsl";


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

@@ -308,7 +308,7 @@ void World::update(float dt) {
for (auto &plane: planes_)
plane->update(dt);

game_->cam_.pos = player_->pos + Vec2{0.5, 0.5};
game_->cam_.pos = player_->pos + player_->size / 2;
}

void World::tick(float dt) {

Loading…
Cancel
Save