diff --git a/CMakeLists.txt b/CMakeLists.txt index 587c14a..6e8a5c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,7 @@ add_library(shared STATIC shared/src/values/Similarity.cpp shared/src/TcpSocket.cpp shared/src/sql.cpp + shared/src/timing.cpp ) add_executable(app @@ -44,21 +45,23 @@ add_executable(app target_include_directories(app PRIVATE app/inc) target_link_libraries(app PRIVATE shared) -add_executable(server - server/src/server.cpp - server/src/checker.cpp -) -target_include_directories(server PRIVATE server/inc) -target_link_libraries(server PRIVATE shared) +# add_executable(server +# server/src/server.cpp +# server/src/checker.cpp +# ) +# target_include_directories(server PRIVATE server/inc) +# target_link_libraries(server PRIVATE shared) -add_executable(view - view/src/main.cpp - view/src/Vapp.cpp -) -target_include_directories(view PRIVATE view/inc) -target_link_libraries(view PRIVATE shared) +# add_executable(view +# view/src/main.cpp +# view/src/Vapp.cpp +# ) +# target_include_directories(view PRIVATE view/inc) +# target_link_libraries(view PRIVATE shared) -add_executable(slike - random/slike.cpp -) -target_link_libraries(slike PRIVATE shared) \ No newline at end of file +# add_executable(slike +# random/slike.cpp +# ) +# target_link_libraries(slike PRIVATE shared) + +file(COPY CascadiaCode.ttf DESTINATION "res") \ No newline at end of file diff --git a/CascadiaCode.ttf b/CascadiaCode.ttf new file mode 100644 index 0000000..bba59c9 Binary files /dev/null and b/CascadiaCode.ttf differ diff --git a/app/inc/App.hpp b/app/inc/App.hpp index 1f9b894..a77e3f7 100644 --- a/app/inc/App.hpp +++ b/app/inc/App.hpp @@ -18,30 +18,14 @@ private: int screenWidth, screenHeight; Canvas canvas; - int pos = 0; - std::array canvasTexure = {0}; + RenderTexture2D canvasTexure = {0}; - float rotation = 0.0f; - Vector2 mouseStart; - bool validHit = false; - float len; - float ofset; - - Liked topLiked = Liked::tbd; Rectangle destA; - Rectangle destB; - Rectangle likeBox; - Rectangle disLikeBox; - std::array unit = {0}; + UiUnit unit = {0}; DnaManagerData manager; - Rectangle likedTextBox; - Rectangle genTextBox; - Rectangle simTextBox; - float simil = 100.0f; - Color appColor = BLUE; }; diff --git a/app/src/App.cpp b/app/src/App.cpp index be8b05c..dccce30 100644 --- a/app/src/App.cpp +++ b/app/src/App.cpp @@ -2,241 +2,118 @@ #include #include "App.hpp" +#include "timing.hpp" #include #include -#define TOP (1 - pos) -#define BOTTOM pos +Font fontTtf; -Rectangle TextInSpace(Rectangle box, float textH, float textW, float margin, bool topOrBottom, bool leftOrRigth) +void DrawTextB(const char *text, float posX, float posY, int fontSize, Color color) { - float br = box.width / box.height; - float tr = textW / textH; - - Rectangle ret = {0, 0, 0, 0}; - - float hm = box.height * margin; - float wm = box.width * margin; - - ret.height = box.height - hm; - ret.width = box.width - wm; - - if (br < tr) - { - // bolj kvadrat izracunaj visino iz sirine - ret.height = ret.width / tr; - } - else - { - // bolj podolgovat izracunaj sirino iz visine - ret.width = ret.height * tr; - } - - if (topOrBottom) - { - ret.y = box.y + hm; - } - else - { - ret.y = box.y + box.height - hm - ret.height; - } - - if (leftOrRigth) - { - ret.x = box.x + wm; - } - else - { - ret.x = box.x + box.width - wm - ret.width; - } - return ret; + DrawTextEx(fontTtf, text, (Vector2){ posX, posY }, fontSize, 1, color); } -// Dimentions for font size 20 -// DISLIKE 83 -// LIKE 46 -// GEN 9999: 999/999 -> 200 -constexpr float textMargin = 0.02f; - void App::init(int screenWidth, int screenHeight) { + fontTtf = LoadFontEx("res/CascadiaCode.ttf", 32, 0, 0); + SetTextLineSpacing(16); this->screenWidth = screenWidth; this->screenHeight = screenHeight; this->canvas.init(screenWidth); - // int s = MeasureText("GEN 9999: 999/999", 20); - // TraceLog(LOG_INFO, "%d", s); - for (size_t i = 0; i < canvasTexure.size(); i++) - { - canvasTexure[i] = LoadRenderTexture(screenWidth, screenWidth); - } + canvasTexure = LoadRenderTexture(screenWidth, screenWidth); DnaStore::load(&manager); - simil = Similarity::calc_similarity(manager.vector); upTex(Liked::tbd); - while (!canvas.tick(canvasTexure[TOP])) + while (!canvas.tick(canvasTexure)) { // wait to finish drawing } - pos = 1 - pos; - upTex(Liked::tbd); - while (!canvas.tick(canvasTexure[TOP])) - { - // wait to finish drawing - } - pos = 1 - pos; float posY = (screenHeight - screenWidth) / 2.0f; - likedTextBox = TextInSpace({0, - 0, - (float)screenWidth / 2.0f, - posY}, - 20.0f, 83.0f, textMargin, false, true); - - genTextBox = TextInSpace({0, - posY + screenWidth, - (float)screenWidth, - posY}, - 20.0f, 200.0f, textMargin, true, true); - - simTextBox = TextInSpace({(float)screenWidth / 2.0f, - likedTextBox.y, - (float)screenWidth / 2.0f, - likedTextBox.height}, - 20.0f, 60.0f, textMargin, false, false); - - destB = {0, posY, (float)screenWidth, (float)screenWidth}; - destA = destB; - - float recPosX = screenWidth * 0.3f; - disLikeBox = {0, posY, (float)recPosX, (float)screenWidth}; - likeBox = {screenWidth - recPosX, posY, (float)recPosX, (float)screenWidth}; - - if(!DnaStore::ping()){ - appColor = RED; - } + destA = {0, posY, (float)screenWidth, (float)screenWidth}; } void App::upTex(Liked liked) { if (liked != Liked::tbd) { - unit[TOP].liked = liked; - bool ng = DnaManager::like(unit[TOP], &manager); + unit.liked = liked; + bool ng = DnaManager::like(unit, &manager); if (ng) { DnaStore::saveGen(&manager); DnaManager::newGen(&manager); DnaStore::saveVec(&manager); - simil = Similarity::calc_similarity(manager.vector); } DnaStore::saveData(&manager); } - unit[TOP] = DnaManager::next(&manager); - if (unit[TOP].dna != nullptr) + unit = DnaManager::next(&manager); + if (unit.dna != nullptr) { - canvas.newGen(canvasTexure[TOP], unit[TOP].dna); + canvas.newGen(canvasTexure, unit.dna); return; } - BeginTextureMode(canvasTexure[TOP]); + BeginTextureMode(canvasTexure); ClearBackground(BLACK); DrawText("NEXT GEN", 10, 10, screenWidth/10, WHITE); EndTextureMode(); } -void App::update() -{ - bool isDone = canvas.tick(canvasTexure[BOTTOM]); - Vector2 mousePosition = GetMousePosition(); - if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) - { - mouseStart = mousePosition; - validHit = CheckCollisionPointRec(mouseStart, destA); - len = Vector2Distance(mouseStart, {destB.x, destB.y}); - ofset = std::atan2(destB.x - mouseStart.x, destB.y - mouseStart.y); - } +void App::update(){} - if (IsMouseButtonDown(MOUSE_BUTTON_LEFT) && validHit) - { - float dist = mousePosition.x - mouseStart.x; - float l = dist / screenWidth; - rotation = Lerp(45.0f, -45.0f, (l + 1) / 2); +enum class Rend_type{ + every_frame, + in_one_frame, + over_frames, +}; - float angle = ((rotation)*PI) / 180.0f; - angle += ofset; - Vector2 newCenter = {.x = len * std::sin(angle), .y = len * std::cos(angle)}; - - destA.x = newCenter.x + mousePosition.x; - destA.y = newCenter.y + mousePosition.y; - - if (CheckCollisionPointRec(mousePosition, disLikeBox)) - { - topLiked = Liked::no; - } - else if (CheckCollisionPointRec(mousePosition, likeBox)) - { - topLiked = Liked::yes; - } - else - { - topLiked = Liked::tbd; - } - } - - if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT) && validHit) - { - if (isDone) - { - if (topLiked != Liked::tbd) - { - upTex(topLiked); - pos = 1 - pos; // switch bottom and top - } - } - rotation = 0.0f; - destA = destB; - topLiked = Liked::tbd; - } -} +constexpr Rend_type rend_type = Rend_type::over_frames; void App::draw() { - ClearBackground(appColor); + if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) + { + TraceLog(LOG_INFO, "CLICK"); + upTex(Liked::yes); + if constexpr (rend_type == Rend_type::in_one_frame){ + while (!canvas.tick(canvasTexure)) + { + // wait to finish drawing + } + } + } + if constexpr (rend_type == Rend_type::over_frames){ + canvas.tick(canvasTexure); + } + ClearBackground(BLUE); + int fps = GetFPS(); + const char* fpstext = TextFormat("%04d FPS", fps); + DrawTextB(fpstext, 10, 10, 36, BLACK); + const char* ctext = TextFormat("%04ld Circles", canvas.tree.circles); + DrawTextB(ctext, 10, 50, 36, BLACK); + Rectangle source = {0, 0, (float)screenWidth, (float)-screenWidth}; Vector2 origin = {0.0f, 0.0f}; - - DrawTexturePro(canvasTexure[BOTTOM].texture, source, destB, origin, 0.0f, WHITE); - - DrawTexturePro(canvasTexure[TOP].texture, source, destA, origin, 360 - rotation, WHITE); - - const char *textGen = TextFormat("GEN %d: %d / %d", manager.generation, unit[TOP].index + 1, NUM_PER_GEN); - DrawText(textGen, genTextBox.x, genTextBox.y, genTextBox.height, BLACK); - const char *textProc = TextFormat("%.1f%%", simil); - DrawText(textProc, simTextBox.x, simTextBox.y, simTextBox.height, BLACK); - switch (topLiked) - { - case Liked::yes: - DrawText("LIKED", likedTextBox.x, likedTextBox.y, likedTextBox.height, BLACK); - break; - case Liked::no: - DrawText("DISLIKE", likedTextBox.x, likedTextBox.y, likedTextBox.height, BLACK); - break; - default: - break; + if constexpr (rend_type == Rend_type::every_frame){ + canvas.newGen(canvasTexure, unit.dna); + while (!canvas.tick(canvasTexure)) + { + // wait to finish drawing + } } + DrawTexturePro(canvasTexure.texture, source, destA, origin, 360, WHITE); } void App::deinit() { - for (size_t i = 0; i < canvasTexure.size(); i++) - { - UnloadRenderTexture(canvasTexure[i]); - } + UnloadRenderTexture(canvasTexure); + UnloadFont(fontTtf); canvas.deinit(); } \ No newline at end of file diff --git a/app/src/main.cpp b/app/src/main.cpp index d5482f4..2949301 100644 --- a/app/src/main.cpp +++ b/app/src/main.cpp @@ -1,5 +1,6 @@ #include #include "App.hpp" +#include "timing.hpp" #if defined(PLATFORM_WEB) #include @@ -7,12 +8,14 @@ static App app; +Timer t; void UpdateDrawFrame() { - app.update(); + t.reset_and_start(); BeginDrawing(); app.draw(); EndDrawing(); + t.stop_and_print("to draw frame"); } int main(void) @@ -34,7 +37,7 @@ int main(void) #if defined(PLATFORM_WEB) emscripten_set_main_loop(UpdateDrawFrame, 0, 1); #else - SetTargetFPS(60); + // SetTargetFPS(60); while (!WindowShouldClose()) { UpdateDrawFrame(); diff --git a/shared/inc/canvas/Canvas.hpp b/shared/inc/canvas/Canvas.hpp index 5d17fb5..65c7f56 100644 --- a/shared/inc/canvas/Canvas.hpp +++ b/shared/inc/canvas/Canvas.hpp @@ -13,7 +13,6 @@ public: void newGen(RenderTexture2D &target, Dna *dna); bool tick(RenderTexture2D &target); -private: BackGround backGround; Tree tree; }; diff --git a/shared/inc/canvas/Tree.hpp b/shared/inc/canvas/Tree.hpp index e4ab0ac..0eb554c 100644 --- a/shared/inc/canvas/Tree.hpp +++ b/shared/inc/canvas/Tree.hpp @@ -23,6 +23,7 @@ public: void init(int size); void draw(Dna *dna); bool tick(); + uint64_t circles; private: Dna *m_dna; @@ -34,7 +35,8 @@ private: void calculateBranch(); - void drawBranch(Vector2 startPoint, Vector2 endPoint, Color startColor, Color endColor, float startThickness, float endThickness); + void drawBranch_rlTriangle(Vector2 startPoint, Vector2 endPoint, Color startColor, Color endColor, float startThickness, float endThickness, float length); + void drawBranch_circles(Vector2 startPoint, Vector2 endPoint, Color startColor, Color endColor, float startThickness, float endThickness, float length); inline size_t getNumOfBranches(int dep); inline Color getStartColor(DrawArgs &arg); inline Color getEndColor(int dep, Color &start); diff --git a/shared/inc/timing.hpp b/shared/inc/timing.hpp new file mode 100644 index 0000000..a9d642e --- /dev/null +++ b/shared/inc/timing.hpp @@ -0,0 +1,18 @@ + +#include + + +struct Timer +{ + std::chrono::steady_clock::time_point start_t; + std::chrono::steady_clock::time_point end_t; + std::chrono::nanoseconds dur; + void start(); + void stop(); + void reset(); + void print(const char * str); + void stop_and_print(const char * str); + void reset_and_start(); +}; + + diff --git a/shared/src/canvas/Canvas.cpp b/shared/src/canvas/Canvas.cpp index ab9eee0..379c503 100644 --- a/shared/src/canvas/Canvas.cpp +++ b/shared/src/canvas/Canvas.cpp @@ -1,4 +1,5 @@ #include "canvas/Canvas.hpp" +#include "timing.hpp" void Canvas::init(int size) { @@ -6,8 +7,13 @@ void Canvas::init(int size) tree.init(size); } +bool finished = false; +Timer timer; void Canvas::newGen(RenderTexture2D &target, Dna *dna) { + + finished = false; + timer.reset_and_start(); BeginTextureMode(target); ClearBackground(WHITE); @@ -15,13 +21,20 @@ void Canvas::newGen(RenderTexture2D &target, Dna *dna) tree.draw(dna); EndTextureMode(); + timer.stop(); } bool Canvas::tick(RenderTexture2D &target) { + timer.start(); BeginTextureMode(target); bool ret = tree.tick(); EndTextureMode(); + timer.stop(); + if(ret && !finished){ + finished = true; + timer.print("to draw canvas"); + } return ret; } diff --git a/shared/src/canvas/Tree.cpp b/shared/src/canvas/Tree.cpp index 3ffb08d..7ff4a5e 100644 --- a/shared/src/canvas/Tree.cpp +++ b/shared/src/canvas/Tree.cpp @@ -1,12 +1,13 @@ #include #include "canvas/Tree.hpp" +#include "timing.hpp" #include #include #include -#define ITER_PER_FRAME 5000 +#define ITER_PER_FRAME 10000 constexpr int maxColorChange = 15; constexpr int minColorChange = -15; @@ -46,22 +47,23 @@ void Tree::init(int size) void Tree::draw(Dna *dna) { + circles = 0; m_dna = dna; branchSeed = dna->branchSeed; drawCalls.push_back({start, 180.0f, 0}); - tick(); } bool Tree::tick() { - size_t i = 0; - while (!drawCalls.empty()) + using namespace std::chrono; + auto start = steady_clock::now(); + nanoseconds dur = 0us; + while (!drawCalls.empty() && dur < 14ms) { calculateBranch(); drawCalls.pop_front(); - i++; - if (i >= ITER_PER_FRAME) - break; + auto end = steady_clock::now(); + dur = end - start; } return drawCalls.empty(); @@ -83,20 +85,13 @@ void Tree::calculateBranch() int sizeStart = getStartSize(arg); int sizeEnd = getEndSize(arg, sizeStart); - float fstep = 1.0 / ((length / sizeStart) * 2.0f); Color colorStart = getStartColor(arg); Color colorEnd = getEndColor(arg.dep, colorStart); - // drawBranch(arg.start, end, colorStart, colorEnd, sizeStart, sizeEnd); - for (float i = 0; i < 1; i += fstep) - { - Vector2 point = Vector2Lerp(arg.start, end, i); - Color color = ColorLerp(colorStart, colorEnd, i); - int size = Lerp(sizeStart, sizeEnd, i); - DrawCircleV(point, size, color); - // DrawTextureEx(texBunny, point,0, ((float)size) / texBunny.height, color); - } - + // drawBranch_rlTriangle(arg.start, end, colorStart, colorEnd, sizeStart, sizeEnd, length); + drawBranch_circles(arg.start, end, colorStart, colorEnd, sizeStart, sizeEnd, length); + // DrawLineEx(arg.start, end, sizeStart, colorStart); + // add more branches to draw if (arg.dep + 1 >= MAX_DEPTH) @@ -114,6 +109,7 @@ void Tree::calculateBranch() inline size_t Tree::getNumOfBranches(int dep) { + return 3; if (m_dna->branches[dep].branchCount < 128) return 2; else @@ -163,7 +159,7 @@ inline int Tree::getStartSize(DrawArgs &arg) float mixLevel = m_dna->branches[arg.dep].sizeLevel / 255.0f; size = std::lerp(size, sizes[MAX_DEPTH - arg.dep - 1], mixLevel); - if (size < 1) + //if (size < 1) size = 1; return size; } @@ -173,7 +169,7 @@ inline int Tree::getEndSize(DrawArgs &arg, int start) int size = Remap(m_dna->branches[arg.dep].sizeChange, 0, 255, MinSizeChange, maxSizeChange); size += start; - if (size < 1) + //if (size < 1) size = 1; return size; } @@ -181,9 +177,9 @@ inline int Tree::getEndSize(DrawArgs &arg, int start) inline float Tree::getLength(DrawArgs &arg) { float lenght = lengths[arg.dep]; - float lenghtRatio = Remap(m_dna->branches[arg.dep].length, 0, 255, 0.5f, 1.3f); + float lenghtRatio = Remap(255, 0, 255, 0.5f, 1.3f); lenght *= lenghtRatio; - float lenghtVar = Remap(m_dna->branches[arg.dep].lengthVar, 0, 255, -0.15f, 0.15f); + float lenghtVar = Remap(255, 0, 255, -0.15f, 0.15f); lenght += lenght * lenghtVar * mrand::getFloat(&branchSeed); if (lenght < 1) lenght = 1; @@ -199,15 +195,28 @@ inline float Tree::getAngleVar(DrawArgs &arg) return angleVar; } -void Tree::drawBranch(Vector2 startPoint, Vector2 endPoint, Color startColor, Color endColor, float startThickness, float endThickness) +void Tree::drawBranch_circles(Vector2 startPoint, Vector2 endPoint, Color startColor, Color endColor, float startThickness, float endThickness, float length) +{ + + float fstep = 1.0 / ((length / startThickness) * 2.0f); + for (float i = 0; i < 1; i += fstep) + { + Vector2 point = Vector2Lerp(startPoint, endPoint, i); + Color color = ColorLerp(startColor, endColor, i); + int size = Lerp(startThickness, endThickness, i); + DrawCircleV(point, size, color); + circles++; + } +} + +void Tree::drawBranch_rlTriangle(Vector2 startPoint, Vector2 endPoint, Color startColor, Color endColor, float startThickness, float endThickness, float length) { + DrawCircleV(startPoint, startThickness, startColor); + DrawCircleV(endPoint, endThickness, endColor); // Calculate the direction vector from startPoint to endPoint Vector2 direction = {endPoint.x - startPoint.x, endPoint.y - startPoint.y}; // Normalize the direction vector - float length = sqrtf(direction.x * direction.x + direction.y * direction.y); - if (length == 0) - length = 1; // Avoid division by zero Vector2 normalizedDir = {direction.x / length, direction.y / length}; // Calculate the perpendicular vector (rotate 90 degrees) diff --git a/shared/src/timing.cpp b/shared/src/timing.cpp new file mode 100644 index 0000000..1468f2e --- /dev/null +++ b/shared/src/timing.cpp @@ -0,0 +1,42 @@ +#include +#include +#include "timing.hpp" + +using namespace std::chrono; + +void Timer::start() +{ + start_t = std::chrono::steady_clock::now(); +} + +void Timer::stop() +{ + end_t = std::chrono::steady_clock::now(); + dur += end_t - start_t; +} + +void Timer::reset() +{ + dur = 0ns; +} + +void Timer::print(const char * str) +{ + auto s = std::chrono::duration_cast(dur); + if (s > 1000us) + { + TraceLog(LOG_INFO, "%ld ms %s", s.count(), str); + } +} + +void Timer::stop_and_print(const char *str) +{ + stop(); + print(str); +} + +void Timer::reset_and_start() +{ + reset(); + start(); +}