int recreate_mask;
} CompositedWindow;
+enum
+{
+ CYLINDRICAL = 1,
+ SPHERICAL
+};
+
typedef struct CompositedMonitor
{
char *name;
unsigned width;
unsigned height;
float keystone_vertical;
- float cylinder_depth;
+ float curvature_type;
+ float curvature_depth;
float vertical_center;
float perspective;
unsigned vertex_buffer;
return;
rects = XShapeGetRectangles(compositor->display, window->window, ShapeBounding, &rect_count, &rect_order);
+ if(!rects)
+ return;
width = window->width+2*window->border;
height = window->height+2*window->border;
unsigned x, y;
unsigned i;
float aspect;
- float cyl_radius;
- float cyl_arc;
+ float curve_radius;
+ float curve_arc;
float sin_ksv;
float cos_ksv;
float distance;
aspect = (float)monitor->width/monitor->height;
- if(monitor->cylinder_depth)
+ if(monitor->curvature_depth)
{
- cyl_radius = (monitor->cylinder_depth*monitor->cylinder_depth+0.25f)/(2.0f*monitor->cylinder_depth);
- cyl_arc = 2.0f*asin(0.5f/cyl_radius);
+ curve_radius = (monitor->curvature_depth*monitor->curvature_depth+0.25f)/(2.0f*monitor->curvature_depth);
+ curve_arc = 2.0f*asin(0.5f/curve_radius);
}
sin_ksv = monitor->keystone_vertical/sqrt(1.0f+monitor->keystone_vertical*monitor->keystone_vertical);
cos_ksv = sqrt(1.0f-sin_ksv*sin_ksv);
distance = monitor->perspective+sin_ksv*((sin_ksv>0)-monitor->vertical_center)/aspect;
+ if(monitor->curvature_depth<0)
+ distance += -monitor->curvature_depth;
eye[0] = 0.0f;
eye[1] = (monitor->vertical_center-0.5f)/aspect+sin_ksv*distance;
v[0] = (float)x/t-0.5f;
v[1] = ((float)y/t-0.5f)/aspect;
v[2] = 0;
- if(monitor->cylinder_depth)
+ if(monitor->curvature_depth)
{
- v[2] = (1.0f-cos(v[0]*cyl_arc))*cyl_radius-monitor->cylinder_depth;
- v[0] = sin(v[0]*cyl_arc)*cyl_radius;
+ if(monitor->curvature_type==CYLINDRICAL)
+ {
+ v[2] = (1.0f-cos(v[0]*curve_arc))*curve_radius-monitor->curvature_depth;
+ v[0] = sin(v[0]*curve_arc)*curve_radius;
+ }
+ else if(monitor->curvature_type==SPHERICAL)
+ {
+ float r;
+
+ v[0] = tan(v[0]*curve_arc)*curve_radius;
+ v[1] = tan(v[1]*curve_arc)*curve_radius;
+ r = sqrt(v[0]*v[0]+v[1]*v[1]+curve_radius*curve_radius)/fabs(curve_radius);
+ v[0] /= r;
+ v[1] /= r;
+ v[2] = curve_radius-curve_radius/r-monitor->curvature_depth;
+ }
}
}
monitor->geometry_data[0] = t;
for(i=0; i<3; ++i)
- monitor->geometry_data[1+i] = eye[i]*10000;
+ monitor->geometry_data[1+i] = eye[i]*4096;
for(y=0; y<2; ++y)
for(x=0; x<2; ++x)
{
i = 1+(1+y*2+x)*3;
- monitor->geometry_data[i] = ((x-0.5f)*distance/monitor->perspective)*10000;
- monitor->geometry_data[i+1] = (eye[1]+look[1]*distance-(y-monitor->vertical_center)*look[2]*distance/monitor->perspective/aspect)*10000;
- monitor->geometry_data[i+2] = (eye[2]+look[2]*distance+(y-monitor->vertical_center)*look[1]*distance/monitor->perspective/aspect)*10000;
+ monitor->geometry_data[i] = ((x-0.5f)*distance/monitor->perspective)*4096;
+ monitor->geometry_data[i+1] = (eye[1]+look[1]*distance-(y-monitor->vertical_center)*look[2]*distance/monitor->perspective/aspect)*4096;
+ monitor->geometry_data[i+2] = (eye[2]+look[2]*distance+(y-monitor->vertical_center)*look[1]*distance/monitor->perspective/aspect)*4096;
}
for(i=0; i<(t+1)*(t+1)*3; ++i)
- monitor->geometry_data[16+i] = vertex_data[i]*10000;
+ monitor->geometry_data[16+i] = vertex_data[i]*4096;
for(y=t; y<=t; --y)
for(x=t; x<=t; --x)
XRRFreeOutputInfo(output);
monitor->keystone_vertical = 0.0f;
- monitor->cylinder_depth = 0.0f;
+ monitor->curvature_type = CYLINDRICAL;
+ monitor->curvature_depth = 0.0f;
monitor->vertical_center = 0.5f;
monitor->perspective = 1.0f;
use_gl(compositor, screen);
name_ptr = names;
- for(i=0; i*4<values_length; ++i)
+ for(i=0; i*5+4<values_length; ++i)
{
CompositedMonitor *monitor;
monitor = find_monitor_by_name(screen, name_ptr);
if(monitor)
{
- monitor->keystone_vertical = values[i*4]/10000.0f;
- monitor->cylinder_depth = values[i*4+1]/10000.0f;
- monitor->vertical_center = values[i*4+2]/10000.0f;
- monitor->perspective = values[i*4+3]/10000.0f;
+ monitor->keystone_vertical = values[i*5]/4096.0f;
+ monitor->curvature_type = values[i*5+1];
+ monitor->curvature_depth = values[i*5+2]/4096.0f;
+ monitor->vertical_center = values[i*5+3]/4096.0f;
+ monitor->perspective = values[i*5+4]/4096.0f;
if(monitor->enabled)
update_monitor_vertices(screen, monitor);
process_damage_event(compositor, (XDamageNotifyEvent *)&event);
else if(event.type==compositor->shape_event+ShapeNotify)
process_shape_event(compositor, (XShapeEvent *)&event);
- else
- printf("Event %d\n", event.type);
}
}
}