116 lines
3.2 KiB
C++
116 lines
3.2 KiB
C++
//
|
|
// tiling.cpp
|
|
// BoE
|
|
//
|
|
// Created by Celtic Minstrel on 17-04-14.
|
|
//
|
|
//
|
|
|
|
#include "tiling.hpp"
|
|
|
|
#include <unordered_map>
|
|
#include <SFML/Graphics.hpp>
|
|
#include <SFML/OpenGL.hpp>
|
|
#include "fileio/resmgr/res_image.hpp"
|
|
#include "gfx/render_image.hpp"
|
|
#include "gfx/render_shapes.hpp"
|
|
|
|
rectangle bg_rects[21];
|
|
tessel_ref_t bg[21];
|
|
tessel_ref_t bw_pats[6];
|
|
|
|
struct tessel_t {
|
|
sf::RenderTexture* tessel;
|
|
sf::Texture* img;
|
|
rectangle srcRect;
|
|
};
|
|
|
|
bool operator==(const tessel_ref_t& a, const tessel_ref_t& b) {
|
|
return a.key == b.key;
|
|
}
|
|
|
|
namespace std {
|
|
template<> struct hash<tessel_ref_t> {
|
|
size_t operator()(tessel_ref_t key) const {
|
|
return key.key;
|
|
}
|
|
};
|
|
}
|
|
|
|
std::unordered_map<tessel_ref_t, tessel_t> tiling_reservoir;
|
|
static int tessel_index = 0;
|
|
|
|
tessel_ref_t prepareForTiling(sf::Texture& srcImg, rectangle srcRect) {
|
|
tessel_ref_t ref = {tessel_index++};
|
|
tiling_reservoir[ref].img = &srcImg;
|
|
tiling_reservoir[ref].srcRect = srcRect;
|
|
tiling_reservoir[ref].tessel = new sf::RenderTexture;
|
|
tiling_reservoir[ref].tessel->create(srcRect.width(), srcRect.height());
|
|
rectangle tesselRect(*tiling_reservoir[ref].tessel);
|
|
rect_draw_some_item(srcImg, srcRect, *tiling_reservoir[ref].tessel, tesselRect);
|
|
tiling_reservoir[ref].tessel->display();
|
|
tiling_reservoir[ref].tessel->setRepeated(true);
|
|
return ref;
|
|
}
|
|
|
|
void tileImage(sf::RenderTarget& target, rectangle area, tessel_ref_t tessel, sf::BlendMode mode) {
|
|
// First, set up a dictionary of all textures ever tiled.
|
|
// The key type is a pair<Texture*,rectangle>.
|
|
// The value type is a Texture.
|
|
tessel_t& tesselInfo = tiling_reservoir[tessel];
|
|
rectangle clipArea = area;
|
|
area.left -= area.left % tesselInfo.srcRect.width();
|
|
area.top -= area.top % tesselInfo.srcRect.height();
|
|
area &= rectangle(target); // Make sure we don't draw out of bounds
|
|
|
|
sf::RectangleShape tesselShape(sf::Vector2f(area.width(),area.height()));
|
|
tesselShape.setTexture(&tesselInfo.tessel->getTexture());
|
|
tesselShape.setTextureRect(area);
|
|
tesselShape.setPosition(area.left, area.top);
|
|
sf::RenderStates renderMode(mode);
|
|
setActiveRenderTarget(target);
|
|
clip_rect(target, clipArea);
|
|
target.draw(tesselShape, renderMode);
|
|
undo_clip(target);
|
|
}
|
|
|
|
void init_tiling() {
|
|
static const location pat_offs[17] = {
|
|
{0,3}, {1,1}, {2,1}, {2,0},
|
|
{3,0}, {3,1}, {1,3}, {0,0},
|
|
{0,2}, {1,2}, {0,1}, {2,2},
|
|
{2,3}, {3,2}, {1,0}, {4,0}, {3,3}
|
|
};
|
|
static const int pat_i[17] = {
|
|
2, 3, 4, 5, 6, 8, 9, 10,
|
|
11,12,13,14,15,16,17,19,20
|
|
};
|
|
for(short i = 0; i < 17; i++){
|
|
bg_rects[pat_i[i]] = {0,0,64,64};
|
|
bg_rects[pat_i[i]].offset(64 * pat_offs[i].x,64 * pat_offs[i].y);
|
|
}
|
|
rectangle tmp_rect = bg_rects[19];
|
|
tmp_rect.offset(0, 64);
|
|
bg_rects[0] = bg_rects[1] = bg_rects[18] = bg_rects[7] = tmp_rect;
|
|
bg_rects[0].right -= 32;
|
|
bg_rects[0].bottom -= 32;
|
|
bg_rects[1].left += 32;
|
|
bg_rects[1].bottom -= 32;
|
|
bg_rects[18].right -= 32;
|
|
bg_rects[18].top += 32;
|
|
bg_rects[7].left += 32;
|
|
bg_rects[7].top += 32;
|
|
|
|
rectangle bw_rect = {0,0,8,8};
|
|
sf::Texture& bg_gworld = *ResMgr::graphics.get("pixpats");
|
|
sf::Texture& bw_gworld = *ResMgr::graphics.get("bwpats");
|
|
for(int i = 0; i < 21; i++) {
|
|
if(i < 6) {
|
|
bw_pats[i] = prepareForTiling(bw_gworld, bw_rect);
|
|
bw_rect.offset(8,0);
|
|
}
|
|
bg[i] = prepareForTiling(bg_gworld, bg_rects[i]);
|
|
}
|
|
glFlush();
|
|
}
|