"#version 150\n"
"uniform vec4 geometry;\n"
"in vec2 vertex;\n"
+ "in vec2 texture_coord;\n"
"out vec2 texcoord;\n"
"void main()\n"
"{\n"
" gl_Position = vec4((geometry.xy+vertex*geometry.zw)*2.0-1.0, 0.0, 1.0);\n"
- " texcoord = vec2(vertex.x, 1.0-vertex.y);\n"
+ " texcoord = texture_coord;\n"
"}\n";
static const char *fshader =
"#version 150\n"
- "uniform sampler2D window;\n"
+ "uniform sampler2D image;\n"
"in vec2 texcoord;\n"
"out vec4 frag_color;\n"
"void main()\n"
"{\n"
- " frag_color = texture(window, texcoord);\n"
+ " frag_color = texture(image, texcoord);\n"
"}\n";
static const float vertices[] =
{
- 0.0f, 1.0f,
- 0.0f, 0.0f,
- 1.0f, 1.0f,
- 1.0f, 0.0f
+ /* vertex texcoord */
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f,
+ 1.0f, 1.0f, 1.0f, 0.0f,
+ 1.0f, 0.0f, 1.0f, 1.0f
};
int terminate_requested = 0;
return shader;
}
-int create_gl_resources(Compositor *compositor, CompositedScreen *screen)
+unsigned link_program(unsigned *shaders, unsigned nshaders)
{
+ unsigned program;
+ unsigned i;
int status;
char info_log[1024];
GLsizei length;
+ program = glCreateProgram();
+ for(i=0; i<nshaders; ++i)
+ glAttachShader(program, shaders[i]);
+ glBindAttribLocation(program, 0, "vertex");
+ glBindAttribLocation(program, 1, "texture_coord");
+ glBindFragDataLocation(program, 0, "frag_color");
+ glLinkProgram(program);
+
+ glGetProgramiv(program, GL_LINK_STATUS, &status);
+ glGetProgramInfoLog(program, sizeof(info_log), &length, info_log);
+ if(!status)
+ {
+ fprintf(stderr, "Program link failed:\n%s\n", info_log);
+ glDeleteProgram(program);
+ return 0;
+ }
+ else if(length)
+ printf("Program info log:\n%s\n", info_log);
+
+ return program;
+}
+
+int create_gl_resources(Compositor *compositor, CompositedScreen *screen)
+{
+ unsigned stride;
+
use_gl(compositor, screen);
screen->shaders[0] = compile_shader(GL_VERTEX_SHADER, vshader);
if(!screen->shaders[0] || !screen->shaders[1])
return 0;
- screen->program = glCreateProgram();
- glAttachShader(screen->program, screen->shaders[0]);
- glAttachShader(screen->program, screen->shaders[1]);
- glBindAttribLocation(screen->program, 0, "vertex");
- glLinkProgram(screen->program);
+ screen->program = link_program(screen->shaders, 2);
+ if(!screen->program)
+ return 0;
screen->geometry_loc = glGetUniformLocation(screen->program, "geometry");
- glGetProgramiv(screen->program, GL_LINK_STATUS, &status);
- glGetProgramInfoLog(screen->program, sizeof(info_log), &length, info_log);
- if(!status)
- {
- fprintf(stderr, "Program link failed:\n%s\n", info_log);
- glDeleteProgram(screen->program);
- return 0;
- }
- else if(length)
- printf("Program info log:\n%s\n", info_log);
-
glGenBuffers(1, &screen->vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, screen->vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
+ stride = 4*sizeof(float);
glGenVertexArrays(1, &screen->vertex_array);
glBindVertexArray(screen->vertex_array);
- glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL);
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, stride, NULL);
glEnableVertexAttribArray(0);
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, stride, (void *)(2*sizeof(float)));
+ glEnableVertexAttribArray(1);
+ glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
void process_create_window_event(Compositor *compositor, XCreateWindowEvent *event)
{
- CompositedScreen *screen = find_screen_by_root(compositor, event->parent);
- if(!screen)
- return;
+ CompositedScreen *screen;
- add_window(compositor, screen, event->window);
+ if((screen = find_screen_by_root(compositor, event->parent)))
+ add_window(compositor, screen, event->window);
}
void process_destroy_window_event(Compositor *compositor, XDestroyWindowEvent *event)
CompositedScreen *screen;
CompositedWindow *window;
- screen = find_screen_by_root(compositor, event->event);
- if(!screen)
- return;
-
- window = find_window(screen, event->window);
- if(window)
- remove_window(compositor, screen, window, 1);
+ if((screen = find_screen_by_root(compositor, event->event)))
+ if((window = find_window(screen, event->window)))
+ remove_window(compositor, screen, window, 1);
}
void process_map_event(Compositor *compositor, XMapEvent *event)
return 1;
}
-void refresh_screens(Compositor *compositor)
+void refresh_screen(Compositor *compositor, CompositedScreen *screen)
{
- unsigned i, j;
+ unsigned i;
- for(i=0; i<compositor->nscreens; ++i)
+ use_gl(compositor, screen);
+
+ glClearColor(0.5f, 0.5f, 0.5f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glUseProgram(screen->program);
+ glBindVertexArray(screen->vertex_array);
+ for(i=0; i<screen->nwindows; ++i)
{
- CompositedScreen *screen = &compositor->screens[i];
- if(!screen->dirty)
+ CompositedWindow *window = &screen->windows[i];
+ if(window->map_state!=IsViewable)
continue;
- use_gl(compositor, 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->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);
+ XDamageSubtract(compositor->display, window->damage, None, None);
+ }
- glClearColor(0.5f, 0.5f, 0.5f, 0.0f);
- glClear(GL_COLOR_BUFFER_BIT);
+ glXSwapBuffers(compositor->display, screen->glx_window);
- glUseProgram(screen->program);
- glBindVertexArray(screen->vertex_array);
- for(j=0; j<screen->nwindows; ++j)
- {
- CompositedWindow *window = &screen->windows[j];
- if(window->map_state==IsViewable)
- {
- 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->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);
- XDamageSubtract(compositor->display, window->damage, None, None);
- }
- }
- glXSwapBuffers(compositor->display, screen->glx_window);
+ screen->dirty = 0;
+}
- screen->dirty = 0;
+void refresh_all_screens(Compositor *compositor)
+{
+ unsigned i;
+
+ for(i=0; i<compositor->nscreens; ++i)
+ {
+ CompositedScreen *screen = &compositor->screens[i];
+ if(screen->dirty)
+ refresh_screen(compositor, screen);
}
compositor->dirty = 0;
while(!terminate_requested)
{
if(!process_event(&compositor))
- refresh_screens(&compositor);
+ refresh_all_screens(&compositor);
}
shutdown_compositor(&compositor);