#include <pattern_handler.hpp> PatternHandler::PatternHandler(Toolbox& tb) : shader_((tb.shader_path + "copy_texture.vert").c_str(), (tb.shader_path + "copy_texture.frag").c_str()) { shader_.use(); shader_.setInt("source_texture", 0); /*Framebuffer*/ glGenFramebuffers(1, &fbo_static_); glBindFramebuffer(GL_FRAMEBUFFER, fbo_static_); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tb.tex_damp_static, 0); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { std::cout << "ERROR::FRAMEBUFFER: Blockchain Framebuffer not complete!" << std::endl; } glBindFramebuffer(GL_FRAMEBUFFER, 0); /*VBO data*/ std::vector<float> vbo_data = { /* x y u v*/ /*blc*/ -1.f, -1.f, 0.f, 0.f, /*trc*/ 1.f, 1.f, 1.f, 1.f, /*brc*/ 1.f, -1.f, 1.f, 0.f, /*blc*/ -1.f, -1.f, 0.f, 0.f, /*trc*/ 1.f, 1.f, 1.f, 1.f, /*tlc*/ -1.f, 1.f, 0.f, 1.f }; /*vao, vbo*/ glGenVertexArrays(1, &vao_); glGenBuffers(1, &vbo_); glBindVertexArray(vao_); glBindBuffer(GL_ARRAY_BUFFER, vbo_); glBufferData(GL_ARRAY_BUFFER, vbo_data.size() * sizeof(float), vbo_data.data(), GL_STATIC_DRAW); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float))); glEnableVertexAttribArray(1); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); /*Load structure textures*/ std::cout << "Loading slit.tex" << std::endl; load_damping_texture_(tb, tb.texture_path + "slit", &texture_singleslit_); std::cout << "Loading doubleslit.tex" << std::endl; load_damping_texture_(tb, tb.texture_path + "doubleslit", &texture_doubleslit_); std::cout << "Loading square.tex" << std::endl; load_damping_texture_(tb, tb.texture_path + "square", &texture_lattice_); std::cout << "Loading channel.tex" << std::endl; load_damping_texture_(tb, tb.texture_path + "channel", &texture_waveguide_); std::cout << "Loading ssh.tex" << std::endl; load_damping_texture_(tb, tb.texture_path + "ssh", &texture_ssh_); std::cout << "Loading fresnel.tex" << std::endl; load_damping_texture_(tb, tb.texture_path + "fresnel", &texture_fresnel_); } void PatternHandler::update(Toolbox& tb) { /*Handle messages*/ for (Message& m : tb.mailbox) { if (m.target == MESSAGETARGET::PATTERN) { PATTERNMESSAGE message = std::get<PATTERNMESSAGE>(m.message); switch (message) { case PATTERNMESSAGE::PATTERN_SINGLESLIT: queued_texture_ = texture_singleslit_; break; case PATTERNMESSAGE::PATTERN_DOUBLESLIT: queued_texture_ = texture_doubleslit_; break; case PATTERNMESSAGE::PATTERN_LATTICE: queued_texture_ = texture_lattice_; break; case PATTERNMESSAGE::PATTERN_WAVEGUIDE: queued_texture_ = texture_waveguide_; break; case PATTERNMESSAGE::PATTERN_SSH: queued_texture_ = texture_ssh_; break; case PATTERNMESSAGE::PATTERN_FRESNEL: queued_texture_ = texture_fresnel_; break; default: break; } } } /*Draw pattern, if requested*/ if (queued_texture_ != 0) { glBindVertexArray(vao_); glBindBuffer(GL_ARRAY_BUFFER, vbo_); glViewport(0, 0, tb.texture_w, tb.texture_h); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, queued_texture_); shader_.use(); glBindFramebuffer(GL_FRAMEBUFFER, fbo_static_); glDrawArrays(GL_TRIANGLES, 0, 6); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0); /*Reset queued texture*/ queued_texture_ = 0; } } bool PatternHandler::load_damping_texture_(const Toolbox& tb, const std::string filename, GLuint* texture_target) { /*Load info about the texture from configuration file*/ int screen_width, screen_height, texture_width, texture_height; int texoffset_left, texoffset_right, texoffset_bottom, texoffset_top; std::string config_filename = filename + ".conf"; std::fstream cfg_file; cfg_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); try { cfg_file.open(config_filename); cfg_file >> screen_width; cfg_file >> screen_height; cfg_file >> texture_width; cfg_file >> texture_height; cfg_file >> texoffset_left; cfg_file >> texoffset_right; cfg_file >> texoffset_bottom; cfg_file >> texoffset_top; cfg_file.close(); } catch (std::ifstream::failure e) { std::cout << "Failed to open file " + config_filename << std::endl; return false; } #ifndef NDEBUG std::cout << "Loaded configuration from " + config_filename; std::cout << "\n\tScreen Resolution: " << screen_width << "x" << screen_height; std::cout << "\n\tTexture Resolution: " << texture_width << "x" << texture_height; std::cout << "\n\tOffset Left: " << texoffset_left; std::cout << "\n\tOffset Right: " << texoffset_right; std::cout << "\n\tOffset Bottom: " << texoffset_bottom; std::cout << "\n\tOffset Top: " << texoffset_top << std::endl; #endif /*Check if configuration is compatible with toolbox settings*/ if (tb.screen_h != screen_height || tb.screen_w != screen_width) { std::cout << "Incompatible Toolbox Screen Resolution: " << tb.screen_w << "x" << tb.screen_h << std::endl; return false; } else if (tb.texture_h != texture_height || tb.texture_w != texture_width) { std::cout << "Incompatible Toolbox Texture Resolution: " << tb.texture_w << "x" << tb.texture_h << std::endl; return false; } else if (tb.texoffset_left != texoffset_left || tb.texoffset_right != texoffset_right || tb.texoffset_bottom != texoffset_bottom || tb.texoffset_top != texoffset_top) { std::cout << "Incompatible Offsets" << std::endl; return false; } /*Load texture data*/ #ifndef NDEBUG else { std::cout << "Texture is compatible" << std::endl; } std::cout << "Loading Texture" << std::endl; #endif std::fstream dmp_file; std::string damping_filename = filename + ".texture"; std::vector<float> data_target; data_target.reserve(4 * texture_width * texture_height); dmp_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); try { dmp_file.open(damping_filename); float value; for (size_t i = 0; i < 4 * texture_width * texture_height; ++i) { /*If the file is finished at this point, we're fucked*/ if (dmp_file.peek() == EOF) { std::cout << "Unexpected End Of Damping File Encountered" << std::endl; data_target.clear(); return false; } dmp_file >> value; data_target.push_back(value); } dmp_file.close(); } catch (std::ifstream::failure e) { std::cout << "Failed to open file " + damping_filename << std::endl; return false; } /*Generate and upload texture*/ glGenTextures(1, texture_target); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, *texture_target); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, texture_width, texture_height, 0, GL_RGBA, GL_FLOAT, data_target.data()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glBindTexture(GL_TEXTURE_2D, 0); return true; }