Browse Source

chunk drawing works, though should be optimized probably

opengl-renderer-broken
Martin Dørum 4 years ago
parent
commit
52de01d886
4 changed files with 53 additions and 14 deletions
  1. 13
    0
      libswan/include/swan/gfxutil.h
  2. 1
    0
      libswan/include/swan/swan.h
  3. 36
    14
      libswan/src/Chunk.cc
  4. 3
    0
      libswan/test/gfxutil.t.cc

+ 13
- 0
libswan/include/swan/gfxutil.h View File

@@ -0,0 +1,13 @@
#include <SDL2/SDL.h>
#include <ostream>

namespace Swan {

inline std::ostream &operator<<(std::ostream &os, const SDL_Rect &rect) {
os
<< "SDL_Rect(" << rect.x << ", " << rect.y << ", "
<< rect.w << ", " << rect.h << ")";
return os;
}

}

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

@@ -20,4 +20,5 @@
#include <swan/WorldPlane.h>
#include <swan/common.h>
#include <swan/log.h>
#include <swan/gfxutil.h>
#include <swan/util.h>

+ 36
- 14
libswan/src/Chunk.cc View File

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

#include "log.h"
#include "gfxutil.h"
#include "World.h"
#include "Game.h"
#include "Win.h"
@@ -102,13 +103,26 @@ void Chunk::render(const Context &ctx) {
CHUNK_WIDTH * TILE_SIZE, CHUNK_HEIGHT * TILE_SIZE));
}

if (pos_ != ChunkPos(0, 0))
return;
info << "Rendering chunk " << pos_;

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

// Get info about or texture for later
uint32_t format;
int access, texw, texh;
if (SDL_QueryTexture(visuals_->texture_.get(), &format, &access, &texw, &texh) < 0) {
panic << "Failed to query texture: " << SDL_GetError();
abort();
}

// ...Now convert the format to an actually useful mask
int bpp = 32;
uint32_t rmask, gmask, bmask, amask;
if (SDL_PixelFormatEnumToMasks(format, &bpp, &rmask, &gmask, &bmask, &amask) != SDL_TRUE) {
panic << "Failed to get pixel mask: " << SDL_GetError();
abort();
}

// We lock the txture to get write access to its raw pixels
SDL_Rect rect{ 0, 0, CHUNK_WIDTH * TILE_SIZE, CHUNK_HEIGHT * TILE_SIZE };
uint8_t *pixels;
int pitch;
@@ -118,6 +132,13 @@ void Chunk::render(const Context &ctx) {
}
auto lock = makeDeferred([this] { SDL_UnlockTexture(visuals_->texture_.get()); });

// This surface will refer to the pixels of our texture which we want to update.
auto destsurf = makeRaiiPtr(
SDL_CreateRGBSurfaceFrom(
pixels, TILE_SIZE, TILE_SIZE, 32, pitch,
rmask, gmask, bmask, amask),
SDL_FreeSurface);

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

auto &tilesurf = tile->image_.surface_;
auto &srcsurf = tile->image_.surface_;
SDL_Rect srcrect{ 0, 0, srcsurf->w, srcsurf->h };

for (int imgy = 0; imgy < TILE_SIZE; ++imgy) {
uint8_t *tilepix = (uint8_t *)tilesurf->pixels + imgy * tilesurf->pitch;
uint8_t *destpix = pixels +
((y * TILE_SIZE + imgy) * pitch) +
(x * TILE_SIZE) * 4;
memcpy(destpix, tilepix, TILE_SIZE * 4);
/*
SDL_Rect destrect{ x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE };
*/
destsurf->pixels = pixels + (y * TILE_SIZE * pitch) + x * TILE_SIZE * 4;
SDL_Rect destrect{ 0, 0, TILE_SIZE, TILE_SIZE };

if (SDL_BlitSurface(srcsurf.get(), &srcrect, destsurf.get(), &destrect) < 0) {
warn << "Failed to blit surface: " << SDL_GetError();
}
}
}

visuals_->dirty_ = true;
}

void Chunk::draw(const Context &ctx, Win &win) {
@@ -151,7 +173,7 @@ void Chunk::draw(const Context &ctx, Win &win) {
}

if (visuals_->dirty_) {
//visuals_->sprite_.setTexture(visuals_->tex_);
need_render_ = true;
visuals_->dirty_ = false;
}


+ 3
- 0
libswan/test/gfxutil.t.cc View File

@@ -0,0 +1,3 @@
#include "gfxutil.h"

#include "lib/test.h"

Loading…
Cancel
Save