319 lines
9.8 KiB
C++
319 lines
9.8 KiB
C++
#include "pch.h"
|
|
#include "app.h"
|
|
|
|
App App::I; // singleton
|
|
|
|
void App::create()
|
|
{
|
|
width = 800;
|
|
height = 500;
|
|
}
|
|
|
|
void App::initShaders()
|
|
{
|
|
static const char* shader_v =
|
|
"#version 300 es\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 300 es\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 300 es\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 300 es\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 300 es\n"
|
|
"uniform sampler2D tex;"
|
|
"in vec2 uv;"
|
|
"out vec4 frag;"
|
|
"void main(){"
|
|
" frag = texture(tex, uv);"
|
|
"}";
|
|
static const char* shader_color_v =
|
|
"#version 300 es\n"
|
|
"uniform mat4 mvp;"
|
|
"in vec4 pos;"
|
|
"void main(){"
|
|
" gl_Position = mvp * pos;"
|
|
"}";
|
|
static const char* shader_color_f =
|
|
"#version 300 es\n"
|
|
"uniform vec4 col;"
|
|
"out vec4 frag;"
|
|
"void main(){"
|
|
" frag = col;"
|
|
"}";
|
|
static const char* shader_font_v =
|
|
"#version 300 es\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 300 es\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);"
|
|
"}";
|
|
|
|
if (!ShaderManager::create(kShader::Texture, shader_v, shader_f))
|
|
LOG("Failed to create shader Texture");
|
|
if (!ShaderManager::create(kShader::Color, shader_color_v, shader_color_f))
|
|
LOG("Failed to create shader Color");
|
|
if (!ShaderManager::create(kShader::UVs, shader_v, shader_uv_f))
|
|
LOG("Failed to create shader UVs");
|
|
if (!ShaderManager::create(kShader::Font, shader_font_v, shader_font_f))
|
|
LOG("Failed to create shader Font");
|
|
if (!ShaderManager::create(kShader::Atlas, shader_atlas_v, shader_atlas_f))
|
|
LOG("Failed to create shader Atlas");
|
|
}
|
|
|
|
void App::initAssets()
|
|
{
|
|
#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);
|
|
|
|
sampler.create(GL_NEAREST);
|
|
if (!tex.load("data/uvs.jpg"))
|
|
LOG("error loading image\n");
|
|
}
|
|
|
|
void App::initLayout()
|
|
{
|
|
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<NodeButton>("btn-close"))
|
|
{
|
|
button->on_click = [] { exit(0); };
|
|
}
|
|
if (auto* button = layout[main_id]->find<NodeButton>("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<NodeButtonCustom>("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<NodeButtonCustom>("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<NodeButtonCustom>("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<NodeButtonCustom>("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<Node>("toolbar"))
|
|
{
|
|
toolbar->m_flood_events = true;
|
|
}
|
|
};
|
|
layout.load("data/layout2.xml");
|
|
}
|
|
|
|
void App::init()
|
|
{
|
|
#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<GLenum, int> 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]);
|
|
LOG("%.*s\n", length, message);
|
|
FlushConsoleInputBuffer(GetStdHandle(STD_OUTPUT_HANDLE));
|
|
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), info.wAttributes);
|
|
}, nullptr);
|
|
glEnable(GL_DEBUG_OUTPUT);
|
|
#endif
|
|
|
|
initShaders();
|
|
initAssets();
|
|
initLayout();
|
|
|
|
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);
|
|
// LOG("GL ext %03d: %s\n", i, s);
|
|
//}
|
|
LOG("GL version: %s\n", glGetString(GL_VERSION));
|
|
LOG("GL vendor: %s\n", glGetString(GL_VENDOR));
|
|
LOG("GL renderer: %s\n", glGetString(GL_RENDERER));
|
|
|
|
GLfloat width_range[2];
|
|
glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, width_range);
|
|
LOG("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);
|
|
LOG("mouse click %f %f\n", x, y);
|
|
|
|
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();
|
|
}
|