Browse Source

cave background stuff

opengl-renderer-broken
Martin Dørum 4 years ago
parent
commit
056579e6be

+ 2
- 1
core.mod/CMakeLists.txt View File

@@ -14,7 +14,8 @@ set(assets
assets/tiles/stone.png
assets/tiles/dirt.png
assets/tiles/leaves.png
assets/tiles/tree-trunk.png)
assets/tiles/tree-trunk.png
assets/misc/background-cave.png)
foreach(a ${assets})
configure_file("${a}" "${a}" COPYONLY)
endforeach(a)

BIN
core.mod/assets-src/misc/background-cave.xcf View File


BIN
core.mod/assets-src/tiles/air.xcf View File


BIN
core.mod/assets/misc/background-cave-2.png View File


BIN
core.mod/assets/misc/background-cave.png View File


BIN
core.mod/assets/tiles/air.png View File


+ 39
- 0
core.mod/src/WGDefault.cc View File

@@ -1,5 +1,7 @@
#include "WGDefault.h"

#include <algorithm>

static int grassLevel(const siv::PerlinNoise &perlin, int x) {
return (int)(perlin.noise(x / 50.0, 0) * 13);
}
@@ -8,6 +10,43 @@ static int stoneLevel(const siv::PerlinNoise &perlin, int x) {
return (int)(perlin.noise(x / 50.0, 10) * 10) + 10;
}

void WGDefault::drawBackground(const Swan::Context &ctx, Swan::Win &win, Swan::Vec2 pos) {
int texmin = 10;
int texmax = 20;

if (pos.y > texmin) {
SDL_Texture *tex = bgCave_.texture_.get();

Uint8 alpha = std::clamp(
(pos.y - texmin) / (texmax - texmin), 0.0f, 1.0f) * 255;
Swan::TexAlphaMod amod(tex, alpha);


Swan::Draw::parallaxBackground(
win, tex, std::nullopt, std::nullopt,
pos.x * Swan::TILE_SIZE, pos.y * Swan::TILE_SIZE, 0.7);
}
}

SDL_Color WGDefault::backgroundColor(Swan::Vec2 pos) {
float y = pos.y;
float deep = 20;
float deeper = deep + 100;
if (y < deep) {
return Swan::Draw::linearColor(
{ 128, 220, 250, 255 },
{ 107, 87, 5, 255 },
y / deep);
} else if (y < deeper) {
return Swan::Draw::linearColor(
{ 107, 87, 5, 255 },
{ 15, 3, 3, 255 },
(y - deep) / (deeper - deep));
} else {
return { 15, 3, 3, 255 };
}
}

Swan::Tile::ID WGDefault::genTile(Swan::TilePos pos) {
int grass_level = grassLevel(perlin_, pos.x);
int stone_level = stoneLevel(perlin_, pos.x);

+ 10
- 3
core.mod/src/WGDefault.h View File

@@ -12,15 +12,22 @@ public:
};

WGDefault(Swan::World &world):
tGrass_(world.getTileID("core::grass")), tDirt_(world.getTileID("core::dirt")),
tStone_(world.getTileID("core::stone")), tAir_(world.getTileID("core::air")),
tTreeTrunk_(world.getTileID("core::tree-trunk")), tLeaves_(world.getTileID("core::leaves")) {}
tGrass_(world.getTileID("core::grass")),
tDirt_(world.getTileID("core::dirt")),
tStone_(world.getTileID("core::stone")),
tAir_(world.getTileID("core::air")),
tTreeTrunk_(world.getTileID("core::tree-trunk")),
tLeaves_(world.getTileID("core::leaves")),
bgCave_(world.resources_.getImage("core::background-cave")) {}

void drawBackground(const Swan::Context &ctx, Swan::Win &win, Swan::Vec2 pos) override;
SDL_Color backgroundColor(Swan::Vec2 pos) override;
void genChunk(Swan::WorldPlane &plane, Swan::Chunk &chunk) override;
Swan::BodyTrait::HasBody *spawnPlayer(Swan::WorldPlane &plane) override;

private:
Swan::Tile::ID genTile(Swan::TilePos pos);
Swan::Tile::ID tGrass_, tDirt_, tStone_, tAir_, tTreeTrunk_, tLeaves_;
Swan::ImageResource &bgCave_;
siv::PerlinNoise perlin_ = siv::PerlinNoise(100);
};

+ 2
- 0
core.mod/src/main.cc View File

