X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fmain.c;h=6412285729296df8fabe6f8053612bd7ac3da8b4;hb=60f2501901790f0fd34e1d82289a88867c3b38f3;hp=13038c29ef83f6b8292a6e970edd06225c4de652;hpb=03938166b24208348b4ea25600b4d06c8fd2400a;p=geometrycompositor.git diff --git a/source/main.c b/source/main.c index 13038c2..6412285 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);