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

assets/tiles/stone.png assets/tiles/stone.png
assets/tiles/dirt.png assets/tiles/dirt.png
assets/tiles/leaves.png assets/tiles/leaves.png
assets/tiles/tree-trunk.png)
assets/tiles/tree-trunk.png
assets/misc/background-cave.png)
foreach(a ${assets}) foreach(a ${assets})
configure_file("${a}" "${a}" COPYONLY) configure_file("${a}" "${a}" COPYONLY)
endforeach(a) 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

#include "WGDefault.h" #include "WGDefault.h"


#include <algorithm>

static int grassLevel(const siv::PerlinNoise &perlin, int x) { static int grassLevel(const siv::PerlinNoise &perlin, int x) {
return (int)(perlin.noise(x / 50.0, 0) * 13); return (int)(perlin.noise(x / 50.0, 0) * 13);
} }
return (int)(perlin.noise(x / 50.0, 10) * 10) + 10; 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) { Swan::Tile::ID WGDefault::genTile(Swan::TilePos pos) {
int grass_level = grassLevel(perlin_, pos.x); int grass_level = grassLevel(perlin_, pos.x);
int stone_level = stoneLevel(perlin_, pos.x); int stone_level = stoneLevel(perlin_, pos.x);

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

}; };


WGDefault(Swan::World &world): 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; void genChunk(Swan::WorldPlane &plane, Swan::Chunk &chunk) override;
Swan::BodyTrait::HasBody *spawnPlayer(Swan::WorldPlane &plane) override; Swan::BodyTrait::HasBody *spawnPlayer(Swan::WorldPlane &plane) override;


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

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

mod.registerImage({ "leaves", "tiles/leaves.png" }); mod.registerImage({ "leaves", "tiles/leaves.png" });
mod.registerImage({ "player-running", "entities/player-running.png", 64 }); mod.registerImage({ "player-running", "entities/player-running.png", 64 });
mod.registerImage({ "player-still", "entities/player-still.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({ mod.registerTile({
.name = "air", .name = "air",

+ 1
- 0
libswan/CMakeLists.txt View File

src/Animation.cc src/Animation.cc
src/Chunk.cc src/Chunk.cc
src/Clock.cc src/Clock.cc
src/drawutil.cc
src/Game.cc src/Game.cc
src/gfxutil.cc src/gfxutil.cc
src/Item.cc src/Item.cc

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

#include <bitset> #include <bitset>
#include <map> #include <map>
#include <string> #include <string>
#include <SDL.h>


#include "common.h" #include "common.h"
#include "Resource.h" #include "Resource.h"


TilePos getMouseTile(); TilePos getMouseTile();


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

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

#include <vector> #include <vector>
#include <string> #include <string>
#include <random> #include <random>
#include <SDL.h>


#include "common.h" #include "common.h"
#include "Item.h" #include "Item.h"
Tile &getTile(const std::string &name); Tile &getTile(const std::string &name);
Item &getItem(const std::string &name); Item &getItem(const std::string &name);


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

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

#pragma once #pragma once


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


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


namespace Swan { namespace Swan {


class World; class World;
class WorldPlane; class WorldPlane;
class ImageResource;


class WorldGen { class WorldGen {
public: public:


virtual ~WorldGen() = default; 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 void genChunk(WorldPlane &plane, Chunk &chunk) = 0;
virtual BodyTrait::HasBody *spawnPlayer(WorldPlane &plane) = 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

BodyTrait::HasBody *spawnPlayer(); BodyTrait::HasBody *spawnPlayer();
void breakBlock(TilePos pos); void breakBlock(TilePos pos);


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

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

#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



#include "util.h" #include "util.h"


#include "log.h"

namespace Swan { namespace Swan {


inline std::ostream &operator<<(std::ostream &os, const SDL_Rect &rect) { inline std::ostream &operator<<(std::ostream &os, const SDL_Rect &rect) {
return os; 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 { class RenderTarget: NonCopyable {
public: public:
RenderTarget(SDL_Renderer *rnd, SDL_Texture *tex): rnd_(rnd) { RenderTarget(SDL_Renderer *rnd, SDL_Texture *tex): rnd_(rnd) {


class TexColorMod: NonCopyable { class TexColorMod: NonCopyable {
public: 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_GetTextureColorMod(tex_, &r_, &g_, &b_);
SDL_SetTextureColorMod(tex_, r, g, b); SDL_SetTextureColorMod(tex_, r, g, b);
} }


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


class TexAlphaMod: NonCopyable { class TexAlphaMod: NonCopyable {
public: public:
TexAlphaMod(SDL_Texture *tex, uint8_t alpha): tex_(tex) {
TexAlphaMod(SDL_Texture *tex, Uint8 alpha): tex_(tex) {
SDL_GetTextureAlphaMod(tex_, &alpha_); SDL_GetTextureAlphaMod(tex_, &alpha_);
SDL_SetTextureAlphaMod(tex_, alpha); SDL_SetTextureAlphaMod(tex_, alpha);
} }


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


} }

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

#include <swan/WorldPlane.h> #include <swan/WorldPlane.h>
#include <swan/common.h> #include <swan/common.h>
#include <swan/log.h> #include <swan/log.h>
#include <swan/drawutil.h>
#include <swan/gfxutil.h> #include <swan/gfxutil.h>
#include <swan/util.h> #include <swan/util.h>

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

texture_.reset(SDL_CreateTexture( texture_.reset(SDL_CreateTexture(
ctx.game.win_.renderer_, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, ctx.game.win_.renderer_, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET,
CHUNK_WIDTH * TILE_SIZE, CHUNK_HEIGHT * TILE_SIZE)); CHUNK_WIDTH * TILE_SIZE, CHUNK_HEIGHT * TILE_SIZE));
SDL_SetTextureBlendMode(texture_.get(), SDL_BLENDMODE_BLEND);
} }


// We wanna render directly to the texture // We wanna render directly to the texture
// We still wanna render directly to the target texture // We still wanna render directly to the target texture
RenderTarget target(rnd, texture_.get()); 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_) { for (auto &[pos, tex]: draw_list_) {
SDL_Rect dest{pos.x * TILE_SIZE, pos.y * TILE_SIZE, TILE_SIZE, TILE_SIZE}; 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); SDL_RenderCopy(rnd, tex, nullptr, &dest);
} }
} }

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

(int)floor(win_.cam_.y + mousePos.y / (Swan::TILE_SIZE * win_.zoom_))); (int)floor(win_.cam_.y + mousePos.y / (Swan::TILE_SIZE * win_.zoom_)));
} }


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

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

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

#include "World.h" #include "World.h"


#include <algorithm>

#include "log.h" #include "log.h"
#include "Game.h" #include "Game.h"
#include "Win.h" #include "Win.h"
return getTileByID(id); return getTileByID(id);
} }


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

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

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

} }
} }


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

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

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

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

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

#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

CPtr<SDL_Renderer, SDL_DestroyRenderer> renderer( CPtr<SDL_Renderer, SDL_DestroyRenderer> renderer(
SDL_CreateRenderer(window.get(), -1, renderflags)); SDL_CreateRenderer(window.get(), -1, renderflags));
sdlassert(renderer, "Could not create renderer"); 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); Win win(window.get(), renderer.get(), gui_scale);


pcounter.countGameTick(tick_clock.duration()); 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
imgui_io.DeltaTime = dt; imgui_io.DeltaTime = dt;

Loading…
Cancel
Save