#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_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;" "in vec2 uv;" "out vec4 frag;" "void main(){" //" frag = vec4(1,0,0,1);" " frag = texture(tex, uv);" "}"; #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 layout.load("data/layout.xml"); //layout["main"].update(width, height); 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); WidgetBorder::m_plane.create<1>(1, 1); if (!tex.load("data/uvs.jpg")) printf("error loading image\n"); #if _WIN32 FILE* font_file = fopen("C:\\Windows\\Fonts\\arial.ttf", "rb"); #else FILE* font_file = fopen("/Library/Fonts/Arial.ttf", "rb"); #endif if (font_file) { fseek(font_file, 0, SEEK_END); long sz = ftell(font_file); auto data = std::make_unique(sz); fseek(font_file, 0, SEEK_SET); auto bytes = fread(data.get(), 1, sz, font_file); assert(bytes==sz); auto bitmap = std::make_unique(w*h); chars.resize(num_chars); int ret = stbtt_BakeFontBitmap(data.get(), 0, 50, bitmap.get(), w, h, start_char, num_chars, chars.data()); font_tex.create(w, h, GL_RED, bitmap.get()); glGenBuffers(2, font_buffers); glGenVertexArrays(1, &font_array); glBindVertexArray(font_array); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, font_buffers[1]); glBindBuffer(GL_ARRAY_BUFFER, font_buffers[0]); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec4), (GLvoid*)0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec4), (GLvoid*)(sizeof(float)*2)); glBindVertexArray(0); } plane.create<1>(400, 400); glEnable(GL_TEXTURE_2D); glDisable(GL_DEPTH_TEST); glPointSize(5); glLineWidth(2); //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) { constexpr auto main_id = const_hash("main"); glClearColor(.1f, .1f, .1f, 1.f); glViewport(0, 0, (GLsizei)width, (GLsizei)height); glClear(GL_COLOR_BUFFER_BIT); if (layout.reload()) { layout[main_id].update(width, height); } /* glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glEnable(GL_SCISSOR_TEST); for (auto& n : layout[main_id]) { if (n.m_widget) { auto box = n.m_widget->clip; glScissor((int)box.x, (int)(height - box.y - box.w), (int)box.z, (int)box.w); n.m_widget->draw(); } } glDisable(GL_SCISSOR_TEST); */ glm::mat4 proj = glm::ortho(0.f, width, height, 0.f, -1.f, 1.f); glm::mat4 tran = glm::translate(glm::vec3(200, 200, 0)); if (chars.size()) { static char str[64]; static int counter = 0; counter++; sprintf(str, "frame %04d", counter); const auto len = strlen(str); float x = 0; float y = 0; std::vector v; std::vector idx; for (int i = 0; i < len; i++) { int c = str[i] - start_char; stbtt_aligned_quad q; stbtt_GetBakedQuad(chars.data(), w, h, c, &x, &y, &q, true); auto n = v.size(); v.emplace_back(q.x0, q.y1, q.s0, q.t1); v.emplace_back(q.x0, q.y0, q.s0, q.t0); v.emplace_back(q.x1, q.y0, q.s1, q.t0); v.emplace_back(q.x1, q.y1, q.s1, q.t1); idx.push_back(n+0); idx.push_back(n+1); idx.push_back(n+2); idx.push_back(n+0); idx.push_back(n+2); idx.push_back(n+3); } font_array_count = (int)idx.size(); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, font_buffers[1]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx.size() * sizeof(GLushort), idx.data(), GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, font_buffers[0]); glBufferData(GL_ARRAY_BUFFER, v.size() * sizeof(glm::vec4), v.data(), GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } glActiveTexture(GL_TEXTURE0); font_tex.bind(); sampler.bind(0); ShaderManager::use(kShader::Font); ShaderManager::u_int(kShaderUniform::Tex, 0); ShaderManager::u_mat4(kShaderUniform::MVP, proj*tran); // plane.draw_fill(); glBindVertexArray(font_array); glDrawElements(GL_TRIANGLES, font_array_count, GL_UNSIGNED_SHORT, 0); glBindVertexArray(0); font_tex.unbind(); sampler.unbind(); /* static int i = 0; i = (i + 1) % 32; auto c = chars["hgfrr56789opk0876ryuewighfcuisdbn"[i] - 32]; glm::vec2 a(c.x0, c.y0); glm::vec2 b(c.x1, c.y1); glm::vec2 s(512, 512); glm::vec2 tof = a / s; glm::vec2 tsz = (b - a) / s; glActiveTexture(GL_TEXTURE0); font_tex.bind(); sampler.bind(0); ShaderManager::use(kShader::Font); ShaderManager::u_int(kShaderUniform::Tex, 0); ShaderManager::u_mat4(kShaderUniform::MVP, proj * tran); ShaderManager::u_vec2(kShaderUniform::Tof, tof); ShaderManager::u_vec2(kShaderUniform::Tsz, tsz); //plane.draw_fill(); font_tex.unbind(); sampler.unbind(); */ } void App::resize(float w, float h) { constexpr auto main_id = const_hash("main"); width = w; height = h; layout[main_id].update(w, h); } void App::mouse_down(int button, float x, float y) { printf("mouse click %f %f\n", x, y); } void App::mouse_move(float x, float y) { } void App::mouse_up(int button, float x, float y) { }