From 0e2b371e59ec0e895659e54d2d9dc10f331b8082 Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Sun, 16 Dec 2018 00:54:37 +1100 Subject: [PATCH] [client] egl: added splash screen rendering --- client/CMakeLists.txt | 2 + client/ll.c | 50 +++++++ client/ll.h | 14 +- client/renderers/egl.c | 42 +++++- client/renderers/egl/draw.c | 66 ++++++++++ client/renderers/egl/draw.h | 25 ++++ client/renderers/egl/model.c | 144 ++++++++++++-------- client/renderers/egl/model.h | 9 +- client/renderers/egl/splash.c | 240 ++++++++++++++++++++++++++++++++++ client/renderers/egl/splash.h | 31 +++++ 10 files changed, 559 insertions(+), 64 deletions(-) create mode 100644 client/renderers/egl/draw.c create mode 100644 client/renderers/egl/draw.h create mode 100644 client/renderers/egl/splash.c create mode 100644 client/renderers/egl/splash.h diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index cd2019c0..e7729ada 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -66,6 +66,8 @@ set(SOURCES renderers/egl/desktop.c renderers/egl/cursor.c renderers/egl/fps.c + renderers/egl/draw.c + renderers/egl/splash.c fonts/sdl.c ) diff --git a/client/ll.c b/client/ll.c index e1aaf07f..f262fab4 100644 --- a/client/ll.c +++ b/client/ll.c @@ -33,6 +33,8 @@ struct ll { struct ll_item * head; struct ll_item * tail; + struct ll_item * pos; + unsigned int count; LG_Lock lock; }; @@ -41,6 +43,7 @@ struct ll * ll_new() struct ll * list = malloc(sizeof(struct ll)); list->head = NULL; list->tail = NULL; + list->pos = NULL; LG_LOCK_INIT(list->lock); return list; } @@ -69,6 +72,7 @@ void ll_push(struct ll * list, void * data) return; } + ++list->count; list->tail->next = item; list->tail = item; LG_UNLOCK(list->lock); @@ -83,8 +87,11 @@ bool ll_shift(struct ll * list, void ** data) return false; } + --list->count; struct ll_item * item = list->head; list->head = item->next; + + list->pos = NULL; LG_UNLOCK(list->lock); if (data) @@ -106,5 +113,48 @@ bool ll_peek_head(struct ll * list, void ** data) *data = list->head->data; LG_UNLOCK(list->lock); + return true; +} + +unsigned int ll_count(struct ll * list) +{ + return list->count; +} + +void ll_reset (struct ll * list) +{ + LG_LOCK(list->lock); + list->pos = NULL; + LG_UNLOCK(list->lock); +} + + +bool ll_walk(struct ll * list, void ** data) +{ + LG_LOCK(list->lock); + + if (!list->pos) + { + if (!list->head) + { + LG_UNLOCK(list->lock); + return false; + } + + list->pos = list->head; + } + else + { + if (!list->pos->next) + { + LG_UNLOCK(list->lock); + return false; + } + list->pos = list->pos->next; + } + + *data = list->pos->data; + LG_UNLOCK(list->lock); + return true; } \ No newline at end of file diff --git a/client/ll.h b/client/ll.h index 22f9d4dc..70ed6b52 100644 --- a/client/ll.h +++ b/client/ll.h @@ -20,8 +20,12 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include struct ll; -struct ll * ll_new(); -void ll_free(struct ll * list); -void ll_push(struct ll * list, void * data); -bool ll_shift(struct ll * list, void ** data); -bool ll_peek_head(struct ll * list, void ** data); \ No newline at end of file +struct ll * ll_new(); +void ll_free (struct ll * list); +void ll_push (struct ll * list, void * data); +bool ll_shift (struct ll * list, void ** data); +bool ll_peek_head(struct ll * list, void ** data); +unsigned int ll_count (struct ll * list); + +void ll_reset (struct ll * list); +bool ll_walk (struct ll * list, void ** data); \ No newline at end of file diff --git a/client/renderers/egl.c b/client/renderers/egl.c index dacf11a9..b3905331 100644 --- a/client/renderers/egl.c +++ b/client/renderers/egl.c @@ -31,6 +31,9 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include "egl/desktop.h" #include "egl/cursor.h" #include "egl/fps.h" +#include "egl/splash.h" + +#define FADE_TIME 1000000 struct Options { @@ -57,15 +60,19 @@ struct Inst EGL_Desktop * desktop; // the desktop EGL_Cursor * cursor; // the mouse cursor EGL_FPS * fps; // the fps display + EGL_Splash * splash; // the splash screen LG_RendererFormat format; bool sourceChanged; + uint64_t waitFadeTime; + bool waitDone; int width, height; LG_RendererRect destRect; float translateX, translateY; float scaleX , scaleY; + float splashScaleY; float mouseWidth , mouseHeight; float mouseScaleX, mouseScaleY; @@ -134,6 +141,7 @@ void egl_deinitialize(void * opaque) egl_desktop_free(&this->desktop); egl_cursor_free (&this->cursor); egl_fps_free (&this->fps ); + egl_splash_free (&this->splash); free(this); } @@ -162,6 +170,8 @@ void egl_on_resize(void * opaque, const int width, const int height, const LG_Re (this->mouseWidth * (1.0f / this->format.width )) * this->scaleX, (this->mouseHeight * (1.0f / this->format.height)) * this->scaleY ); + + this->splashScaleY = (float)width / (float)height; } bool egl_on_mouse_shape(void * opaque, const LG_RendererCursor cursor, const int width, const int height, const int pitch, const uint8_t * data) @@ -217,6 +227,9 @@ bool egl_on_frame_event(void * opaque, const LG_RendererFormat format, const uin return false; } + if (!this->waitFadeTime) + this->waitFadeTime = microtime() + FADE_TIME; + return true; } @@ -256,6 +269,8 @@ bool egl_render_startup(void * opaque, SDL_Window * window) { EGL_BUFFER_SIZE , 16, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_SAMPLE_BUFFERS , 1, + EGL_SAMPLES , 8, EGL_NONE }; @@ -312,6 +327,12 @@ bool egl_render_startup(void * opaque, SDL_Window * window) return false; } + if (!egl_splash_init(&this->splash)) + { + DEBUG_ERROR("Failed to initialize the splash screen"); + return false; + } + return true; } @@ -324,8 +345,27 @@ bool egl_render(void * opaque, SDL_Window * window) egl_desktop_render(this->desktop, this->translateX, this->translateY, this->scaleX, this->scaleY); egl_cursor_render(this->cursor); - egl_fps_render(this->fps, this->width, this->height); + if (!this->waitDone) + { + float a; + if (!this->waitFadeTime) + a = 1.0f; + else + { + uint64_t t = microtime(); + if (t > this->waitFadeTime) + this->waitDone = true; + else + { + uint64_t delta = this->waitFadeTime - t; + a = 1.0f / FADE_TIME * delta; + } + } + egl_splash_render(this->splash, a, this->splashScaleY); + } + + egl_fps_render(this->fps, this->width, this->height); eglSwapBuffers(this->display, this->surface); // defer texture uploads until after the flip to avoid stalling diff --git a/client/renderers/egl/draw.c b/client/renderers/egl/draw.c new file mode 100644 index 00000000..e88f4568 --- /dev/null +++ b/client/renderers/egl/draw.c @@ -0,0 +1,66 @@ +/* +Looking Glass - KVM FrameRelay (KVMFR) Client +Copyright (C) 2017 Geoffrey McRae +https://looking-glass.hostfission.com + +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 "draw.h" +#include +#include + +void egl_draw_torus(EGL_Model * model, unsigned int pts, float x, float y, float inner, float outer) +{ + GLfloat * v = (GLfloat *)malloc(sizeof(GLfloat) * (pts + 1) * 6); + GLfloat * dst = v; + + for(unsigned int i = 0; i <= pts; ++i) + { + const float angle = (i / (float)pts) * M_PI * 2.0f; + const float c = cos(angle); + const float s = sin(angle); + *dst = x + (inner * c); ++dst; + *dst = y + (inner * s); ++dst; + *dst = 0.0f; ++dst; + *dst = x + (outer * c); ++dst; + *dst = y + (outer * s); ++dst; + *dst = 0.0f; ++dst; + } + + egl_model_add_verticies(model, v, NULL, (pts + 1) * 2); + free(v); +} + +void egl_draw_torus_arc(EGL_Model * model, unsigned int pts, float x, float y, float inner, float outer, float s, float e) +{ + GLfloat * v = (GLfloat *)malloc(sizeof(GLfloat) * (pts + 1) * 6); + GLfloat * dst = v; + + for(unsigned int i = 0; i <= pts; ++i) + { + const float angle = s + ((i / (float)pts) * e); + const float c = cos(angle); + const float s = sin(angle); + *dst = x + (inner * c); ++dst; + *dst = y + (inner * s); ++dst; + *dst = 0.0f; ++dst; + *dst = x + (outer * c); ++dst; + *dst = y + (outer * s); ++dst; + *dst = 0.0f; ++dst; + } + + egl_model_add_verticies(model, v, NULL, (pts + 1) * 2); + free(v); +} \ No newline at end of file diff --git a/client/renderers/egl/draw.h b/client/renderers/egl/draw.h new file mode 100644 index 00000000..720c1dea --- /dev/null +++ b/client/renderers/egl/draw.h @@ -0,0 +1,25 @@ +/* +Looking Glass - KVM FrameRelay (KVMFR) Client +Copyright (C) 2017 Geoffrey McRae +https://looking-glass.hostfission.com + +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 +*/ + +#pragma once + +#include "model.h" + +void egl_draw_torus (EGL_Model * model, unsigned int pts, float x, float y, float inner, float outer); +void egl_draw_torus_arc(EGL_Model * model, unsigned int pts, float x, float y, float inner, float outer, float s, float e); \ No newline at end of file diff --git a/client/renderers/egl/model.c b/client/renderers/egl/model.c index 336bcebf..5d04b3e5 100644 --- a/client/renderers/egl/model.c +++ b/client/renderers/egl/model.c @@ -23,26 +23,36 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include "debug.h" #include "utils.h" +#include "ll.h" #include #include #include +#include #include struct EGL_Model { - bool hasVertexBuffer; - GLuint vertexBuffer; - GLsizei vertexCount; + bool rebuild; + struct ll * verticies; + size_t vertexCount; + bool finish; - bool hasUVBuffer; - GLuint uvBuffer; + bool hasBuffer; + GLuint buffer; EGL_Shader * shader; EGL_Texture * texture; }; +struct FloatList +{ + GLfloat * v; + GLfloat * u; + size_t count; +}; + void update_uniform_bindings(EGL_Model * model); bool egl_model_init(EGL_Model ** model) @@ -55,6 +65,9 @@ bool egl_model_init(EGL_Model ** model) } memset(*model, 0, sizeof(EGL_Model)); + + (*model)->verticies = ll_new(); + return true; } @@ -63,11 +76,17 @@ void egl_model_free(EGL_Model ** model) if (!*model) return; - if ((*model)->hasVertexBuffer) - glDeleteBuffers(1, &(*model)->vertexBuffer); + struct FloatList * fl; + while(ll_shift((*model)->verticies, (void **)&fl)) + { + free(fl->u); + free(fl->v); + free(fl); + } + ll_free((*model)->verticies); - if ((*model)->hasUVBuffer) - glDeleteBuffers(1, &(*model)->uvBuffer); + if ((*model)->hasBuffer) + glDeleteBuffers(1, &(*model)->buffer); free(*model); *model = NULL; @@ -91,71 +110,90 @@ void egl_model_set_default(EGL_Model * model) 1.0f, 0.0f }; - egl_model_set_verticies(model, square, sizeof(square) / sizeof(GLfloat)); - egl_model_set_uvs (model, uvs , sizeof(uvs ) / sizeof(GLfloat)); + egl_model_add_verticies(model, square, uvs, 4); } -void egl_model_set_verticies(EGL_Model * model, const GLfloat * verticies, const size_t count) +void egl_model_add_verticies(EGL_Model * model, const GLfloat * verticies, const GLfloat * uvs, const size_t count) { - if (model->hasVertexBuffer) - glDeleteBuffers(1, &model->vertexBuffer); + struct FloatList * fl = (struct FloatList *)malloc(sizeof(struct FloatList)); - glGenBuffers(1, &model->vertexBuffer); - glBindBuffer(GL_ARRAY_BUFFER, model->vertexBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * count, verticies, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); + fl->count = count; + fl->v = (GLfloat *)malloc(sizeof(GLfloat) * count * 3); + fl->u = (GLfloat *)malloc(sizeof(GLfloat) * count * 2); + memcpy(fl->v, verticies, sizeof(GLfloat) * count * 3); - model->hasVertexBuffer = true; - model->vertexCount = count / 3; -} + if (uvs) + memcpy(fl->u, uvs, sizeof(GLfloat) * count * 2); + else + memset(fl->u, 0 , sizeof(GLfloat) * count * 2); -void egl_model_set_uvs(EGL_Model * model, const GLfloat * uvs, const size_t count) -{ - if (model->hasUVBuffer) - glDeleteBuffers(1, &model->uvBuffer); - - glGenBuffers(1, &model->uvBuffer); - glBindBuffer(GL_ARRAY_BUFFER, model->uvBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * count, uvs, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - model->hasUVBuffer = true; + ll_push(model->verticies, fl); + model->rebuild = true; + model->vertexCount += count; } void egl_model_render(EGL_Model * model) { - if (!model->hasVertexBuffer) - { - DEBUG_ERROR("Model has no verticies"); + if (!model->vertexCount) return; + + if (model->rebuild) + { + if (model->hasBuffer) + glDeleteBuffers(1, &model->buffer); + + /* create a buffer large enough */ + glGenBuffers(1, &model->buffer); + glBindBuffer(GL_ARRAY_BUFFER, model->buffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * (model->vertexCount * 5), NULL, GL_STATIC_DRAW); + + GLintptr offset = 0; + + /* buffer the verticies */ + struct FloatList * fl; + for(ll_reset(model->verticies); ll_walk(model->verticies, (void **)&fl);) + { + glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(GLfloat) * fl->count * 3, fl->v); + offset += sizeof(GLfloat) * fl->count * 3; + } + + /* buffer the uvs */ + for(ll_reset(model->verticies); ll_walk(model->verticies, (void **)&fl);) + { + glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(GLfloat) * fl->count * 2, fl->u); + offset += sizeof(GLfloat) * fl->count * 2; + } + + glBindBuffer(GL_ARRAY_BUFFER, 0); + model->rebuild = false; } + /* bind the model buffer and setup the pointers */ + glBindBuffer(GL_ARRAY_BUFFER, model->buffer); + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(GLfloat) * model->vertexCount * 3)); + if (model->shader) egl_shader_use(model->shader); - GLuint location = 0; - glEnableVertexAttribArray(location); - glBindBuffer(GL_ARRAY_BUFFER, model->vertexBuffer); - glVertexAttribPointer(location, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); - - if (model->hasUVBuffer) - { - ++location; - glEnableVertexAttribArray(location); - glBindBuffer(GL_ARRAY_BUFFER, model->uvBuffer); - glVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); - } - if (model->texture) egl_texture_bind(model->texture); - glDrawArrays(GL_TRIANGLE_STRIP, 0, model->vertexCount); + /* draw the arrays */ + GLint offset = 0; + struct FloatList * fl; + for(ll_reset(model->verticies); ll_walk(model->verticies, (void **)&fl);) + { + glDrawArrays(GL_TRIANGLE_STRIP, offset, fl->count); + offset += fl->count; + } + + /* unbind and cleanup */ glBindTexture(GL_TEXTURE_2D, 0); - - while(location > 0) - glDisableVertexAttribArray(location--); glDisableVertexAttribArray(0); - + glDisableVertexAttribArray(1); glUseProgram(0); } diff --git a/client/renderers/egl/model.h b/client/renderers/egl/model.h index e3f7f0d9..68621f53 100644 --- a/client/renderers/egl/model.h +++ b/client/renderers/egl/model.h @@ -30,10 +30,9 @@ typedef struct EGL_Model EGL_Model; bool egl_model_init(EGL_Model ** model); void egl_model_free(EGL_Model ** model); -void egl_model_set_default (EGL_Model * model); -void egl_model_set_verticies (EGL_Model * model, const GLfloat * verticies, const size_t count); -void egl_model_set_uvs (EGL_Model * model, const GLfloat * uvs , const size_t count); -void egl_model_set_shader (EGL_Model * model, EGL_Shader * shader); -void egl_model_set_texture (EGL_Model * model, EGL_Texture * texture); +void egl_model_set_default (EGL_Model * model); +void egl_model_add_verticies(EGL_Model * model, const GLfloat * verticies, const GLfloat * uvs, const size_t count); +void egl_model_set_shader (EGL_Model * model, EGL_Shader * shader); +void egl_model_set_texture (EGL_Model * model, EGL_Texture * texture); void egl_model_render(EGL_Model * model); \ No newline at end of file diff --git a/client/renderers/egl/splash.c b/client/renderers/egl/splash.c new file mode 100644 index 00000000..78a77764 --- /dev/null +++ b/client/renderers/egl/splash.c @@ -0,0 +1,240 @@ +/* +Looking Glass - KVM FrameRelay (KVMFR) Client +Copyright (C) 2017 Geoffrey McRae +https://looking-glass.hostfission.com + +This program is free software; you can redistribute it and/or modify it under +cahe 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 "splash.h" +#include "debug.h" +#include "utils.h" + +#include "draw.h" +#include "texture.h" +#include "shader.h" +#include "model.h" + +#include +#include +#include +#include + +struct EGL_Splash +{ + EGL_Shader * bgShader; + EGL_Model * bg; + + EGL_Shader * logoShader; + EGL_Model * logo; + + // uniforms + GLint uBGAlpha; + GLint uScale; +}; + +static const char vertex_bgShader[] = "\ +#version 300 es\n\ +\ +layout(location = 0) in vec3 vertexPosition_modelspace;\ +\ +uniform float alpha;\ +\ +out highp vec3 pos; \ +out highp float a; \ +\ +void main()\ +{\ + gl_Position.xyz = vertexPosition_modelspace; \ + gl_Position.w = 1.0; \ +\ + pos = vertexPosition_modelspace; \ + a = alpha; \ +}\ +"; + +static const char frag_bgShader[] = "\ +#version 300 es\n\ +\ +in highp vec3 pos;\ +in highp float a;\ +out highp vec4 color;\ +\ +uniform sampler2D sampler1;\ +\ +void main()\ +{\ + highp float d = 1.0 - sqrt(pos.x * pos.x + pos.y * pos.y) / 2.0; \ + color = vec4(0.234375 * d, 0.015625f * d, 0.425781f * d, a); \ +}\ +"; + +static const char vertex_logoShader[] = "\ +#version 300 es\n\ +\ +layout(location = 0) in vec3 vertexPosition_modelspace;\ +\ +uniform vec2 scale;\ +\ +out highp float a; \ +\ +void main()\ +{\ + gl_Position.xyz = vertexPosition_modelspace; \ + gl_Position.y *= scale.y; \ + gl_Position.w = 1.0; \ +\ + a = scale.x; \ +}\ +"; + +static const char frag_logoShader[] = "\ +#version 300 es\n\ +\ +out highp vec4 color;\ +in highp float a;\ +\ +uniform sampler2D sampler1;\ +\ +void main()\ +{\ + color = vec4(1.0, 1.0, 1.0, a);\ +}\ +"; + +bool egl_splash_init(EGL_Splash ** splash) +{ + *splash = (EGL_Splash *)malloc(sizeof(EGL_Splash)); + if (!*splash) + { + DEBUG_ERROR("Failed to malloc EGL_Splash"); + return false; + } + + memset(*splash, 0, sizeof(EGL_Splash)); + + if (!egl_shader_init(&(*splash)->bgShader)) + { + DEBUG_ERROR("Failed to initialize the splash bgShader"); + return false; + } + + if (!egl_shader_compile((*splash)->bgShader, + vertex_bgShader, sizeof(vertex_bgShader), + frag_bgShader , sizeof(frag_bgShader ))) + { + DEBUG_ERROR("Failed to compile the splash bgShader"); + return false; + } + + (*splash)->uBGAlpha = egl_shader_get_uniform_location((*splash)->bgShader, "alpha"); + + if (!egl_model_init(&(*splash)->bg)) + { + DEBUG_ERROR("Failed to intiailize the splash bg model"); + return false; + } + + egl_model_set_default((*splash)->bg); + + if (!egl_shader_init(&(*splash)->logoShader)) + { + DEBUG_ERROR("Failed to initialize the splash logoShader"); + return false; + } + + if (!egl_shader_compile((*splash)->logoShader, + vertex_logoShader, sizeof(vertex_logoShader), + frag_logoShader , sizeof(frag_logoShader ))) + { + DEBUG_ERROR("Failed to compile the splash logoShader"); + return false; + } + + (*splash)->uScale = egl_shader_get_uniform_location((*splash)->logoShader, "scale"); + + if (!egl_model_init(&(*splash)->logo)) + { + DEBUG_ERROR("Failed to intiailize the splash model"); + return false; + } + + /* build the splash model */ + #define P(x) ((1.0f/800.0f)*(float)(x)) + egl_draw_torus_arc((*splash)->logo, 30, P( 0 ), P(0), P(102), P(98), 0.0f, -M_PI); + egl_draw_torus ((*splash)->logo, 30, P(-100), P(4), P(8 ), P(4 )); + egl_draw_torus ((*splash)->logo, 30, P( 100), P(4), P(8 ), P(4 )); + + egl_draw_torus ((*splash)->logo, 60, P(0), P(0), P(83), P(79)); + egl_draw_torus ((*splash)->logo, 60, P(0), P(0), P(67), P(63)); + + static const GLfloat lines[][12] = + { + { + P( -2), P(-140), 0.0f, + P( -2), P(-100), 0.0f, + P( 2), P(-140), 0.0f, + P( 2), P(-100), 0.0f + }, + { + P(-26), P(-144), 0.0f, + P(-26), P(-140), 0.0f, + P( 26), P(-144), 0.0f, + P( 26), P(-140), 0.0f + }, + { + P(-40), P(-156), 0.0f, + P(-40), P(-152), 0.0f, + P( 40), P(-156), 0.0f, + P( 40), P(-152), 0.0f + } + }; + + egl_model_add_verticies((*splash)->logo, lines[0], NULL, 4); + egl_model_add_verticies((*splash)->logo, lines[1], NULL, 4); + egl_model_add_verticies((*splash)->logo, lines[2], NULL, 4); + + egl_draw_torus_arc((*splash)->logo, 10, P(-26), P(-154), P(10), P(14), M_PI , -M_PI / 2.0); + egl_draw_torus_arc((*splash)->logo, 10, P( 26), P(-154), P(10), P(14), M_PI / 2.0f, -M_PI / 2.0); + #undef P + + return true; +} + +void egl_splash_free(EGL_Splash ** splash) +{ + if (!*splash) + return; + + egl_model_free(&(*splash)->logo); + + free(*splash); + *splash = NULL; +} + +void egl_splash_render(EGL_Splash * splash, float alpha, float scaleY) +{ + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + egl_shader_use(splash->bgShader); + glUniform1f(splash->uBGAlpha, alpha); + egl_model_render(splash->bg); + + egl_shader_use(splash->logoShader); + glUniform2f(splash->uScale, alpha, scaleY); + egl_model_render(splash->logo); + + glDisable(GL_BLEND); +} \ No newline at end of file diff --git a/client/renderers/egl/splash.h b/client/renderers/egl/splash.h new file mode 100644 index 00000000..8f7567cf --- /dev/null +++ b/client/renderers/egl/splash.h @@ -0,0 +1,31 @@ +/* +Looking Glass - KVM FrameRelay (KVMFR) Client +Copyright (C) 2017 Geoffrey McRae +https://looking-glass.hostfission.com + +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 +*/ + +#pragma once + +#include + +#include "lg-fonts.h" + +typedef struct EGL_Splash EGL_Splash; + +bool egl_splash_init(EGL_Splash ** splash); +void egl_splash_free(EGL_Splash ** splash); + +void egl_splash_render(EGL_Splash * splash, float alpha, float scaleY); \ No newline at end of file