Skip to content

Commit

Permalink
Merge pull request mrkite#174 from EtlamGit/asynchronous-chunk-loading
Browse files Browse the repository at this point in the history
fix Overlays when changing depth
  • Loading branch information
mrkite authored Aug 9, 2019
2 parents 2f74810 + a715fd7 commit c367653
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 27 deletions.
8 changes: 8 additions & 0 deletions chunkcache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ QString ChunkCache::getPath() const {
return path;
}

int ChunkCache::getCost() const {
return cache.totalCost();
}

int ChunkCache::getMaxCost() const {
return cache.maxCost();
}

QSharedPointer<Chunk> ChunkCache::fetchCached(int cx, int cz) {
// try to get Chunk from Cache
ChunkID id(cx, cz);
Expand Down
2 changes: 2 additions & 0 deletions chunkcache.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ class ChunkCache : public QObject {
QString getPath() const;
QSharedPointer<Chunk> fetch(int cx, int cz); // fetch Chunk and load when not found
QSharedPointer<Chunk> fetchCached(int cx, int cz); // fetch Chunk only if cached
int getCost() const;
int getMaxCost() const;

signals:
void chunkLoaded(int cx, int cz);
Expand Down
60 changes: 34 additions & 26 deletions mapview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,8 @@ void MapView::mouseMoveEvent(QMouseEvent *event) {
int centerblockx = floor(this->x);
int centerblockz = floor(this->z);

int centerx = image.width() / 2;
int centery = image.height() / 2;
int centerx = imageChunks.width() / 2;
int centery = imageChunks.height() / 2;

centerx -= (this->x - centerblockx) * zoom;
centery -= (this->z - centerblockz) * zoom;
Expand All @@ -172,8 +172,8 @@ void MapView::mouseDoubleClickEvent(QMouseEvent *event) {
int centerblockx = floor(this->x);
int centerblockz = floor(this->z);

int centerx = image.width() / 2;
int centery = image.height() / 2;
int centerx = imageChunks.width() / 2;
int centery = imageChunks.height() / 2;

centerx -= (this->x - centerblockx) * zoom;
centery -= (this->z - centerblockz) * zoom;
Expand Down Expand Up @@ -270,24 +270,22 @@ void MapView::keyPressEvent(QKeyEvent *event) {
}

void MapView::resizeEvent(QResizeEvent *event) {
image = QImage(event->size(), QImage::Format_RGB32);
imageChunks = QImage(event->size(), QImage::Format_RGB32);
imageOverlays = QImage(event->size(), QImage::Format_RGBA8888);
redraw();
}

void MapView::paintEvent(QPaintEvent * /* event */) {
QPainter p(this);
p.drawImage(QPoint(0, 0), image);
p.drawImage(QPoint(0, 0), imageChunks);
p.drawImage(QPoint(0, 0), imageOverlays);
p.end();
}

void MapView::redraw() {
if (!this->isEnabled()) {
// blank
uchar *bits = image.bits();
int imgstride = image.bytesPerLine();
int imgoffset = 0;
for (int y = 0; y < image.height(); y++, imgoffset += imgstride)
memset(bits + imgoffset, 0xee, imgstride);
imageChunks.fill(0xeeeeee);
update();
return;
}
Expand All @@ -298,26 +296,29 @@ void MapView::redraw() {
int centerchunkx = floor(x / 16);
int centerchunkz = floor(z / 16);
// and the center of the screen
int centerx = image.width() / 2;
int centery = image.height() / 2;
int centerx = imageChunks.width() / 2;
int centery = imageChunks.height() / 2;
// and align for panning
centerx -= (x - centerchunkx * 16) * zoom;
centery -= (z - centerchunkz * 16) * zoom;
// now calculate the topleft block on the screen
int startx = centerchunkx - floor(centerx / chunksize) - 1;
int startz = centerchunkz - floor(centery / chunksize) - 1;
// and the dimensions of the screen in blocks
int blockswide = image.width() / chunksize + 3;
int blockstall = image.height() / chunksize + 3;
int blockswide = imageChunks.width() / chunksize + 3;
int blockstall = imageChunks.height() / chunksize + 3;

for (int cz = startz; cz < startz + blockstall; cz++)
for (int cx = startx; cx < startx + blockswide; cx++)
drawChunk(cx, cz);

// clear the overlay layer
imageOverlays.fill(0);

// add on the entity layer
QPainter canvas(&image);
double halfviewwidth = image.width() / 2 / zoom;
double halvviewheight = image.height() / 2 / zoom;
QPainter canvas(&imageOverlays);
double halfviewwidth = imageOverlays.width() / 2 / zoom;
double halvviewheight = imageOverlays.height() / 2 / zoom;
double x1 = x - halfviewwidth;
double z1 = z - halvviewheight;
double x2 = x + halfviewwidth;
Expand Down Expand Up @@ -392,8 +393,8 @@ void MapView::drawChunk(int x, int z) {
int centerchunkx = floor(this->x / 16);
int centerchunkz = floor(this->z / 16);
// and the center chunk screen coordinates
int centerx = image.width() / 2;
int centery = image.height() / 2;
int centerx = imageChunks.width() / 2;
int centery = imageChunks.height() / 2;
// which need to be shifted to account for panning inside that chunk
centerx -= (this->x - centerchunkx * 16) * zoom;
centery -= (this->z - centerchunkz * 16) * zoom;
Expand All @@ -404,8 +405,8 @@ void MapView::drawChunk(int x, int z) {
centery += (z - centerchunkz) * chunksize;

int srcoffset = 0;
uchar *bits = image.bits();
int imgstride = image.bytesPerLine();
uchar *bits = imageChunks.bits();
int imgstride = imageChunks.bytesPerLine();

int skipx = 0, skipy = 0;
int blockwidth = chunksize, blockheight = chunksize;
Expand All @@ -419,10 +420,10 @@ void MapView::drawChunk(int x, int z) {
centery = 0;
}
// or the other side, we need to trim
if (centerx + blockwidth > image.width())
blockwidth = image.width() - centerx;
if (centery + blockheight > image.height())
blockheight = image.height() - centery;
if (centerx + blockwidth > imageChunks.width())
blockwidth = imageChunks.width() - centerx;
if (centery + blockheight > imageChunks.height())
blockheight = imageChunks.height() - centery;
if (blockwidth <= 0 || skipx >= blockwidth) return;
int imgoffset = centerx * 4 + centery * imgstride;
if (chunk)
Expand Down Expand Up @@ -511,6 +512,13 @@ void MapView::getToolTip(int x, int z) {
hovertext += " (" + blockstate + ")";
if (entityStr.length() > 0)
hovertext += " - " + entityStr;

#ifdef DEBUG
hovertext += " [Cache:"
+ QString().number(this->cache.getCost()) + "/"
+ QString().number(this->cache.getMaxCost()) + "]";
#endif

emit hoverTextChanged(hovertext);
}

Expand Down
3 changes: 2 additions & 1 deletion mapview.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ class MapView : public QWidget {
double zoom;
int flags;
ChunkCache &cache;
QImage image;
QImage imageChunks;
QImage imageOverlays;
DefinitionManager *dm;
uchar placeholder[16 * 16 * 4]; // no chunk found placeholder
QSet<QString> overlayItemTypes;
Expand Down

0 comments on commit c367653

Please sign in to comment.