@@ -15,6 +15,8 @@ extern "C" void mod_init(Swan::Mod &mod) {
mod.registerImage({ "leaves", "tiles/leaves.png" });
mod.registerImage({ "player-running", "entities/player-running.png", 64 });
mod.registerImage({ "player-still", "entities/player-still.png", 64 });
mod.registerImage({ "background-cave", "misc/background-cave.png" });
mod.registerImage({ "background-cave-2", "misc/background-cave-2.png" });

mod.registerTile({
.name = "air",

+ 1
- 0
libswan/CMakeLists.txt View File

@@ -3,6 +3,7 @@ add_library(libswan SHARED
src/Animation.cc
src/Chunk.cc
src/Clock.cc
src/drawutil.cc
src/Game.cc
src/gfxutil.cc
src/Item.cc

+ 2
- 0
libswan/include/swan/Game.h View File

@@ -3,6 +3,7 @@
#include <bitset>
#include <map>
#include <string>
#include <SDL.h>

#include "common.h"
#include "Resource.h"
@@ -61,6 +62,7 @@ public:

TilePos getMouseTile();

SDL_Color backgroundColor();
void draw();
void update(float dt);
void tick(float dt);

+ 2
- 0
libswan/include/swan/World.h View File

@@ -4,6 +4,7 @@
#include <vector>
#include <string>
#include <random>
#include <SDL.h>

#include "common.h"
#include "Item.h"
@@ -35,6 +36,7 @@ public:
Tile &getTile(const std::string &name);
Item &getItem(const std::string &name);

SDL_Color backgroundColor();
void draw(Win &win);
void update(float dt);
void tick(float dt);

+ 14
- 0
libswan/include/swan/WorldGen.h View File

@@ -1,15 +1,19 @@
#pragma once

#include <memory>
#include <SDL.h>

#include "common.h"
#include "Chunk.h"
#include "Entity.h"
#include "traits/BodyTrait.h"
#include "Vector2.h"

namespace Swan {

class World;
class WorldPlane;
class ImageResource;

class WorldGen {
public:
@@ -22,8 +26,18 @@ public:

virtual ~WorldGen() = default;

virtual void drawBackground(const Context &ctx, Win &win, Vec2 pos) = 0;
virtual SDL_Color backgroundColor(Vec2 pos) = 0;

virtual void genChunk(WorldPlane &plane, Chunk &chunk) = 0;
virtual BodyTrait::HasBody *spawnPlayer(WorldPlane &plane) = 0;
};

class WorldGenStructure {
public:
virtual ~WorldGenStructure() = 0;

virtual bool isBase(TilePos pos);
};

}

+ 1
- 0
libswan/include/swan/WorldPlane.h View File

@@ -53,6 +53,7 @@ public:
BodyTrait::HasBody *spawnPlayer();
void breakBlock(TilePos pos);

SDL_Color backgroundColor();
void draw(Win &win);
void update(float dt);
void tick(float dt);

+ 19
- 0
libswan/include/swan/drawutil.h View File

@@ -0,0 +1,19 @@
#pragma once

#include <SDL.h>
#include <optional>

#include "Win.h"

namespace Swan {
namespace Draw {

SDL_Color linearColor(SDL_Color from, SDL_Color to, float frac);

void parallaxBackground(
Win &win, SDL_Texture *tex,
std::optional<SDL_Rect> srcrect, std::optional<SDL_Rect> destrect,
float x, float y, float factor);

}
}

+ 59
- 4
libswan/include/swan/gfxutil.h View File

@@ -3,6 +3,8 @@

#include "util.h"

#include "log.h"

namespace Swan {

inline std::ostream &operator<<(std::ostream &os, const SDL_Rect &rect) {
@@ -12,6 +14,59 @@ inline std::ostream &operator<<(std::ostream &os, const SDL_Rect &rect) {
return os;
}

class RenderBlendMode: NonCopyable {
public:
RenderBlendMode(SDL_Renderer *rnd, SDL_BlendMode mode): rnd_(rnd) {
SDL_GetRenderDrawBlendMode(rnd_, &mode_);
SDL_SetRenderDrawBlendMode(rnd_, mode);
}

~RenderBlendMode() {
SDL_SetRenderDrawBlendMode(rnd_, mode_);
}

private:
SDL_Renderer *rnd_;
SDL_BlendMode mode_;
};

class RenderDrawColor: NonCopyable {
public:
RenderDrawColor(SDL_Renderer *rnd, Uint8 r, Uint8 g, Uint8 b, Uint8 a = 255): rnd_(rnd) {
SDL_GetRenderDrawColor(rnd_, &r_, &g_, &b_, &a_);
SDL_SetRenderDrawColor(rnd_, r, g, b, a);
}

~RenderDrawColor() {
SDL_SetRenderDrawColor(rnd_, r_, g_, b_, a_);
}

private:
SDL_Renderer *rnd_;
Uint8 r_, g_, b_, a_;
};

class RenderClipRect: NonCopyable {
public:
RenderClipRect(SDL_Renderer *rnd, SDL_Rect *rect): rnd_(rnd) {
enabled_ = SDL_RenderIsClipEnabled(rnd_);
SDL_RenderGetClipRect(rnd_, &rect_);
SDL_RenderSetClipRect(rnd_, rect);
}

~RenderClipRect() {
if (enabled_)
SDL_RenderSetClipRect(rnd_, &rect_);
else
SDL_RenderSetClipRect(rnd_, nullptr);
}

private:
SDL_Renderer *rnd_;
bool enabled_;
SDL_Rect rect_;
};

class RenderTarget: NonCopyable {
public:
RenderTarget(SDL_Renderer *rnd, SDL_Texture *tex): rnd_(rnd) {
@@ -44,7 +99,7 @@ private:

class TexColorMod: NonCopyable {
public:
TexColorMod(SDL_Texture *tex, uint8_t r, uint8_t g, uint8_t b): tex_(tex) {
TexColorMod(SDL_Texture *tex, Uint8 r, Uint8 g, Uint8 b): tex_(tex) {
SDL_GetTextureColorMod(tex_, &r_, &g_, &b_);
SDL_SetTextureColorMod(tex_, r, g, b);
}
@@ -55,12 +110,12 @@ public:

private:
SDL_Texture *tex_;
uint8_t r_, g_, b_;
Uint8 r_, g_, b_;
};

class TexAlphaMod: NonCopyable {
public:
TexAlphaMod(SDL_Texture *tex, uint8_t alpha): tex_(tex) {
TexAlphaMod(SDL_Texture *tex, Uint8 alpha): tex_(tex) {
SDL_GetTextureAlphaMod(tex_, &alpha_);
SDL_SetTextureAlphaMod(tex_, alpha);
}
@@ -71,7 +126,7 @@ public:

private:
SDL_Texture *tex_;
uint8_t alpha_;
Uint8 alpha_;
};

}

+ 1
- 0
libswan/include/swan/swan.h View File

@@ -22,5 +22,6 @@
#include <swan/WorldPlane.h>
#include <swan/common.h>
#include <swan/log.h>
#include <swan/drawutil.h>
#include <swan/gfxutil.h>
#include <swan/util.h>

+ 9
- 0
libswan/src/Chunk.cc View File

@@ -99,6 +99,7 @@ void Chunk::render(const Context &ctx, SDL_Renderer *rnd) {
texture_.reset(SDL_CreateTexture(
ctx.game.win_.renderer_, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET,
CHUNK_WIDTH * TILE_SIZE, CHUNK_HEIGHT * TILE_SIZE));
SDL_SetTextureBlendMode(texture_.get(), SDL_BLENDMODE_BLEND);
}

// We wanna render directly to the texture
@@ -129,8 +130,16 @@ void Chunk::renderList(SDL_Renderer *rnd) {
// We still wanna render directly to the target texture
RenderTarget target(rnd, texture_.get());

// We must make sure the blend mode is NONE, because we want transparent
// pixels to actually overwrite non-transparent pixels
RenderBlendMode mode(rnd, SDL_BLENDMODE_NONE);

// When we FillRect, we must fill transparency.
RenderDrawColor color(rnd, 0, 0, 0, 0);

for (auto &[pos, tex]: draw_list_) {
SDL_Rect dest{pos.x * TILE_SIZE, pos.y * TILE_SIZE, TILE_SIZE, TILE_SIZE};
SDL_RenderFillRect(rnd, &dest);
SDL_RenderCopy(rnd, tex, nullptr, &dest);
}
}

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

@@ -43,6 +43,10 @@ TilePos Game::getMouseTile() {
(int)floor(win_.cam_.y + mousePos.y / (Swan::TILE_SIZE * win_.zoom_)));
}

SDL_Color Game::backgroundColor() {
return world_->backgroundColor();
}

void Game::draw() {
world_->draw(win_);
}

+ 6
- 0
libswan/src/World.cc View File

@@ -1,5 +1,7 @@
#include "World.h"

#include <algorithm>

#include "log.h"
#include "Game.h"
#include "Win.h"
@@ -123,6 +125,10 @@ Tile &World::getTile(const std::string &name) {
return getTileByID(id);
}

SDL_Color World::backgroundColor() {
return planes_[current_plane_].backgroundColor();
}

void World::draw(Win &win) {
auto bounds = player_->getBody().getBounds();
win.cam_ = bounds.pos - (win.getSize() / 2) + (bounds.size / 2);

+ 7
- 0
libswan/src/WorldPlane.cc View File

@@ -162,8 +162,15 @@ void WorldPlane::breakBlock(TilePos pos) {
}
}

SDL_Color WorldPlane::backgroundColor() {
return gen_->backgroundColor(world_->player_->getBody().getBounds().pos);
}

void WorldPlane::draw(Win &win) {
auto pbounds = world_->player_->getBody().getBounds();

gen_->drawBackground(getContext(), win, pbounds.pos);

ChunkPos pcpos = ChunkPos(
(int)floor(pbounds.pos.x / CHUNK_WIDTH),
(int)floor(pbounds.pos.y / CHUNK_HEIGHT));

+ 74
- 0
libswan/src/drawutil.cc View File

@@ -0,0 +1,74 @@
#include "drawutil.h"

#include <algorithm>
#include <cmath>

#include "gfxutil.h"

namespace Swan {
namespace Draw {

static Uint8 linearLine(float from, float to, float frac) {
return (Uint8)std::clamp(to * frac + from * (1 - frac), 0.0f, 255.0f);
}

SDL_Color linearColor(SDL_Color from, SDL_Color to, float frac) {
return {
.r = linearLine(from.r, to.r, frac),
.g = linearLine(from.g, to.g, frac),
.b = linearLine(from.b, to.b, frac),
.a = linearLine(from.a, to.a, frac),
};
}

void parallaxBackground(
Win &win, SDL_Texture *tex,
std::optional<SDL_Rect> srcrect, std::optional<SDL_Rect> destrect,
float x, float y, float factor) {

SDL_Renderer *rnd = win.renderer_;

// We only need to set a clip rect if we have a destrect
std::optional<RenderClipRect> clip;

if (!srcrect) {
Uint32 fmt;
int access, w, h;
SDL_QueryTexture(tex, &fmt, &access, &w, &h);
srcrect = SDL_Rect{ 0, 0, w, h };
}

if (destrect) {
clip.emplace(rnd, &*destrect);
} else {
int w, h;
SDL_RenderGetLogicalSize(rnd, &w, &h);
destrect = SDL_Rect{ 0, 0, w, h };
}

x = (x * win.zoom_) * -factor;
y = (y * win.zoom_) * -factor;
SDL_Rect rect{
0, 0,
(int)(srcrect->w * win.zoom_),
(int)(srcrect->h * win.zoom_),
};

rect.x = (int)std::floor((int)x % rect.w);
if (rect.x > 0) rect.x -= rect.w;
rect.y = (int)std::floor((int)y % rect.h);
if (rect.y > 0) rect.y -= rect.h;

int numx = destrect->w / rect.w + 2;
int numy = destrect->h / rect.h + 2;

for (int x = 0; x < numx; ++x) {
for (int y = 0; y < numy; ++y) {
SDL_Rect r{ rect.x + x * rect.w, rect.y + y * rect.h, rect.w, rect.h };
SDL_RenderCopy(rnd, tex, &*srcrect, &r);
}
}
}

}
}

+ 7
- 1
src/main.cc View File

@@ -91,6 +91,8 @@ int main(int argc, char **argv) {
CPtr<SDL_Renderer, SDL_DestroyRenderer> renderer(
SDL_CreateRenderer(window.get(), -1, renderflags));
sdlassert(renderer, "Could not create renderer");
SDL_SetRenderDrawBlendMode(renderer.get(), SDL_BLENDMODE_BLEND);
SDL_SetRenderDrawColor(renderer.get(), 0, 0, 0, 255);

Win win(window.get(), renderer.get(), gui_scale);

@@ -230,7 +232,11 @@ int main(int argc, char **argv) {
pcounter.countGameTick(tick_clock.duration());
}

SDL_RenderClear(renderer.get());
{
auto [r, g, b, a] = game.backgroundColor();
RenderDrawColor c(renderer.get(), r, g, b, a);
SDL_RenderClear(renderer.get());
}

// ImGUI
imgui_io.DeltaTime = dt;

Loading…
Cancel
Save