mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-04-26 00:26:32 +00:00
[client] implemented renderer specific option API
Please note the vsync and mipmap options are now specific to OpenGL To configure them use the following options: -o opengl:mipmap=1 -o opengl:vsync=0
This commit is contained in:
parent
f3e19b743c
commit
06e38d897d
@ -15,6 +15,7 @@ BIN ?= bin
|
|||||||
CFLAGS += -DBUILD_VERSION='"$(shell git describe --always --long --dirty --abbrev=10 --tags)"'
|
CFLAGS += -DBUILD_VERSION='"$(shell git describe --always --long --dirty --abbrev=10 --tags)"'
|
||||||
|
|
||||||
OBJS = main.o \
|
OBJS = main.o \
|
||||||
|
lg-renderer.o \
|
||||||
spice/spice.o \
|
spice/spice.o \
|
||||||
ivshmem/ivshmem.o \
|
ivshmem/ivshmem.o \
|
||||||
renderers/opengl.o
|
renderers/opengl.o
|
||||||
|
50
client/lg-renderer.c
Normal file
50
client/lg-renderer.c
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
Looking Glass - KVM FrameRelay (KVMFR) Client
|
||||||
|
Copyright (C) 2017 Geoffrey McRae <geoff@hostfission.com>
|
||||||
|
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 "lg-renderer.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
bool LG_RendererValidatorBool(const char * value)
|
||||||
|
{
|
||||||
|
if (!value)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return
|
||||||
|
(strcasecmp(value, "1" ) == 0) ||
|
||||||
|
(strcasecmp(value, "0" ) == 0) ||
|
||||||
|
(strcasecmp(value, "true" ) == 0) ||
|
||||||
|
(strcasecmp(value, "false" ) == 0) ||
|
||||||
|
(strcasecmp(value, "yes" ) == 0) ||
|
||||||
|
(strcasecmp(value, "no" ) == 0) ||
|
||||||
|
(strcasecmp(value, "on" ) == 0) ||
|
||||||
|
(strcasecmp(value, "off" ) == 0) ||
|
||||||
|
(strcasecmp(value, "enable" ) == 0) ||
|
||||||
|
(strcasecmp(value, "disable") == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LG_RendererValueToBool(const char * value)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(strcasecmp(value, "1" ) == 0) ||
|
||||||
|
(strcasecmp(value, "true" ) == 0) ||
|
||||||
|
(strcasecmp(value, "yes" ) == 0) ||
|
||||||
|
(strcasecmp(value, "on" ) == 0) ||
|
||||||
|
(strcasecmp(value, "enable" ) == 0);
|
||||||
|
}
|
@ -26,6 +26,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
|
|
||||||
#define IS_LG_RENDERER_VALID(x) \
|
#define IS_LG_RENDERER_VALID(x) \
|
||||||
((x)->get_name && \
|
((x)->get_name && \
|
||||||
|
(x)->create && \
|
||||||
(x)->initialize && \
|
(x)->initialize && \
|
||||||
(x)->configure && \
|
(x)->configure && \
|
||||||
(x)->deconfigure && \
|
(x)->deconfigure && \
|
||||||
@ -36,14 +37,33 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
(x)->on_mouse_event && \
|
(x)->on_mouse_event && \
|
||||||
(x)->render)
|
(x)->render)
|
||||||
|
|
||||||
|
#define LGR_OPTION_COUNT(x) (sizeof(x) / sizeof(LG_RendererOpt))
|
||||||
|
|
||||||
|
typedef bool(* LG_RendererOptValidator)(const char * value);
|
||||||
|
typedef void(* LG_RendererOptHandler )(void * opaque, const char * value);
|
||||||
|
|
||||||
|
typedef struct LG_RendererOpt
|
||||||
|
{
|
||||||
|
const char * name;
|
||||||
|
const char * desc;
|
||||||
|
LG_RendererOptValidator validator;
|
||||||
|
LG_RendererOptHandler handler;
|
||||||
|
}
|
||||||
|
LG_RendererOpt;
|
||||||
|
|
||||||
|
typedef struct LG_RendererOptValue
|
||||||
|
{
|
||||||
|
const LG_RendererOpt * opt;
|
||||||
|
const char * value;
|
||||||
|
} LG_RendererOptValue;
|
||||||
|
|
||||||
|
typedef LG_RendererOpt * LG_RendererOptions;
|
||||||
|
|
||||||
typedef struct LG_RendererParams
|
typedef struct LG_RendererParams
|
||||||
{
|
{
|
||||||
int argc;
|
TTF_Font * font;
|
||||||
const char ** argv;
|
bool showFPS;
|
||||||
TTF_Font * font;
|
bool vsync;
|
||||||
bool showFPS;
|
|
||||||
bool resample;
|
|
||||||
bool vsync;
|
|
||||||
}
|
}
|
||||||
LG_RendererParams;
|
LG_RendererParams;
|
||||||
|
|
||||||
@ -75,7 +95,8 @@ typedef enum LG_RendererCursor
|
|||||||
LG_RendererCursor;
|
LG_RendererCursor;
|
||||||
|
|
||||||
typedef const char * (* LG_RendererGetName )();
|
typedef const char * (* LG_RendererGetName )();
|
||||||
typedef bool (* LG_RendererInitialize )(void ** opaque, const LG_RendererParams params, Uint32 * sdlFlags);
|
typedef bool (* LG_RendererCreate )(void ** opaque, const LG_RendererParams params);
|
||||||
|
typedef bool (* LG_RendererInitialize )(void * opaque, Uint32 * sdlFlags);
|
||||||
typedef bool (* LG_RendererConfigure )(void * opaque, SDL_Window *window, const LG_RendererFormat format);
|
typedef bool (* LG_RendererConfigure )(void * opaque, SDL_Window *window, const LG_RendererFormat format);
|
||||||
typedef void (* LG_RendererDeConfigure )(void * opaque);
|
typedef void (* LG_RendererDeConfigure )(void * opaque);
|
||||||
typedef void (* LG_RendererDeInitialize )(void * opaque);
|
typedef void (* LG_RendererDeInitialize )(void * opaque);
|
||||||
@ -88,7 +109,10 @@ typedef bool (* LG_RendererRender )(void * opaque);
|
|||||||
|
|
||||||
typedef struct LG_Renderer
|
typedef struct LG_Renderer
|
||||||
{
|
{
|
||||||
|
LG_RendererCreate create;
|
||||||
LG_RendererGetName get_name;
|
LG_RendererGetName get_name;
|
||||||
|
LG_RendererOptions options;
|
||||||
|
unsigned int option_count;
|
||||||
LG_RendererInitialize initialize;
|
LG_RendererInitialize initialize;
|
||||||
LG_RendererConfigure configure;
|
LG_RendererConfigure configure;
|
||||||
LG_RendererDeConfigure deconfigure;
|
LG_RendererDeConfigure deconfigure;
|
||||||
@ -100,4 +124,8 @@ typedef struct LG_Renderer
|
|||||||
LG_RendererOnFrameEvent on_frame_event;
|
LG_RendererOnFrameEvent on_frame_event;
|
||||||
LG_RendererRender render;
|
LG_RendererRender render;
|
||||||
}
|
}
|
||||||
LG_Renderer;
|
LG_Renderer;
|
||||||
|
|
||||||
|
// generic option helpers
|
||||||
|
bool LG_RendererValidatorBool(const char * value);
|
||||||
|
bool LG_RendererValueToBool (const char * value);
|
@ -27,4 +27,6 @@ const LG_Renderer * LG_Renderers[] =
|
|||||||
{
|
{
|
||||||
&LGR_OpenGL,
|
&LGR_OpenGL,
|
||||||
NULL // end of array sentinal
|
NULL // end of array sentinal
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define LG_RENDERER_COUNT ((sizeof(LG_Renderers) / sizeof(LG_Renderer *)) - 1)
|
131
client/main.c
131
client/main.c
@ -63,9 +63,16 @@ struct AppState
|
|||||||
unsigned int shmSize;
|
unsigned int shmSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct RenderOpts
|
||||||
|
{
|
||||||
|
unsigned int size;
|
||||||
|
unsigned int argc;
|
||||||
|
LG_RendererOptValue * argv;
|
||||||
|
}
|
||||||
|
RendererOpts;
|
||||||
|
|
||||||
struct AppParams
|
struct AppParams
|
||||||
{
|
{
|
||||||
bool vsync;
|
|
||||||
bool autoResize;
|
bool autoResize;
|
||||||
bool allowResize;
|
bool allowResize;
|
||||||
bool keepAspect;
|
bool keepAspect;
|
||||||
@ -75,7 +82,6 @@ struct AppParams
|
|||||||
int x, y;
|
int x, y;
|
||||||
unsigned int w, h;
|
unsigned int w, h;
|
||||||
const char * ivshmemSocket;
|
const char * ivshmemSocket;
|
||||||
bool useMipmap;
|
|
||||||
bool showFPS;
|
bool showFPS;
|
||||||
bool useSpice;
|
bool useSpice;
|
||||||
const char * spiceHost;
|
const char * spiceHost;
|
||||||
@ -84,15 +90,12 @@ struct AppParams
|
|||||||
bool hideMouse;
|
bool hideMouse;
|
||||||
bool ignoreQuit;
|
bool ignoreQuit;
|
||||||
|
|
||||||
unsigned int rendererOptSize;
|
RendererOpts rendererOpts[LG_RENDERER_COUNT];
|
||||||
unsigned int rendererOptCount;
|
|
||||||
const char ** rendererOpts;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AppState state;
|
struct AppState state;
|
||||||
struct AppParams params =
|
struct AppParams params =
|
||||||
{
|
{
|
||||||
.vsync = true,
|
|
||||||
.autoResize = false,
|
.autoResize = false,
|
||||||
.allowResize = true,
|
.allowResize = true,
|
||||||
.keepAspect = true,
|
.keepAspect = true,
|
||||||
@ -104,7 +107,6 @@ struct AppParams params =
|
|||||||
.w = 1024,
|
.w = 1024,
|
||||||
.h = 768,
|
.h = 768,
|
||||||
.ivshmemSocket = "/tmp/ivshmem_socket",
|
.ivshmemSocket = "/tmp/ivshmem_socket",
|
||||||
.useMipmap = true,
|
|
||||||
.showFPS = false,
|
.showFPS = false,
|
||||||
.useSpice = true,
|
.useSpice = true,
|
||||||
.spiceHost = "127.0.0.1",
|
.spiceHost = "127.0.0.1",
|
||||||
@ -720,33 +722,41 @@ int run()
|
|||||||
}
|
}
|
||||||
|
|
||||||
LG_RendererParams lgrParams;
|
LG_RendererParams lgrParams;
|
||||||
lgrParams.argc = params.rendererOptCount;
|
|
||||||
lgrParams.argv = params.rendererOpts;
|
|
||||||
lgrParams.font = state.font;
|
lgrParams.font = state.font;
|
||||||
lgrParams.resample = params.useMipmap;
|
|
||||||
lgrParams.showFPS = params.showFPS;
|
lgrParams.showFPS = params.showFPS;
|
||||||
lgrParams.vsync = params.vsync;
|
|
||||||
Uint32 sdlFlags;
|
Uint32 sdlFlags;
|
||||||
|
|
||||||
// probe for a a suitable renderer
|
// probe for a a suitable renderer
|
||||||
for(const LG_Renderer **r = &LG_Renderers[0]; *r; ++r)
|
for(unsigned int i = 0; i < LG_RENDERER_COUNT; ++i)
|
||||||
{
|
{
|
||||||
if (!IS_LG_RENDERER_VALID(*r))
|
const LG_Renderer *r = LG_Renderers[i];
|
||||||
|
RendererOpts *opts = ¶ms.rendererOpts[i];
|
||||||
|
|
||||||
|
if (!IS_LG_RENDERER_VALID(r))
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("FIXME: Renderer %d is invalid, skipping", (int)(r - &LG_Renderers[0]));
|
DEBUG_ERROR("FIXME: Renderer %d is invalid, skipping", i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create the renderer
|
||||||
state.lgrData = NULL;
|
state.lgrData = NULL;
|
||||||
sdlFlags = 0;
|
if (!r->create(&state.lgrData, lgrParams))
|
||||||
if (!(*r)->initialize(&state.lgrData, lgrParams, &sdlFlags))
|
continue;
|
||||||
|
|
||||||
|
// set it's options
|
||||||
|
for(unsigned int i = 0; i < opts->argc; ++i)
|
||||||
|
opts->argv[i].opt->handler(state.lgrData, opts->argv[i].value);
|
||||||
|
|
||||||
|
// initialize the renderer
|
||||||
|
sdlFlags = 0;
|
||||||
|
if (!r->initialize(state.lgrData, &sdlFlags))
|
||||||
{
|
{
|
||||||
(*r)->deinitialize(state.lgrData);
|
r->deinitialize(state.lgrData);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
state.lgr = *r;
|
state.lgr = r;
|
||||||
DEBUG_INFO("Initialized %s", (*r)->get_name());
|
DEBUG_INFO("Initialized %s", r->get_name());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -939,10 +949,8 @@ void doHelp(char * app)
|
|||||||
" -j Disable cursor position scaling\n"
|
" -j Disable cursor position scaling\n"
|
||||||
" -M Don't hide the host cursor\n"
|
" -M Don't hide the host cursor\n"
|
||||||
"\n"
|
"\n"
|
||||||
" -m Disable mipmapping\n"
|
|
||||||
" -v Disable VSYNC\n"
|
|
||||||
" -k Enable FPS display\n"
|
" -k Enable FPS display\n"
|
||||||
" -o FLAG Specify a renderer flag\n"
|
" -o FLAG Specify a renderer option (ie: opengl:vsync=0)\n"
|
||||||
"\n"
|
"\n"
|
||||||
" -a Auto resize the window to the guest\n"
|
" -a Auto resize the window to the guest\n"
|
||||||
" -n Don't allow the window to be manually resized\n"
|
" -n Don't allow the window to be manually resized\n"
|
||||||
@ -996,7 +1004,7 @@ void doLicense()
|
|||||||
int main(int argc, char * argv[])
|
int main(int argc, char * argv[])
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
while((c = getopt(argc, argv, "hf:sc:p:jMmvko:anrdFx:y:w:b:Ql")) != -1)
|
while((c = getopt(argc, argv, "hf:sc:p:jMvko:anrdFx:y:w:b:Ql")) != -1)
|
||||||
switch(c)
|
switch(c)
|
||||||
{
|
{
|
||||||
case '?':
|
case '?':
|
||||||
@ -1029,19 +1037,79 @@ int main(int argc, char * argv[])
|
|||||||
params.hideMouse = false;
|
params.hideMouse = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'm':
|
|
||||||
params.useMipmap = false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'v':
|
|
||||||
params.vsync = false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'k':
|
case 'k':
|
||||||
params.showFPS = true;
|
params.showFPS = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'o':
|
case 'o':
|
||||||
|
{
|
||||||
|
const LG_Renderer * renderer = NULL;
|
||||||
|
RendererOpts * opts = NULL;
|
||||||
|
|
||||||
|
const size_t len = strlen(optarg);
|
||||||
|
const char * name = strtok(optarg, ":");
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < LG_RENDERER_COUNT; ++i)
|
||||||
|
if (strcasecmp(LG_Renderers[i]->get_name(), name) == 0)
|
||||||
|
{
|
||||||
|
renderer = LG_Renderers[i];
|
||||||
|
opts = ¶ms.rendererOpts[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!renderer)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "No such renderer: %s\n", name);
|
||||||
|
doHelp(argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * option = strtok(NULL , "=");
|
||||||
|
if (!option)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Renderer option name not specified\n");
|
||||||
|
doHelp(argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LG_RendererOpt * opt = NULL;
|
||||||
|
for(unsigned int i = 0; i < renderer->option_count; ++i)
|
||||||
|
if (strcasecmp(option, renderer->options[i].name) == 0)
|
||||||
|
{
|
||||||
|
opt = &renderer->options[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!opt)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Renderer \"%s\" doesn't have the option: %s\n", renderer->get_name(), option);
|
||||||
|
doHelp(argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * value = NULL;
|
||||||
|
if (len > strlen(name) + strlen(option) + 2)
|
||||||
|
value = option + strlen(option) + 1;
|
||||||
|
|
||||||
|
if (opt->validator && !opt->validator(value))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Renderer \"%s\" reported Invalid value for option \"%s\"\n", renderer->get_name(), option);
|
||||||
|
doHelp(argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opts->argc == opts->size)
|
||||||
|
{
|
||||||
|
opts->size += 5;
|
||||||
|
opts->argv = realloc(opts->argv, sizeof(LG_RendererOptValue) * opts->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
opts->argv[opts->argc].opt = opt;
|
||||||
|
opts->argv[opts->argc].value = value;
|
||||||
|
++opts->argc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
if (params.rendererOptCount == params.rendererOptSize)
|
if (params.rendererOptCount == params.rendererOptSize)
|
||||||
{
|
{
|
||||||
params.rendererOptSize += 5;
|
params.rendererOptSize += 5;
|
||||||
@ -1050,6 +1118,7 @@ int main(int argc, char * argv[])
|
|||||||
params.rendererOptSize * sizeof(char *));
|
params.rendererOptSize * sizeof(char *));
|
||||||
}
|
}
|
||||||
params.rendererOpts[params.rendererOptCount++] = optarg;
|
params.rendererOpts[params.rendererOptCount++] = optarg;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'a':
|
case 'a':
|
||||||
|
@ -43,9 +43,23 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
static PFNGLXGETVIDEOSYNCSGIPROC glXGetVideoSyncSGI = NULL;
|
static PFNGLXGETVIDEOSYNCSGIPROC glXGetVideoSyncSGI = NULL;
|
||||||
static PFNGLXWAITVIDEOSYNCSGIPROC glXWaitVideoSyncSGI = NULL;
|
static PFNGLXWAITVIDEOSYNCSGIPROC glXWaitVideoSyncSGI = NULL;
|
||||||
|
|
||||||
|
struct Options
|
||||||
|
{
|
||||||
|
bool mipmap;
|
||||||
|
bool vsync;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct Options defaultOptions =
|
||||||
|
{
|
||||||
|
.mipmap = true,
|
||||||
|
.vsync = true
|
||||||
|
};
|
||||||
|
|
||||||
struct LGR_OpenGL
|
struct LGR_OpenGL
|
||||||
{
|
{
|
||||||
LG_RendererParams params;
|
LG_RendererParams params;
|
||||||
|
struct Options opt;
|
||||||
|
|
||||||
bool configured;
|
bool configured;
|
||||||
SDL_Window * sdlWindow;
|
SDL_Window * sdlWindow;
|
||||||
SDL_GLContext glContext;
|
SDL_GLContext glContext;
|
||||||
@ -104,7 +118,7 @@ const char * lgr_opengl_get_name()
|
|||||||
return "OpenGL";
|
return "OpenGL";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lgr_opengl_initialize(void ** opaque, const LG_RendererParams params, Uint32 * sdlFlags)
|
bool lgr_opengl_create(void ** opaque, const LG_RendererParams params)
|
||||||
{
|
{
|
||||||
// create our local storage
|
// create our local storage
|
||||||
*opaque = malloc(sizeof(struct LGR_OpenGL));
|
*opaque = malloc(sizeof(struct LGR_OpenGL));
|
||||||
@ -116,7 +130,17 @@ bool lgr_opengl_initialize(void ** opaque, const LG_RendererParams params, Uint3
|
|||||||
memset(*opaque, 0, sizeof(struct LGR_OpenGL));
|
memset(*opaque, 0, sizeof(struct LGR_OpenGL));
|
||||||
|
|
||||||
struct LGR_OpenGL * this = (struct LGR_OpenGL *)*opaque;
|
struct LGR_OpenGL * this = (struct LGR_OpenGL *)*opaque;
|
||||||
memcpy(&this->params, ¶ms, sizeof(LG_RendererParams));
|
memcpy(&this->params, ¶ms , sizeof(LG_RendererParams));
|
||||||
|
memcpy(&this->opt , &defaultOptions, sizeof(struct Options ));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool lgr_opengl_initialize(void * opaque, Uint32 * sdlFlags)
|
||||||
|
{
|
||||||
|
struct LGR_OpenGL * this = (struct LGR_OpenGL *)opaque;
|
||||||
|
if (!this)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!glXGetVideoSyncSGI)
|
if (!glXGetVideoSyncSGI)
|
||||||
{
|
{
|
||||||
@ -629,7 +653,7 @@ bool lgr_opengl_on_frame_event(void * opaque, const uint8_t * data)
|
|||||||
// unbind the buffer
|
// unbind the buffer
|
||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||||
|
|
||||||
const bool mipmap = this->params.resample && (
|
const bool mipmap = this->opt.mipmap && (
|
||||||
(this->format.width > this->destRect.w) ||
|
(this->format.width > this->destRect.w) ||
|
||||||
(this->format.height > this->destRect.h));
|
(this->format.height > this->destRect.h));
|
||||||
|
|
||||||
@ -756,9 +780,36 @@ bool lgr_opengl_render(void * opaque)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_opt_mipmap(void * opaque, const char *value)
|
||||||
|
{
|
||||||
|
struct LGR_OpenGL * this = (struct LGR_OpenGL *)opaque;
|
||||||
|
if (!this)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this->opt.mipmap = LG_RendererValueToBool(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_opt_vsync(void * opaque, const char *value)
|
||||||
|
{
|
||||||
|
struct LGR_OpenGL * this = (struct LGR_OpenGL *)opaque;
|
||||||
|
if (!this)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this->opt.vsync = LG_RendererValueToBool(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static LG_RendererOpt lgr_opengl_options[] =
|
||||||
|
{
|
||||||
|
{ .name = "mipmap", .validator = LG_RendererValidatorBool, .handler = handle_opt_mipmap },
|
||||||
|
{ .name = "vsync" , .validator = LG_RendererValidatorBool, .handler = handle_opt_vsync }
|
||||||
|
};
|
||||||
|
|
||||||
const LG_Renderer LGR_OpenGL =
|
const LG_Renderer LGR_OpenGL =
|
||||||
{
|
{
|
||||||
.get_name = lgr_opengl_get_name,
|
.get_name = lgr_opengl_get_name,
|
||||||
|
.options = lgr_opengl_options,
|
||||||
|
.option_count = LGR_OPTION_COUNT(lgr_opengl_options),
|
||||||
|
.create = lgr_opengl_create,
|
||||||
.initialize = lgr_opengl_initialize,
|
.initialize = lgr_opengl_initialize,
|
||||||
.configure = lgr_opengl_configure,
|
.configure = lgr_opengl_configure,
|
||||||
.deconfigure = lgr_opengl_deconfigure,
|
.deconfigure = lgr_opengl_deconfigure,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user