-
-
Save rubenwardy/3d104ebcef8258b14bc8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include "SDLEngine.hpp" | |
#include <sstream> | |
#include <vector> | |
#include <thread> | |
#include <mutex> | |
#define TILE_SIZE 64 | |
#define TILE_TEX_SIZE 32 * TILE_SIZE * TILE_SIZE | |
struct Tile | |
{ | |
int X; | |
int Y; | |
SDL_Texture *texture; | |
}; | |
struct TileData | |
{ | |
int X; | |
int Y; | |
Uint32 *pixels; | |
}; | |
#include <unistd.h> | |
class TileRenderWorker | |
{ | |
std::thread the_thread; | |
bool stop_thread; | |
void doTile(int X, int Y, double acorn, double bcorn, double size, double max_loop) | |
{ | |
//std::cerr << "Building tile " << X << ", " << Y << std::endl; | |
Uint32 *pixels = static_cast<Uint32*>(malloc(TILE_TEX_SIZE)); | |
for (double x = 0; x < TILE_SIZE; x++) { | |
for (double y = 0; y < TILE_SIZE; y++) { | |
double ax = x + X * TILE_SIZE; | |
double ay = y + Y * TILE_SIZE; | |
double count = 0; | |
double ca = acorn + ax * size / 1280; | |
double cb = bcorn + ay * size / 720; | |
double zx = 0; | |
double zy = 0; | |
do { | |
count++; | |
double tmp = zx*zx - zy*zy; | |
zy = 2*zx*zy + cb; | |
zx = tmp + ca; | |
} while(count < max_loop && zx*zx + zy*zy <= 4); | |
Uint32 result = (count / max_loop) * (count / max_loop) * 255.0; | |
Uint32 r2 = 255 / (count + 1); | |
pixels[(int)x + (int)y * TILE_SIZE] = | |
(result << 32) + | |
(result << 16) + | |
(result << 8) + | |
0xFF; | |
} | |
} | |
TileData tmp; | |
tmp.X = X; | |
tmp.Y = Y; | |
tmp.pixels = pixels; | |
{ | |
std::lock_guard<std::mutex> guard(mut_out); | |
out.push_back(tmp); | |
} | |
} | |
public: | |
TileRenderWorker(): | |
the_thread() | |
{} | |
~TileRenderWorker() | |
{ | |
stop_thread = true; | |
if(the_thread.joinable()) | |
the_thread.join(); | |
} | |
std::vector<TileData> out; | |
std::mutex mut_out; | |
void run() | |
{ | |
double acorn = -0.5; | |
double bcorn = 0.25; | |
double size = 1; | |
double max_loop = 1; | |
while(!stop_thread && max_loop < 100) { | |
for (int X = 0; X < 1280/TILE_SIZE; X++) { | |
for (int Y = 0; Y < 720/TILE_SIZE; Y++) { | |
doTile(X, Y, acorn, bcorn, size, max_loop); | |
} | |
} | |
max_loop += 1; | |
usleep(100000); | |
} | |
} | |
void start() | |
{ | |
the_thread = std::thread(&TileRenderWorker::run, this); | |
} | |
}; | |
class Game : public IEventReceiver | |
{ | |
std::vector<Tile> tiles; | |
TileRenderWorker worker; | |
public: | |
void addTile(Uint32 *data, int X, int Y) | |
{ | |
SDLEngine *engine = SDLEngine::get(); | |
SDL_Texture *texture = SDL_CreateTexture(engine->getRenderer(), | |
SDL_PIXELFORMAT_RGBA8888, | |
SDL_TEXTUREACCESS_STREAMING, | |
TILE_SIZE, TILE_SIZE); | |
SDL_UpdateTexture(texture, NULL, data, TILE_SIZE * sizeof (Uint32)); | |
free(data); | |
int i = 0; | |
for (Tile tile : tiles) { | |
if (tile.X == X && tile.Y == Y) { | |
SDL_DestroyTexture(tile.texture); | |
tiles.erase(tiles.begin() + i); | |
break; | |
} | |
i++; | |
} | |
Tile tmp; | |
// std::cerr << "Adding " << X << ", " << Y << std::endl; | |
tmp.X = X; | |
tmp.Y = Y; | |
tmp.texture = texture; | |
tiles.push_back(tmp); | |
} | |
void run() | |
{ | |
SDLEngine *engine = SDLEngine::get(); | |
engine->init(); | |
engine->setEventReceiver(this); | |
double count = 0; | |
int frames_since = 0; | |
while (engine->run()) { | |
frames_since++; | |
if (engine->renderNeeded()) { | |
engine->start(); | |
for (Tile tile : tiles) { | |
engine->renderTexture(tile.texture, TILE_SIZE * tile.X, | |
TILE_SIZE * tile.Y); | |
} | |
engine->end(); | |
} | |
{ | |
std::lock_guard<std::mutex> guard(worker.mut_out); | |
for (TileData data : worker.out) | |
addTile(data.pixels, data.X, data.Y); | |
worker.out.clear(); | |
} | |
count += engine->dtime; | |
if (count > 1) { | |
std::ostringstream os; | |
os << "FractalTest | "; | |
os << frames_since; | |
os << " uFPS | "; | |
os << engine->renderProportion() * frames_since; | |
os << " rFPS ["; | |
os << engine->renderProportion() * 100; | |
os << "%]"; | |
engine->setWindowTitle(os.str().c_str()); | |
frames_since = 0; | |
count = 0; | |
} | |
} | |
} | |
bool onEvent(SDL_Event &e) | |
{ | |
if (e.type == SDL_KEYDOWN && | |
e.key.keysym.sym == SDLK_UP) { | |
worker.start(); | |
} | |
} | |
}; | |
int main() | |
{ | |
Game game; | |
game.run(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment