Browse Source

SDL progress

opengl-renderer-broken
Martin Dørum 4 years ago
parent
commit
50f7d00ff1
3 changed files with 35 additions and 23 deletions
  1. 3
    2
      libswan/include/swan/Chunk.h
  2. 9
    6
      libswan/include/swan/util.h
  3. 23
    15
      libswan/src/Chunk.cc

+ 3
- 2
libswan/include/swan/Chunk.h View File

@@ -4,6 +4,7 @@
#include <stdint.h>
#include <memory>

#include "util.h"
#include "common.h"
#include "Tile.h"

@@ -51,8 +52,8 @@ private:
float deactivate_timer_ = DEACTIVATE_INTERVAL;

struct Visuals {
std::unique_ptr<SDL_Surface, void (*)(SDL_Surface *)> surface_{nullptr, SDL_FreeSurface};
bool dirty_;
RaiiPtr<SDL_Texture> texture_ = makeRaiiPtr<SDL_Texture>(nullptr, SDL_DestroyTexture);
bool dirty_ = true;
};
std::unique_ptr<Visuals> visuals_;
};

+ 9
- 6
libswan/include/swan/util.h View File

@@ -1,4 +1,4 @@
#pragma once
#pragma once

#include <optional>
#include <functional>
@@ -6,6 +6,14 @@

namespace Swan {

template<typename T, typename Del = void (*)(T *)>
using RaiiPtr = std::unique_ptr<T, Del>;

template<typename T, typename Del>
RaiiPtr<T, Del> makeRaiiPtr(T *val, Del d) {
return std::unique_ptr<T, Del>(val, d);
}

template<typename Func>
class Deferred {
public:
@@ -19,11 +27,6 @@ private:
bool active_ = true;
};

template<typename T, typename Del>
std::unique_ptr<T, Del> makeRaiiPtr(T *val, Del d) {
return std::unique_ptr<T, Del>(val, d);
}

template<typename Func>
Deferred<Func> makeDeferred(Func func) {
return Deferred(func);

+ 23
- 15
libswan/src/Chunk.cc View File

@@ -1,6 +1,7 @@
#include "Chunk.h"

#include <zlib.h>
#include <stdint.h>

#include "log.h"
#include "World.h"
@@ -83,8 +84,6 @@ void Chunk::decompress() {
data_ = std::move(dest);

visuals_.reset(new Visuals());
visuals_->surface_.reset(SDL_CreateRGBSurface(
0, CHUNK_WIDTH * TILE_SIZE, CHUNK_HEIGHT * TILE_SIZE, 24, 0, 0, 0, 0));
visuals_->dirty_ = true;
need_render_ = true;

@@ -96,9 +95,25 @@ void Chunk::decompress() {
}

void Chunk::render(const Context &ctx) {
// The texture might not be created yet
if (!visuals_->texture_) {
visuals_->texture_.reset(SDL_CreateTexture(
ctx.game.win_.renderer_, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING,
CHUNK_WIDTH * TILE_SIZE, CHUNK_HEIGHT * TILE_SIZE));
}

Tile::ID prevID = Tile::INVALID_ID;
Tile *tile = ctx.game.invalid_tile_.get();

SDL_Rect rect{ 0, 0, CHUNK_WIDTH * TILE_SIZE, CHUNK_HEIGHT * TILE_SIZE };
uint8_t *pixels;
int pitch;
if (SDL_LockTexture(visuals_->texture_.get(), &rect, (void **)&pixels, &pitch) < 0) {
panic << "Failed to lock texture: " << SDL_GetError();
abort();
}
auto lock = makeDeferred([this] { SDL_UnlockTexture(visuals_->texture_.get()); });

for (int x = 0; x < CHUNK_WIDTH; ++x) {
for (int y = 0; y < CHUNK_HEIGHT; ++y) {
Tile::ID id = getTileID(RelPos(x, y));
@@ -107,23 +122,16 @@ void Chunk::render(const Context &ctx) {
tile = &ctx.world.getTileByID(id);
}

// TODO: Reimplement this for SDL
/*
const sf::Uint8 *imgptr = NULL;
//const sf::Uint8 *imgptr = tile->image->getPixelsPtr();
auto &tilesurf = tile->image_.surface_;

for (int imgy = 0; imgy < TILE_SIZE; ++imgy) {
int pixx = x * TILE_SIZE;
int pixy = y * TILE_SIZE + imgy;
sf::Uint8 *pix = renderbuf +
pixy * CHUNK_WIDTH * TILE_SIZE * 4 +
pixx * 4;
memcpy(pix, imgptr + imgy * TILE_SIZE * 4, TILE_SIZE * 4);
uint8_t *tilepix = (uint8_t *)tilesurf->pixels + (imgy * tilesurf->pitch) * 4;
uint8_t *destpix = pixels + (y * pitch + x * TILE_SIZE) * 4;
memcpy(destpix, tilepix, TILE_SIZE * 4);
}
*/
}
}

//visuals_->tex_.update(renderbuf, CHUNK_WIDTH * TILE_SIZE, CHUNK_HEIGHT * TILE_SIZE, 0, 0);
visuals_->dirty_ = true;
}

@@ -132,7 +140,7 @@ void Chunk::draw(const Context &ctx, Win &win) {
return;

if (need_render_) {
render(ctx);
info << "OK need render, so we create texture";
need_render_ = false;
}


Loading…
Cancel
Save