wayland resize
This commit is contained in:
parent
39f44a56e3
commit
d4d4835fd1
2 changed files with 207 additions and 85 deletions
|
|
@ -41,6 +41,7 @@ struct _MwLLWaylandTopLevel {
|
|||
struct xdg_toplevel* xdg_top_level;
|
||||
struct xdg_toplevel_listener xdg_toplevel_listener;
|
||||
struct xdg_surface_listener xdg_surface_listener;
|
||||
struct wl_surface_listener surface_listener;
|
||||
|
||||
struct xkb_context* xkb_context;
|
||||
|
||||
|
|
@ -81,7 +82,8 @@ struct _MwLLWayland {
|
|||
|
||||
MwBool configured;
|
||||
MwBool force_redraw;
|
||||
MwBool do_clear;
|
||||
MwBool egl_setup;
|
||||
MwBool egl_do_resetup;
|
||||
MwU32 x, y, ww, wh;
|
||||
int z_index;
|
||||
|
||||
|
|
@ -89,15 +91,12 @@ struct _MwLLWayland {
|
|||
|
||||
GLuint fbo;
|
||||
unsigned int fbo_texture;
|
||||
unsigned int rbo;
|
||||
|
||||
MwBool egl_setup;
|
||||
EGLNativeWindowType egl_window_native;
|
||||
EGLDisplay egl_display;
|
||||
EGLContext egl_context;
|
||||
EGLSurface egl_surface;
|
||||
GLuint vertex_buffer;
|
||||
GLuint vertex_array;
|
||||
EGLConfig egl_config;
|
||||
};
|
||||
|
||||
struct _MwLLWaylandColor {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,12 @@ PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer;
|
|||
PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
|
||||
PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatus;
|
||||
|
||||
EGLint contextAttribs[] = {
|
||||
EGL_CONTEXT_CLIENT_VERSION, 1,
|
||||
EGL_CONTEXT_MAJOR_VERSION, 1,
|
||||
EGL_CONTEXT_MINOR_VERSION, 1,
|
||||
EGL_NONE};
|
||||
|
||||
#define WAYLAND_GET_INTERFACE(r, inter) shget(r.wl_protocol_map, inter##_interface.name)
|
||||
|
||||
static void new_protocol(void* data, struct wl_registry* registry,
|
||||
|
|
@ -52,6 +58,19 @@ static void protocol_removed(void* data,
|
|||
|
||||
};
|
||||
|
||||
static void surface_enter(void* data,
|
||||
struct wl_surface* wl_surface,
|
||||
struct wl_output* output) {
|
||||
MwLL self = data;
|
||||
|
||||
printf("yhdhfgh\n");
|
||||
};
|
||||
static void surface_leave(void* data,
|
||||
struct wl_surface* wl_surface,
|
||||
struct wl_output* output) {
|
||||
printf("yhdhfgh\n");
|
||||
};
|
||||
|
||||
static void wl_seat_name(void* data, struct wl_seat* wl_seat, const char* name) {};
|
||||
static void wl_seat_capabilities(void* data, struct wl_seat* wl_seat,
|
||||
MwU32 capabilities) {};
|
||||
|
|
@ -64,13 +83,6 @@ void xdg_wm_base_ping(void* data,
|
|||
xdg_wm_base_pong(xdg_wm_base, serial);
|
||||
};
|
||||
|
||||
static wayland_protocol_t* wl_shm_setup(MwU32 name, struct _MwLLWayland* wayland) {
|
||||
wayland->shm = wl_registry_bind(wayland->registry, name, &wl_shm_interface, 1);
|
||||
return NULL;
|
||||
}
|
||||
// static void buffer_setup(struct _MwLLWayland* wayland) {
|
||||
// }
|
||||
|
||||
static wayland_protocol_t* wl_seat_setup(MwU32 name, struct _MwLLWayland* wayland) {
|
||||
wayland_protocol_t* proto = malloc(sizeof(wayland_protocol_t));
|
||||
proto->listener = malloc(sizeof(struct wl_seat_listener));
|
||||
|
|
@ -143,7 +155,6 @@ static MwBool egl_setup(MwLL self, int width, int height) {
|
|||
EGLint minorVersion;
|
||||
EGLContext context;
|
||||
EGLSurface surface;
|
||||
EGLConfig config;
|
||||
EGLint fbAttribs[] =
|
||||
{
|
||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||
|
|
@ -153,11 +164,6 @@ static MwBool egl_setup(MwLL self, int width, int height) {
|
|||
EGL_BLUE_SIZE, 8,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
|
||||
EGL_NONE};
|
||||
EGLint contextAttribs[] = {
|
||||
EGL_CONTEXT_CLIENT_VERSION, 1,
|
||||
EGL_CONTEXT_MAJOR_VERSION, 1,
|
||||
EGL_CONTEXT_MINOR_VERSION, 1,
|
||||
EGL_NONE};
|
||||
|
||||
EGLDisplay display = eglGetDisplay(self->wayland.display);
|
||||
if(display == EGL_NO_DISPLAY) {
|
||||
|
|
@ -178,7 +184,7 @@ static MwBool egl_setup(MwLL self, int width, int height) {
|
|||
}
|
||||
|
||||
// Choose config
|
||||
if((eglChooseConfig(display, fbAttribs, &config, 1, &numConfigs) != EGL_TRUE) || (numConfigs != 1)) {
|
||||
if((eglChooseConfig(display, fbAttribs, &self->wayland.egl_config, 1, &numConfigs) != EGL_TRUE) || (numConfigs != 1)) {
|
||||
printf("ERROR: eglChooseConfig, %0X\n", eglGetError());
|
||||
return MwFALSE;
|
||||
}
|
||||
|
|
@ -191,7 +197,7 @@ static MwBool egl_setup(MwLL self, int width, int height) {
|
|||
}
|
||||
|
||||
// Create a surface
|
||||
surface = eglCreateWindowSurface(display, config, self->wayland.egl_window_native, NULL);
|
||||
surface = eglCreateWindowSurface(display, self->wayland.egl_config, self->wayland.egl_window_native, NULL);
|
||||
if(surface == EGL_NO_SURFACE) {
|
||||
printf("ERROR: eglCreateWindowSurface, %0X\n", eglGetError());
|
||||
return MwFALSE;
|
||||
|
|
@ -200,7 +206,7 @@ static MwBool egl_setup(MwLL self, int width, int height) {
|
|||
eglBindAPI(EGL_OPENGL_API);
|
||||
|
||||
// Create a GL context
|
||||
context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
|
||||
context = eglCreateContext(display, self->wayland.egl_config, EGL_NO_CONTEXT, contextAttribs);
|
||||
if(context == EGL_NO_CONTEXT) {
|
||||
printf("ERROR: eglCreateContext, %0X\n", eglGetError());
|
||||
return MwFALSE;
|
||||
|
|
@ -226,24 +232,15 @@ static MwBool egl_setup(MwLL self, int width, int height) {
|
|||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glGenRenderbuffers(1, &self->wayland.rbo);
|
||||
// glBindRenderbuffer(GL_RENDERBUFFER, self->wayland.rbo));
|
||||
// glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 768, 1024);
|
||||
// glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
|
||||
glGenFramebuffers(1, &self->wayland.fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER_BINDING, self->wayland.fbo);
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->wayland.fbo_texture, 0);
|
||||
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, self->wayland.rbo);
|
||||
|
||||
if((err = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
printf("Error binding framebuffer: %0X\n", err);
|
||||
return MwFALSE;
|
||||
|
|
@ -263,6 +260,66 @@ static MwBool egl_setup(MwLL self, int width, int height) {
|
|||
return MwTRUE;
|
||||
}
|
||||
|
||||
static void egl_resetup(MwLL handle) {
|
||||
int err;
|
||||
|
||||
if(!handle->wayland.egl_do_resetup) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!eglMakeCurrent(handle->wayland.egl_display, 0, 0, handle->wayland.egl_context)) {
|
||||
printf("ERROR: eglMakeCurrent, %0X\n", eglGetError());
|
||||
return;
|
||||
}
|
||||
|
||||
if(!eglDestroySurface(handle->wayland.egl_display, handle->wayland.egl_surface)) {
|
||||
printf("ERROR: eglDestroySurface, %0X\n", eglGetError());
|
||||
return;
|
||||
};
|
||||
|
||||
handle->wayland.egl_surface = eglCreateWindowSurface(handle->wayland.egl_display, handle->wayland.egl_config, handle->wayland.egl_window_native, NULL);
|
||||
if(handle->wayland.egl_surface == EGL_NO_SURFACE) {
|
||||
printf("ERROR: eglCreateWindowSurface, %0X\n", eglGetError());
|
||||
return;
|
||||
}
|
||||
|
||||
if(!eglMakeCurrent(handle->wayland.egl_display, handle->wayland.egl_surface, handle->wayland.egl_surface, handle->wayland.egl_context)) {
|
||||
printf("ERROR: eglMakeCurrent, %0X\n", eglGetError());
|
||||
return;
|
||||
}
|
||||
|
||||
glDeleteTextures(1, &handle->wayland.fbo_texture);
|
||||
glGenTextures(1, &handle->wayland.fbo_texture);
|
||||
glBindTexture(GL_TEXTURE_2D, handle->wayland.fbo_texture);
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, handle->wayland.ww, handle->wayland.wh, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
glGenFramebuffers(1, &handle->wayland.fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER_BINDING, handle->wayland.fbo);
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, handle->wayland.fbo_texture, 0);
|
||||
|
||||
if((err = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
printf("Error binding framebuffer: %0X\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER_BINDING, 0);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, handle->wayland.ww, handle->wayland.wh, 0, -1, 1);
|
||||
glViewport(0, 0, handle->wayland.ww, handle->wayland.wh);
|
||||
|
||||
handle->wayland.egl_do_resetup = MwFALSE;
|
||||
}
|
||||
|
||||
static void xdg_toplevel_configure(void* data,
|
||||
struct xdg_toplevel* xdg_toplevel,
|
||||
MwI32 width, MwI32 height,
|
||||
|
|
@ -284,26 +341,12 @@ static void xdg_toplevel_configure(void* data,
|
|||
if(!self->wayland.egl_setup) {
|
||||
self->wayland.egl_setup = egl_setup(self, width, height);
|
||||
MwLLForceRender(self);
|
||||
} else {
|
||||
wl_egl_window_resize(self->wayland.egl_window_native, width, height, 0, 0);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, width, height, 0, -1, 1);
|
||||
self->wayland.do_clear = MwTRUE;
|
||||
|
||||
// glDeleteTextures(1, &self->wayland.fbo_texture);
|
||||
// glGenTextures(1, &self->wayland.fbo_texture);
|
||||
// glBindTexture(GL_TEXTURE_2D, self->wayland.fbo_texture);
|
||||
|
||||
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
// glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
wl_egl_window_resize(self->wayland.egl_window_native, width, height, 0, 0);
|
||||
self->wayland.egl_do_resetup = MwTRUE;
|
||||
egl_resetup(self);
|
||||
|
||||
return;
|
||||
};
|
||||
|
||||
|
|
@ -416,7 +459,6 @@ static void setup_callbacks(struct _MwLLWayland* wayland) {
|
|||
wayland->wl_protocol_setup_map = NULL;
|
||||
wayland->wl_protocol_map = NULL;
|
||||
|
||||
WL_INTERFACE(wl_shm);
|
||||
WL_INTERFACE(wl_compositor);
|
||||
WL_INTERFACE(wl_subcompositor);
|
||||
if(wayland->type == MWLL_WAYLAND_TOPLEVEL) {
|
||||
|
|
@ -429,8 +471,9 @@ static void setup_callbacks(struct _MwLLWayland* wayland) {
|
|||
|
||||
#undef WL_INTERFACE
|
||||
|
||||
static void setup_toplevel(MwLL r, int x, int y, int width, int height) {
|
||||
int i;
|
||||
static void setup_toplevel(MwLL r, int x, int y) {
|
||||
int i;
|
||||
struct wl_region* region;
|
||||
|
||||
r->wayland.type = MWLL_WAYLAND_TOPLEVEL;
|
||||
r->wayland.toplevel = malloc(sizeof(struct _MwLLWaylandTopLevel));
|
||||
|
|
@ -484,20 +527,29 @@ static void setup_toplevel(MwLL r, int x, int y, int width, int height) {
|
|||
r->wayland.toplevel->xdg_top_level = xdg_surface_get_toplevel(r->wayland.toplevel->xdg_surface);
|
||||
|
||||
// setup mandatory listeners
|
||||
r->wayland.toplevel->xdg_surface_listener.configure = xdg_surface_configure;
|
||||
r->wayland.toplevel->xdg_surface_listener.configure = xdg_surface_configure;
|
||||
|
||||
r->wayland.toplevel->surface_listener.enter = surface_enter;
|
||||
r->wayland.toplevel->surface_listener.leave = surface_leave;
|
||||
|
||||
r->wayland.toplevel->xdg_toplevel_listener.configure = xdg_toplevel_configure;
|
||||
r->wayland.toplevel->xdg_toplevel_listener.close = xdg_toplevel_close;
|
||||
|
||||
xdg_surface_add_listener(r->wayland.toplevel->xdg_surface, &r->wayland.toplevel->xdg_surface_listener, r);
|
||||
xdg_toplevel_add_listener(r->wayland.toplevel->xdg_top_level, &r->wayland.toplevel->xdg_toplevel_listener,
|
||||
r);
|
||||
wl_surface_add_listener(r->wayland.surface, &r->wayland.toplevel->surface_listener, r);
|
||||
|
||||
xdg_toplevel_set_title(r->wayland.toplevel->xdg_top_level, "Milsko Wayland App");
|
||||
xdg_toplevel_set_app_id(r->wayland.toplevel->xdg_top_level, "MilskoWaylandApp");
|
||||
|
||||
// Perform the initial commit and wait for the first configure event
|
||||
region = wl_compositor_create_region(r->wayland.compositor);
|
||||
wl_region_add(region, 0, 0, r->wayland.ww, r->wayland.wh);
|
||||
wl_surface_set_opaque_region(r->wayland.surface, region);
|
||||
wl_surface_commit(r->wayland.surface);
|
||||
event_loop(&r->wayland);
|
||||
wl_region_destroy(region);
|
||||
|
||||
printf("%p\n", shget(r->wayland.wl_protocol_map, zxdg_decoration_manager_v1_interface.name));
|
||||
|
||||
|
|
@ -516,21 +568,33 @@ static void setup_toplevel(MwLL r, int x, int y, int width, int height) {
|
|||
|
||||
// buffer_setup(&r->wayland);
|
||||
|
||||
wl_surface_commit(r->wayland.surface);
|
||||
|
||||
// glGenBuffers(1, &vertex_buffer);
|
||||
}
|
||||
|
||||
static void setup_subsurface(MwLL parent, MwLL r, int x, int y, int width, int height) {
|
||||
static void setup_subsurface(MwLL parent, MwLL r, int x, int y) {
|
||||
struct wl_compositor* compositor = parent->wayland.compositor;
|
||||
struct wl_subcompositor* subcompositor = parent->wayland.subcompositor;
|
||||
struct wl_surface* parent_surface = parent->wayland.surface;
|
||||
MwLL topmost_parent = parent;
|
||||
struct wl_region* region;
|
||||
|
||||
while(topmost_parent->wayland.type != MWLL_WAYLAND_TOPLEVEL) {
|
||||
topmost_parent = topmost_parent->wayland.parent;
|
||||
}
|
||||
|
||||
r->wayland.type = MWLL_WAYLAND_SUBSURFACE;
|
||||
|
||||
r->wayland.display = parent->wayland.display;
|
||||
|
||||
r->wayland.surface = wl_compositor_create_surface(compositor);
|
||||
wl_surface_add_listener(r->wayland.surface, &topmost_parent->wayland.toplevel->surface_listener, r);
|
||||
|
||||
region = wl_compositor_create_region(compositor);
|
||||
wl_region_add(region, 0, 0, r->wayland.ww, r->wayland.wh);
|
||||
wl_surface_set_opaque_region(r->wayland.surface, region);
|
||||
wl_surface_commit(r->wayland.surface);
|
||||
event_loop(&r->wayland);
|
||||
wl_region_destroy(region);
|
||||
|
||||
r->wayland.subsurface = wl_subcompositor_get_subsurface(subcompositor, r->wayland.surface, parent_surface);
|
||||
|
||||
|
|
@ -540,8 +604,8 @@ static void setup_subsurface(MwLL parent, MwLL r, int x, int y, int width, int h
|
|||
|
||||
setup_callbacks(&r->wayland);
|
||||
|
||||
r->wayland.registry = wl_display_get_registry(parent->wayland.display);
|
||||
r->wayland.display = parent->wayland.display;
|
||||
r->wayland.registry = wl_display_get_registry(topmost_parent->wayland.display);
|
||||
r->wayland.display = topmost_parent->wayland.display;
|
||||
|
||||
wl_registry_add_listener(r->wayland.registry, &r->wayland.registry_listener, r);
|
||||
if(wl_display_roundtrip(r->wayland.display) == -1) {
|
||||
|
|
@ -554,13 +618,24 @@ static void setup_subsurface(MwLL parent, MwLL r, int x, int y, int width, int h
|
|||
|
||||
r->wayland.configured = MwTRUE;
|
||||
|
||||
r->wayland.egl_context = parent->wayland.egl_context;
|
||||
r->wayland.egl_display = parent->wayland.egl_display;
|
||||
r->wayland.egl_surface = parent->wayland.egl_surface;
|
||||
r->wayland.fbo = parent->wayland.fbo;
|
||||
r->wayland.fbo_texture = parent->wayland.fbo_texture;
|
||||
r->wayland.rbo = parent->wayland.rbo;
|
||||
r->wayland.egl_context = topmost_parent->wayland.egl_context;
|
||||
r->wayland.egl_display = topmost_parent->wayland.egl_display;
|
||||
r->wayland.egl_surface = topmost_parent->wayland.egl_surface;
|
||||
r->wayland.fbo = topmost_parent->wayland.fbo;
|
||||
r->wayland.fbo_texture = topmost_parent->wayland.fbo_texture;
|
||||
}
|
||||
|
||||
static void framebuffer_action_begin(MwLL handle) {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, handle->wayland.fbo);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, handle->wayland.fbo_texture, 0);
|
||||
}
|
||||
|
||||
static void framebuffer_action_end(MwLL handle) {
|
||||
glFinish();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
|
||||
MwLL r;
|
||||
r = malloc(sizeof(*r));
|
||||
|
|
@ -576,13 +651,12 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
|
|||
r->wayland.parent = parent;
|
||||
|
||||
r->wayland.force_redraw = MwFALSE;
|
||||
r->wayland.do_clear = MwFALSE;
|
||||
r->common.success = MwTRUE;
|
||||
|
||||
if(parent == NULL) {
|
||||
setup_toplevel(r, x, y, width, height);
|
||||
setup_toplevel(r, x, y);
|
||||
} else {
|
||||
setup_subsurface(parent, r, x, y, width, height);
|
||||
setup_subsurface(parent, r, x, y);
|
||||
}
|
||||
|
||||
return r;
|
||||
|
|
@ -611,6 +685,10 @@ static void MwLLSetXYImpl(MwLL handle, int x, int y) {
|
|||
}
|
||||
|
||||
static void MwLLSetWHImpl(MwLL handle, int w, int h) {
|
||||
/* Prevent an integer underflow when the w/h is too low */
|
||||
if(w < 10 || h < 10) {
|
||||
return;
|
||||
}
|
||||
handle->wayland.ww = w;
|
||||
handle->wayland.wh = h;
|
||||
|
||||
|
|
@ -621,29 +699,74 @@ static void MwLLSetWHImpl(MwLL handle, int w, int h) {
|
|||
}
|
||||
|
||||
static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) {
|
||||
int i;
|
||||
int i, n;
|
||||
float maxX = 0, maxY = 0;
|
||||
float centerX, centerY;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, handle->wayland.fbo);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, handle->wayland.fbo_texture, 0);
|
||||
if(points_count > 3) {
|
||||
/* To avoid having to do a real triangulation algorithim:
|
||||
1.) loop through the points once to determine the bounds of the polygon
|
||||
2.) calculate the center of the polygon
|
||||
|
||||
if(points_count == 3) {
|
||||
glBegin(GL_TRIANGLES);
|
||||
} else if(points_count == 4) {
|
||||
glBegin(GL_QUADS);
|
||||
} else {
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
*/
|
||||
for(i = 0; i < points_count; i++) {
|
||||
float x = round(handle->wayland.x) + round(points[i].x);
|
||||
float y = round(handle->wayland.y) + round(points[i].y);
|
||||
if(x >= maxX) {
|
||||
maxX = x;
|
||||
}
|
||||
if(y >= maxY) {
|
||||
maxY = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
centerX = (handle->wayland.x + maxX / 2);
|
||||
centerY = (handle->wayland.y + maxY / 2);
|
||||
|
||||
/* Efficient? No. But at the end of the day it's still not that many polygons, and if a computer can't handle 12 polygons over 6 then it should not be using Wayland anyways */
|
||||
|
||||
framebuffer_action_begin(handle);
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
for(i = 0; i < points_count; i++) {
|
||||
float x = round(handle->wayland.x) + round(points[i].x);
|
||||
float y = round(handle->wayland.y) + round(points[i].y);
|
||||
|
||||
glColor3f(color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0);
|
||||
glVertex2f(
|
||||
ceil(handle->wayland.x) + ceil(points[i].x),
|
||||
ceil(handle->wayland.y) + ceil(points[i].y));
|
||||
|
||||
/* If we have a polygon that's covering the whole screen, we want to do glClear
|
||||
*/
|
||||
if(x == 0 && y == 0) {
|
||||
/*
|
||||
We determine this by checking if all of the points are at the edge of the screen (and if there's more then 6 points).
|
||||
Not a pretty solution, but unless the user does something weird like draw a triangle over itself twice, I'm pretty sure this is effective.
|
||||
*/
|
||||
if(points_count >= 6) {
|
||||
MwBool doClear = MwTRUE;
|
||||
for(n = 0; n < points_count; n++) {
|
||||
if((points[n].x >= (handle->wayland.ww) - 1 || points[n].x <= 1) && (points[n].y >= (handle->wayland.wh) - 1 || points[n].y <= 1)) {
|
||||
} else {
|
||||
doClear = MwFALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(doClear) {
|
||||
glEnd();
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glClearColor(color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0, 1);
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glVertex2f(x, y);
|
||||
if(points_count > 3) {
|
||||
glVertex2f(maxX, maxY);
|
||||
glVertex2f(x, y);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
glFinish();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
framebuffer_action_end(handle);
|
||||
}
|
||||
|
||||
static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) {
|
||||
|
|
@ -663,8 +786,8 @@ static void MwLLEndDrawImpl(MwLL handle) {
|
|||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, handle->wayland.fbo_texture);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glClearColor(0, 0, 0, 1);
|
||||
// glClear(GL_COLOR_BUFFER_BIT);
|
||||
// glClearColor(0, 0, 0, 1);
|
||||
|
||||
glColor3f(1.0, 1.0, 1.0);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue