X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fmain.c;h=92537e21a59bf3c01dee00ec66e94bb75109cde1;hb=44e0516f74915a4e50fdb48d3d2fa90df9013b12;hp=f34acb54885ac30a1e1d5ea18869f6aba83f5151;hpb=551624d89ac272ef91d99c6c51c6579adadbf5c5;p=geometrycompositor.git diff --git a/source/main.c b/source/main.c index f34acb5..92537e2 100644 --- a/source/main.c +++ b/source/main.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -33,6 +34,10 @@ typedef struct CompositedMonitor int y; unsigned width; unsigned height; + float keystone_vertical; + float cylinder_depth; + float vertical_center; + float perspective; unsigned vertex_buffer; unsigned index_buffer; unsigned vertex_array; @@ -455,24 +460,49 @@ void update_monitor_vertices(CompositedScreen *screen, CompositedMonitor *monito unsigned short *index_data; unsigned x, y; unsigned i; + float aspect; + float cyl_w_sq; + float sin_ksv; + float cos_ksv; t = monitor->tessellation; data_size = (t+1)*(t+1)*4*sizeof(float); vertex_data = (float *)malloc(data_size); + aspect = (float)monitor->width/monitor->height; + cyl_w_sq = 0.25f-(0.5f-monitor->cylinder_depth)*(0.5f-monitor->cylinder_depth); + sin_ksv = monitor->keystone_vertical/sqrt(1.0f+monitor->keystone_vertical*monitor->keystone_vertical); + cos_ksv = sqrt(1.0f-sin_ksv*sin_ksv); for(y=0; y<=t; ++y) for(x=0; x<=t; ++x) { - float xf, yf; + float xf, yf, z, rz; + float scale; float *v; xf = (float)x/t; yf = (float)y/t; + v = vertex_data+(y*(t+1)+x)*4; - v[0] = xf; - v[1] = yf; v[2] = (monitor->x+xf*monitor->width)/screen->width; v[3] = (monitor->y+yf*monitor->height)/screen->height; + + z = sqrt(0.25f-(xf-0.5f)*(xf-0.5f)*4.0f*cyl_w_sq)-0.5f+monitor->cylinder_depth; + if(monitor->keystone_vertical>0) + { + rz = (1.0f-yf)/aspect*sin_ksv+z*cos_ksv; + yf = 1.0f-((1.0f-yf)*cos_ksv-z*aspect*sin_ksv); + z = rz; + } + else if(monitor->keystone_vertical<0) + { + rz = z*cos_ksv-yf/aspect*sin_ksv; + yf = yf*cos_ksv+z*aspect*sin_ksv; + z = rz; + } + scale = monitor->perspective/(monitor->perspective+z); + v[0] = 0.5f+(xf-0.5f)*scale; + v[1] = monitor->vertical_center+(yf-monitor->vertical_center)*scale; } glBindBuffer(GL_ARRAY_BUFFER, monitor->vertex_buffer); glBufferData(GL_ARRAY_BUFFER, data_size, vertex_data, GL_STATIC_DRAW); @@ -499,13 +529,16 @@ void update_monitor_vertices(CompositedScreen *screen, CompositedMonitor *monito free(index_data); } -int initialize_monitor(Compositor *compositor, CompositedScreen *screen, CompositedMonitor *monitor, XRRScreenResources *xrr_res, unsigned index) +int initialize_monitor(Compositor *compositor, CompositedScreen *screen, XRRScreenResources *xrr_res, unsigned index) { + CompositedMonitor *monitor; XRROutputInfo *output; XRRCrtcInfo *crtc; unsigned buffers[2]; unsigned stride; + monitor = &screen->monitors[index]; + output = XRRGetOutputInfo(compositor->display, xrr_res, xrr_res->outputs[index]); monitor->enabled = !!output->crtc; if(!monitor->enabled) @@ -522,11 +555,16 @@ int initialize_monitor(Compositor *compositor, CompositedScreen *screen, Composi XRRFreeCrtcInfo(crtc); XRRFreeOutputInfo(output); + monitor->keystone_vertical = 0.0f; + monitor->cylinder_depth = 0.0f; + monitor->vertical_center = 0.5f; + monitor->perspective = 1.0f; + glGenBuffers(2, buffers); monitor->vertex_buffer = buffers[0]; monitor->index_buffer = buffers[1]; - monitor->tessellation = 20; + monitor->tessellation = 50; update_monitor_vertices(screen, monitor); stride = 4*sizeof(float); @@ -583,7 +621,7 @@ int initialize_screen(Compositor *compositor, unsigned number) screen->nmonitors = xrr_res->noutput; screen->monitors = (CompositedMonitor *)malloc(screen->nmonitors*sizeof(CompositedMonitor)); for(i=0; inmonitors; ++i) - if(!initialize_monitor(compositor, screen, &screen->monitors[i], xrr_res, i)) + if(!initialize_monitor(compositor, screen, xrr_res, i)) return 0; XRRFreeScreenResources(xrr_res); @@ -684,6 +722,22 @@ void shutdown_screen(Compositor *compositor, CompositedScreen *screen) } } + for(i=0; inmonitors; ++i) + if(screen->monitors[i].enabled) + { + glDeleteBuffers(1, &screen->monitors[i].vertex_buffer); + glDeleteBuffers(1, &screen->monitors[i].index_buffer); + glDeleteVertexArrays(1, &screen->monitors[i].vertex_array); + } + + glDeleteBuffers(1, &screen->window_vertex_buffer); + glDeleteVertexArrays(1, &screen->window_vertex_array); + glDeleteFramebuffers(1, &screen->framebuffer); + glDeleteTextures(1, &screen->fb_texture); + glDeleteProgram(screen->program); + glDeleteShader(screen->shaders[0]); + glDeleteShader(screen->shaders[1]); + glXMakeContextCurrent(compositor->display, 0, 0, NULL); glXDestroyContext(compositor->display, screen->glx_context); glXDestroyWindow(compositor->display, screen->glx_window); @@ -894,7 +948,7 @@ void refresh_screen(Compositor *compositor, CompositedScreen *screen) glBindTexture(GL_TEXTURE_2D, window->texture); compositor->glXBindTexImageEXT(compositor->display, window->glx_pixmap, GLX_FRONT_LEFT_EXT, NULL); glUniform4f(screen->geometry_loc, - (float)window->x/screen->width, (float)(screen->height-window->y-window->height)/screen->height, + (float)window->x/screen->width, ((float)screen->height-window->y-window->height)/screen->height, (float)(window->width+2*window->border)/screen->width, (float)(window->height+2*window->border)/screen->height); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); compositor->glXReleaseTexImageEXT(compositor->display, window->glx_pixmap, GLX_FRONT_LEFT_EXT); @@ -922,6 +976,8 @@ void refresh_screen(Compositor *compositor, CompositedScreen *screen) glDrawElements(GL_TRIANGLE_STRIP, monitor->nelements, GL_UNSIGNED_SHORT, NULL); } + glBindVertexArray(0); + glXSwapBuffers(compositor->display, screen->glx_window); screen->dirty = 0;