#include "pch.h" #include "app.h" App App::I; // singleton void App::create() { width = 800; height = 500; } void App::init() { static const char* shader_v = "#version 150\n" "uniform mat4 mvp;" "in vec4 pos;" "in vec2 uvs;" "out vec3 uv;" "void main(){" " uv = vec3(uvs, pos.w);" " gl_Position = mvp * vec4(pos.xyz, 1.f);" "}"; static const char* shader_f = "#version 150\n" "uniform sampler2D tex;" "in vec3 uv;" "out vec4 frag;" "void main(){" //" frag = texture(tex, uv.xy/uv.z);" " frag = texture(tex, uv.xy);" "}"; static const char* shader_uv_f = "#version 150\n" "uniform sampler2D tex;" "in vec3 uv;" "out vec4 frag;" "void main(){" " frag = vec4(uv.xy,0,1);" "}"; static const char* shader_atlas_v = "#version 150\n" "uniform mat4 mvp;" "uniform vec2 tof;" "uniform vec2 tsz;" "in vec2 pos;" "in vec2 uvs;" "out vec2 uv;" "void main(){" " uv = tof + uvs * tsz;" " gl_Position = mvp * vec4(pos, 0, 1);" "}"; static const char* shader_atlas_f = "#version 150\n" "uniform sampler2D tex;" "in vec2 uv;" "out vec4 frag;" "void main(){" " frag = texture(tex, uv);" "}"; static const char* shader_color_v = "#version 150\n" "uniform mat4 mvp;" "in vec4 pos;" "void main(){" " gl_Position = mvp * pos;" "}"; static const char* shader_color_f = "#version 150\n" "uniform vec4 col;" "out vec4 frag;" "void main(){" " frag = col;" "}"; static const char* shader_font_v = "#version 150\n" "uniform mat4 mvp;" "in vec2 pos;" "in vec2 uvs;" "out vec2 uv;" "void main(){" " uv = uvs;" " gl_Position = mvp * vec4(pos, 0, 1);" "}"; static const char* shader_font_f = "#version 150\n" "uniform sampler2D tex;" "uniform vec4 col;" "in vec2 uv;" "out vec4 frag;" "void main(){" " float a = texture(tex, uv).r;" " frag = vec4(col.rgb, a);" "}"; #ifdef _WIN32 static CONSOLE_SCREEN_BUFFER_INFO info; GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info); // colors: http://stackoverflow.com/questions/4053837/colorizing-text-in-the-console-with-c glDebugMessageCallback([](GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam) { static std::map colors = { { GL_DEBUG_SEVERITY_NOTIFICATION, 8 }, { GL_DEBUG_SEVERITY_LOW, 8 }, { GL_DEBUG_SEVERITY_MEDIUM, FOREGROUND_GREEN | FOREGROUND_INTENSITY }, { GL_DEBUG_SEVERITY_HIGH, FOREGROUND_RED | FOREGROUND_INTENSITY }, }; SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colors[severity]); printf("%.*s\n", length, message); FlushConsoleInputBuffer(GetStdHandle(STD_OUTPUT_HANDLE)); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), info.wAttributes); }, nullptr); glEnable(GL_DEBUG_OUTPUT); #endif #if _WIN32 const char* ttf = "C:\\Windows\\Fonts\\arial.ttf"; #else const char* ttf = "/Library/Fonts/Arial.ttf"; #endif FontManager::init(); FontManager::load(kFont::Arial_11, ttf, 15); FontManager::load(kFont::Arial_30, ttf, 30); NodeBorder::static_init(); NodeImage::static_init(); NodeIcon::static_init(); layout.on_loaded = [&] { layout[main_id]->update(width, height); if (auto* button = layout[main_id]->find("btn-close")) { button->on_click = [] { exit(0); }; } if (auto* button = layout[main_id]->find("btn-popup")) { button->on_click = [this] { msgbox = new NodeMessageBox(); msgbox->m_manager = &layout; msgbox->init(); layout[main_id]->add_child(msgbox); layout[main_id]->update(); }; } if (auto* button = layout[main_id]->find("btn-settings")) { button->on_click = [this] { settings = new NodeSettings(); settings->m_manager = &layout; settings->init(); layout[main_id]->add_child(settings); layout[main_id]->update(); }; } if (auto* menu_file = layout[main_id]->find("menu-file")) { menu_file->on_click = [=] { glm::vec2 pos = menu_file->m_pos + glm::vec2(0, menu_file->m_size.y); popup = (NodePopupMenu*)layout[const_hash("file-menu")]->m_children[0]->clone(); popup->SetPositioning(YGPositionTypeAbsolute); popup->SetPosition(pos.x, pos.y); layout[main_id]->add_child(popup); layout[main_id]->update(); }; } if (auto* menu_file = layout[main_id]->find("menu-edit")) { menu_file->on_click = [=] { glm::vec2 pos = menu_file->m_pos + glm::vec2(0, menu_file->m_size.y); popup = (NodePopupMenu*)layout[const_hash("edit-menu")]->m_children[0]->clone(); popup->SetPositioning(YGPositionTypeAbsolute); popup->SetPosition(pos.x, pos.y); layout[main_id]->add_child(popup); layout[main_id]->update(); }; } if (auto* menu_file = layout[main_id]->find("menu-layers")) { menu_file->on_click = [=] { glm::vec2 pos = menu_file->m_pos + glm::vec2(0, menu_file->m_size.y); popup = (NodePopupMenu*)layout[const_hash("layers-menu")]->m_children[0]->clone(); popup->SetPositioning(YGPositionTypeAbsolute); popup->SetPosition(pos.x, pos.y); layout[main_id]->add_child(popup); layout[main_id]->update(); }; } if (auto* toolbar = layout[main_id]->find("toolbar")) { toolbar->m_flood_events = true; } }; layout.load("data/layout2.xml"); //msgbox->find("btn-ok")->on_click = [] { exit(0); }; // msgbox->find("btn-ok")->m_text->m_text = "DO"; // msgbox->find("btn-ok")->m_text->create(); sampler.create(GL_NEAREST); ShaderManager::create(kShader::Texture, shader_v, shader_f); ShaderManager::create(kShader::Color, shader_color_v, shader_color_f); ShaderManager::create(kShader::UVs, shader_v, shader_uv_f); ShaderManager::create(kShader::Font, shader_font_v, shader_font_f); ShaderManager::create(kShader::Atlas, shader_atlas_v, shader_atlas_f); if (!tex.load("data/uvs.jpg")) printf("error loading image\n"); glEnable(GL_TEXTURE_2D); glDisable(GL_DEPTH_TEST); glPointSize(5); glLineWidth(2); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendEquation(GL_FUNC_ADD); //int n; //glGetIntegerv(GL_NUM_EXTENSIONS, &n); //for (int i = 0; i < n; i++) //{ // const unsigned char* s = glGetStringi(GL_EXTENSIONS, i); // printf("GL ext %03d: %s\n", i, s); //} printf("GL version: %s\n", glGetString(GL_VERSION)); printf("GL vendor: %s\n", glGetString(GL_VENDOR)); printf("GL renderer: %s\n", glGetString(GL_RENDERER)); GLfloat width_range[2]; glGetFloatv(GL_LINE_WIDTH_RANGE, width_range); printf("GL line range: %f - %f\n", width_range[0], width_range[1]); } void App::update(float dt) { glClearColor(.1f, .1f, .1f, 1.f); glViewport(0, 0, (GLsizei)width, (GLsizei)height); glClear(GL_COLOR_BUFFER_BIT); layout.reload(); auto observer = [this](Node* n) { if (n && n->m_display) { auto box = n->m_clip; glScissor((int)box.x-1, (int)(height - box.y - box.w)-1, (int)box.z+2, (int)box.w+2); n->draw(); } }; glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glEnable(GL_SCISSOR_TEST); if (auto* main = layout[main_id]) main->watch(observer); //msgbox->watch(observer); glDisable(GL_SCISSOR_TEST); } void App::resize(float w, float h) { width = w; height = h; if (auto* main = layout[main_id]) main->update(w, h); } void App::mouse_down(int button, float x, float y) { MouseEvent e; e.m_type = button ? kEventType::MouseDownR : kEventType::MouseDownL; e.m_pos = { x, y }; layout[main_id]->on_event(&e); printf("mouse click %f %f\n", x, y); // NodeBorder* n = new NodeBorder(); // n->SetPositioning(YGPositionTypeAbsolute); // n->SetWidth(100); // n->SetHeight(100); // n->SetPosition(x, y); // n->m_color = glm::vec4(.5, .5, .5, .5); // layout[main_id].add_child(n); // layout[main_id].update(width, height); if (popup) { layout[main_id]->remove_child(popup); popup = nullptr; } if (button == 1) { popup = (NodePopupMenu*)layout[const_hash("popup-menu")]->m_children[0]->clone(); popup->SetPositioning(YGPositionTypeAbsolute); popup->SetPosition(x, y); layout[main_id]->add_child(popup); } layout[main_id]->update(); } void App::mouse_move(float x, float y) { MouseEvent e; e.m_type = kEventType::MouseMove; e.m_pos = { x, y }; if (auto* main = layout[main_id]) main->on_event(&e); } void App::mouse_up(int button, float x, float y) { MouseEvent e; e.m_type = button ? kEventType::MouseUpR : kEventType::MouseUpL; e.m_pos = { x, y }; layout[main_id]->on_event(&e); layout[main_id]->update(); }