290 lines
8.7 KiB
C++
290 lines
8.7 KiB
C++
#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<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]);
|
|
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<uint8_t[]>(sz);
|
|
fseek(font_file, 0, SEEK_SET);
|
|
auto bytes = fread(data.get(), 1, sz, font_file);
|
|
assert(bytes==sz);
|
|
auto bitmap = std::make_unique<uint8_t[]>(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<glm::vec4> v;
|
|
std::vector<GLushort> 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)
|
|
{
|
|
|
|
}
|