mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-12-23 14:03:40 +00:00
[opengl] added support for alerts
This commit is contained in:
parent
89959b48a7
commit
fbbee1cdac
@ -33,12 +33,14 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "lg-decoders.h"
|
#include "lg-decoders.h"
|
||||||
|
#include "ll.h"
|
||||||
|
|
||||||
#define BUFFER_COUNT 2
|
#define BUFFER_COUNT 2
|
||||||
|
|
||||||
#define FPS_TEXTURE 0
|
#define FPS_TEXTURE 0
|
||||||
#define MOUSE_TEXTURE 1
|
#define MOUSE_TEXTURE 1
|
||||||
#define TEXTURE_COUNT 2
|
#define ALERT_TEXTURE 2
|
||||||
|
#define TEXTURE_COUNT 3
|
||||||
|
|
||||||
struct Options
|
struct Options
|
||||||
{
|
{
|
||||||
@ -56,6 +58,13 @@ static struct Options defaultOptions =
|
|||||||
.amdPinnedMem = true,
|
.amdPinnedMem = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Alert
|
||||||
|
{
|
||||||
|
SDL_Surface *text;
|
||||||
|
float r, g, b, a;
|
||||||
|
uint64_t timeout;
|
||||||
|
};
|
||||||
|
|
||||||
struct Inst
|
struct Inst
|
||||||
{
|
{
|
||||||
LG_RendererParams params;
|
LG_RendererParams params;
|
||||||
@ -96,6 +105,8 @@ struct Inst
|
|||||||
GLsync fences[BUFFER_COUNT];
|
GLsync fences[BUFFER_COUNT];
|
||||||
void * decoderFrames[BUFFER_COUNT];
|
void * decoderFrames[BUFFER_COUNT];
|
||||||
GLuint textures[TEXTURE_COUNT];
|
GLuint textures[TEXTURE_COUNT];
|
||||||
|
struct ll * alerts;
|
||||||
|
int alertList;
|
||||||
|
|
||||||
bool fpsTexture;
|
bool fpsTexture;
|
||||||
uint64_t lastFrameTime;
|
uint64_t lastFrameTime;
|
||||||
@ -155,6 +166,7 @@ bool opengl_create(void ** opaque, const LG_RendererParams params)
|
|||||||
LG_LOCK_INIT(this->syncLock );
|
LG_LOCK_INIT(this->syncLock );
|
||||||
LG_LOCK_INIT(this->mouseLock );
|
LG_LOCK_INIT(this->mouseLock );
|
||||||
|
|
||||||
|
this->alerts = ll_new();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,6 +195,15 @@ void opengl_deinitialize(void * opaque)
|
|||||||
LG_LOCK_FREE(this->syncLock );
|
LG_LOCK_FREE(this->syncLock );
|
||||||
LG_LOCK_FREE(this->mouseLock );
|
LG_LOCK_FREE(this->mouseLock );
|
||||||
|
|
||||||
|
struct Alert * alert;
|
||||||
|
while(ll_shift(this->alerts, (void **)&alert))
|
||||||
|
{
|
||||||
|
if (alert->text)
|
||||||
|
SDL_FreeSurface(alert->text);
|
||||||
|
free(alert);
|
||||||
|
}
|
||||||
|
ll_free(this->alerts);
|
||||||
|
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,6 +309,79 @@ bool opengl_on_frame_event(void * opaque, const LG_RendererFormat format, const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void opengl_on_alert(void * opaque, const LG_RendererAlert alert, const char * message)
|
||||||
|
{
|
||||||
|
struct Inst * this = (struct Inst *)opaque;
|
||||||
|
struct Alert * a = malloc(sizeof(struct Alert));
|
||||||
|
memset(a, 0, sizeof(struct Alert));
|
||||||
|
const SDL_Color color = {0xff, 0xff, 0xff};
|
||||||
|
|
||||||
|
switch(alert)
|
||||||
|
{
|
||||||
|
case LG_ALERT_INFO:
|
||||||
|
a->r = 0.0f;
|
||||||
|
a->g = 0.0f;
|
||||||
|
a->b = 0.8f;
|
||||||
|
a->a = 0.8f;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LG_ALERT_SUCCESS:
|
||||||
|
a->r = 0.0f;
|
||||||
|
a->g = 0.8f;
|
||||||
|
a->b = 0.0f;
|
||||||
|
a->a = 0.8f;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LG_ALERT_WARNING:
|
||||||
|
a->r = 0.8f;
|
||||||
|
a->g = 0.5f;
|
||||||
|
a->b = 0.0f;
|
||||||
|
a->a = 0.8f;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LG_ALERT_ERROR:
|
||||||
|
a->r = 1.0f;
|
||||||
|
a->g = 0.0f;
|
||||||
|
a->b = 0.0f;
|
||||||
|
a->a = 0.8f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(a->text = TTF_RenderText_Blended(this->params.alertFont, message, color)))
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("Failed to render alert text: %s", TTF_GetError());
|
||||||
|
free(a);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ll_push(this->alerts, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
void surface_to_texture(SDL_Surface * surface, GLuint texture)
|
||||||
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D , texture );
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT , 4 );
|
||||||
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, surface->w);
|
||||||
|
glTexImage2D(
|
||||||
|
GL_TEXTURE_2D,
|
||||||
|
0,
|
||||||
|
surface->format->BytesPerPixel,
|
||||||
|
surface->w,
|
||||||
|
surface->h,
|
||||||
|
0,
|
||||||
|
GL_BGRA,
|
||||||
|
GL_UNSIGNED_BYTE,
|
||||||
|
surface->pixels
|
||||||
|
);
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
|
|
||||||
bool opengl_render(void * opaque, SDL_Window * window)
|
bool opengl_render(void * opaque, SDL_Window * window)
|
||||||
{
|
{
|
||||||
struct Inst * this = (struct Inst *)opaque;
|
struct Inst * this = (struct Inst *)opaque;
|
||||||
@ -340,36 +434,16 @@ bool opengl_render(void * opaque, SDL_Window * window)
|
|||||||
const float avgFPS = 1000.0f / (((float)this->renderTime / this->frameCount ) / 1e6f);
|
const float avgFPS = 1000.0f / (((float)this->renderTime / this->frameCount ) / 1e6f);
|
||||||
const float renderFPS = 1000.0f / (((float)this->renderTime / this->renderCount) / 1e6f);
|
const float renderFPS = 1000.0f / (((float)this->renderTime / this->renderCount) / 1e6f);
|
||||||
snprintf(str, sizeof(str), "UPS: %8.4f, FPS: %8.4f", avgFPS, renderFPS);
|
snprintf(str, sizeof(str), "UPS: %8.4f, FPS: %8.4f", avgFPS, renderFPS);
|
||||||
SDL_Color color = {0xff, 0xff, 0xff};
|
const SDL_Color color = {0xff, 0xff, 0xff};
|
||||||
SDL_Surface *textSurface = NULL;
|
SDL_Surface *textSurface = NULL;
|
||||||
if (!(textSurface = TTF_RenderText_Blended(this->params.font, str, color)))
|
if (!(textSurface = TTF_RenderText_Blended(this->params.font, str, color)))
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to render text");
|
DEBUG_ERROR("Failed to render text: %s", TTF_GetError());
|
||||||
LG_UNLOCK(this->formatLock);
|
LG_UNLOCK(this->formatLock);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D , this->textures[FPS_TEXTURE]);
|
surface_to_texture(textSurface, this->textures[FPS_TEXTURE]);
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT , 4 );
|
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, textSurface->w );
|
|
||||||
glTexImage2D(
|
|
||||||
GL_TEXTURE_2D,
|
|
||||||
0,
|
|
||||||
textSurface->format->BytesPerPixel,
|
|
||||||
textSurface->w,
|
|
||||||
textSurface->h,
|
|
||||||
0,
|
|
||||||
GL_BGRA,
|
|
||||||
GL_UNSIGNED_BYTE,
|
|
||||||
textSurface->pixels
|
|
||||||
);
|
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
|
|
||||||
this->fpsRect.x = 5;
|
this->fpsRect.x = 5;
|
||||||
this->fpsRect.y = 5;
|
this->fpsRect.y = 5;
|
||||||
@ -422,6 +496,60 @@ bool opengl_render(void * opaque, SDL_Window * window)
|
|||||||
if (this->fpsTexture)
|
if (this->fpsTexture)
|
||||||
glCallList(this->fpsList);
|
glCallList(this->fpsList);
|
||||||
|
|
||||||
|
struct Alert * alert;
|
||||||
|
while(ll_peek_head(this->alerts, (void **)&alert))
|
||||||
|
{
|
||||||
|
if (alert->timeout == 0)
|
||||||
|
{
|
||||||
|
surface_to_texture(alert->text, this->textures[ALERT_TEXTURE]);
|
||||||
|
|
||||||
|
glNewList(this->alertList, GL_COMPILE);
|
||||||
|
const int p = 4;
|
||||||
|
const int w = alert->text->w + p * 2;
|
||||||
|
const int h = alert->text->h + p * 2;
|
||||||
|
glTranslatef(-(w / 2), -(h / 2), 0.0f);
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
glColor4f(alert->r, alert->g, alert->b, alert->a);
|
||||||
|
glBegin(GL_TRIANGLE_STRIP);
|
||||||
|
glVertex2i(0, 0);
|
||||||
|
glVertex2i(w, 0);
|
||||||
|
glVertex2i(0, h);
|
||||||
|
glVertex2i(w, h);
|
||||||
|
glEnd();
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, this->textures[ALERT_TEXTURE]);
|
||||||
|
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
glTranslatef(p, p, 0.0f);
|
||||||
|
glBegin(GL_TRIANGLE_STRIP);
|
||||||
|
glTexCoord2f(0.0f, 0.0f); glVertex2i(0 , 0 );
|
||||||
|
glTexCoord2f(1.0f, 0.0f); glVertex2i(alert->text->w, 0 );
|
||||||
|
glTexCoord2f(0.0f, 1.0f); glVertex2i(0 , alert->text->h);
|
||||||
|
glTexCoord2f(1.0f, 1.0f); glVertex2i(alert->text->w, alert->text->h);
|
||||||
|
glEnd();
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
glEndList();
|
||||||
|
|
||||||
|
alert->timeout = microtime() + 2*1000000;
|
||||||
|
|
||||||
|
SDL_FreeSurface(alert->text);
|
||||||
|
alert->text = NULL;
|
||||||
|
}
|
||||||
|
else if (alert->timeout < microtime())
|
||||||
|
{
|
||||||
|
free(alert);
|
||||||
|
ll_shift(this->alerts, NULL);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
glPushMatrix();
|
||||||
|
glLoadIdentity();
|
||||||
|
glTranslatef(this->window.x / 2, this->window.y / 2, 0.0f);
|
||||||
|
glCallList(this->alertList);
|
||||||
|
glPopMatrix();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (this->opt.preventBuffer)
|
if (this->opt.preventBuffer)
|
||||||
{
|
{
|
||||||
SDL_GL_SwapWindow(window);
|
SDL_GL_SwapWindow(window);
|
||||||
@ -523,6 +651,7 @@ const LG_Renderer LGR_OpenGL =
|
|||||||
.on_mouse_shape = opengl_on_mouse_shape,
|
.on_mouse_shape = opengl_on_mouse_shape,
|
||||||
.on_mouse_event = opengl_on_mouse_event,
|
.on_mouse_event = opengl_on_mouse_event,
|
||||||
.on_frame_event = opengl_on_frame_event,
|
.on_frame_event = opengl_on_frame_event,
|
||||||
|
.on_alert = opengl_on_alert,
|
||||||
.render = opengl_render
|
.render = opengl_render
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -644,6 +773,7 @@ static bool configure(struct Inst * this, SDL_Window *window)
|
|||||||
this->texList = glGenLists(BUFFER_COUNT);
|
this->texList = glGenLists(BUFFER_COUNT);
|
||||||
this->fpsList = glGenLists(1);
|
this->fpsList = glGenLists(1);
|
||||||
this->mouseList = glGenLists(1);
|
this->mouseList = glGenLists(1);
|
||||||
|
this->alertList = glGenLists(1);
|
||||||
|
|
||||||
// generate the pixel unpack buffers if the decoder isn't going to do it for us
|
// generate the pixel unpack buffers if the decoder isn't going to do it for us
|
||||||
if (!this->decoder->has_gl)
|
if (!this->decoder->has_gl)
|
||||||
|
Loading…
Reference in New Issue
Block a user