/* Looking Glass - KVM FrameRelay (KVMFR) Client Copyright (C) 2021 Guanzhong Chen https://looking-glass.io This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "help.h" #include "common/debug.h" #include "texture.h" #include "shader.h" #include "model.h" #include #include // these headers are auto generated by cmake #include "help.vert.h" #include "help.frag.h" #include "help_bg.frag.h" struct EGL_Help { const LG_Font * font; LG_FontObj fontObj; EGL_Texture * texture; EGL_Shader * shader; EGL_Shader * shaderBG; EGL_Model * model; LG_FontBitmap * bmp; bool shouldRender; int iwidth, iheight; float width, height; // uniforms GLint uScreen , uSize; GLint uScreenBG, uSizeBG; }; bool egl_help_init(EGL_Help ** help, const LG_Font * font, LG_FontObj fontObj) { *help = (EGL_Help *)malloc(sizeof(EGL_Help)); if (!*help) { DEBUG_ERROR("Failed to malloc EGL_Help"); return false; } memset(*help, 0, sizeof(EGL_Help)); (*help)->font = font; (*help)->fontObj = fontObj; if (!egl_texture_init(&(*help)->texture, NULL)) { DEBUG_ERROR("Failed to initialize the help texture"); return false; } if (!egl_shader_init(&(*help)->shader)) { DEBUG_ERROR("Failed to initialize the help shader"); return false; } if (!egl_shader_init(&(*help)->shaderBG)) { DEBUG_ERROR("Failed to initialize the help bg shader"); return false; } if (!egl_shader_compile((*help)->shader, b_shader_help_vert, b_shader_help_vert_size, b_shader_help_frag, b_shader_help_frag_size)) { DEBUG_ERROR("Failed to compile the help shader"); return false; } if (!egl_shader_compile((*help)->shaderBG, b_shader_help_vert , b_shader_help_vert_size, b_shader_help_bg_frag, b_shader_help_bg_frag_size)) { DEBUG_ERROR("Failed to compile the help shader"); return false; } (*help)->uSize = egl_shader_get_uniform_location((*help)->shader , "size" ); (*help)->uScreen = egl_shader_get_uniform_location((*help)->shader , "screen"); (*help)->uSizeBG = egl_shader_get_uniform_location((*help)->shaderBG, "size" ); (*help)->uScreenBG = egl_shader_get_uniform_location((*help)->shaderBG, "screen"); if (!egl_model_init(&(*help)->model)) { DEBUG_ERROR("Failed to initialize the fps model"); return false; } egl_model_set_default((*help)->model); egl_model_set_texture((*help)->model, (*help)->texture); return true; } void egl_help_free(EGL_Help ** help) { if (!*help) return; egl_texture_free(&(*help)->texture ); egl_shader_free (&(*help)->shader ); egl_shader_free (&(*help)->shaderBG); egl_model_free (&(*help)->model ); free(*help); *help = NULL; } void egl_help_set_text(EGL_Help * help, const char * help_text) { if (!help_text) { help->shouldRender = false; return; } help->bmp = help->font->render(help->fontObj, 0xffffff00, help_text); if (!help->bmp) { DEBUG_ERROR("Failed to render help text"); return; } } void egl_help_render(EGL_Help * help, const float scaleX, const float scaleY) { if (help->bmp) { if (help->iwidth != help->bmp->width || help->iheight != help->bmp->height) { help->iwidth = help->bmp->width; help->iheight = help->bmp->height; help->width = (float)help->bmp->width; help->height = (float)help->bmp->height; egl_texture_setup( help->texture, EGL_PF_BGRA, help->bmp->width , help->bmp->height, help->bmp->width * help->bmp->bpp, false, false ); } egl_texture_update ( help->texture, help->bmp->pixels ); help->shouldRender = true; help->font->release(help->fontObj, help->bmp); help->bmp = NULL; } if (!help->shouldRender) return; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // render the background first egl_shader_use(help->shaderBG); glUniform2f(help->uScreenBG, scaleX , scaleY ); glUniform2f(help->uSizeBG , help->width, help->height); egl_model_render(help->model); // render the texture over the background egl_shader_use(help->shader); glUniform2f(help->uScreen, scaleX , scaleY ); glUniform2f(help->uSize , help->width, help->height); egl_model_render(help->model); glDisable(GL_BLEND); }