#ifndef SHADER_AUTOMATON_PROGRAM_H #define SHADER_AUTOMATON_PROGRAM_H #include "options.h" #include #include #include #include class Program { public: explicit Program(Options opts); ~Program(); void run(); void keyCallback(int key, int scancode, int action, int mods); private: struct BufferInfo { GLuint bufferName; GLuint bindingPoint; }; void createWindow(); [[nodiscard]] GLsync startCompute(BufferInfo in, BufferInfo out) const; void renderFrame(BufferInfo from, BufferInfo to, double step) const; void renderUI(); void initializeFirstBuffer(BufferInfo buffer) const; void toggleFullscreen(); void imguiMainWindow(); void imguiCloseWindow(); Options options; GLFWwindow *window{}; int window_pos_x{}; int window_pos_y{}; int window_width{}; int window_height{}; GLuint renderProgram{}; GLuint renderBlockIndexFrom{}; GLuint renderBlockIndexTo{}; GLint renderPreviewColormapLoc{}; GLint renderDimensionsLoc{}; GLint renderShowMaxAgeLoc{}; GLint renderGlobalMaxAgeLoc{}; GLint renderGlobalMinimumMaxAgeLoc{}; GLint renderBlendStepLoc{}; GLint renderDeadColorLoc{}; GLint renderDeadColorIsCielabLoc{}; GLint renderLivingColorLoc{}; GLint renderLivingColormapLoc{}; GLint renderLivingUseColormapLoc{}; GLint renderLivingColormapInvertLoc{}; GLint renderLivingColormapScaleLoc{}; GLint renderLivingColormapScaleIsMaxAgeLoc{}; GLint renderLivingColorIsCielabLoc{}; GLuint computeProgram{}; GLuint computeBlockIndexInput{}; GLuint computeBlockIndexOutput{}; GLint computeDimensionsLoc{}; GLint computeBirthRuleLoc{}; GLint computeSurviveRuleLoc{}; GLint computeStarveDelayLoc{}; GLint computeStarveRecoverLoc{}; GLint computeHasMaxAgeLoc{}; std::map colormap_textures{}; GLuint vertexBuffer{}; GLFWmonitor *fullscreenMonitor{}; bool is_fullscreen = false; bool show_ui = false; bool show_close_popup = false; bool is_paused{}; // todo uint8_t render_max_age{}; bool preview_colormap{}; void debugPrintBuffer(const std::string &text, BufferInfo buffer) const { return; auto width = options.automaton_options.width; auto height = options.automaton_options.height; glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer.bufferName); auto *bufferData = static_cast(glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY)); std::cout << "=====[" << text << " (" << buffer.bufferName << ")]=====" << std::endl; auto offset = width * height; for (size_t ix = 0; ix < width; ++ix) { for (size_t iy = 0; iy < height; ++iy) { std::cout << std::format("max-age at {}, {}: {}",ix, iy, bufferData[offset + ix + iy * width]) << std::endl; } } std::cout << "===============" << std::endl << std::endl; std::cout << std::flush; glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); } void imguiAutomatonTab(); void imguiDisplayTab(); bool imguiBirthConditionTable(bool apply_changes, bool revert_changes); bool imguiMaxAge(bool apply_changes, bool revert_changes); bool imguiSurviveConditionTable(bool apply_changes, bool revert_changes); bool imguiStarve(bool apply_changes, bool revert_changes); void imguiDeadCells(); void imguiLivingCells(); uint32_t makeRuleBitfield(const std::vector &rule) const; void initializeMaxAge(BufferInfo buffer, uint64_t generation) const; }; #endif // SHADER_AUTOMATON_PROGRAM_H