[gtk+] GdkGL: Fix up GL_ARB_texture_rectangle support
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] GdkGL: Fix up GL_ARB_texture_rectangle support
- Date: Thu, 6 Nov 2014 11:25:54 +0000 (UTC)
commit 5f9e6ec2dc2e5ae4442d5cdb64684cd4a51d20d4
Author: Alexander Larsson <alexl redhat com>
Date: Thu Nov 6 11:31:01 2014 +0100
GdkGL: Fix up GL_ARB_texture_rectangle support
This broke when gdk_gl_texture_quad moved to shaders. We need
a specialized shader for the rectangle case.
gdk/gdkgl.c | 80 ++++++++++++++++++++++++++++++++++++++------
gdk/gdkglcontextprivate.h | 5 +++
gdk/gdkinternals.h | 1 +
gdk/x11/gdkglcontext-x11.c | 47 +++++++++++++++----------
4 files changed, 103 insertions(+), 30 deletions(-)
---
diff --git a/gdk/gdkgl.c b/gdk/gdkgl.c
index 44d205e..6d0e8f4 100644
--- a/gdk/gdkgl.c
+++ b/gdk/gdkgl.c
@@ -140,7 +140,10 @@ bind_vao (GdkGLContextPaintData *paint_data)
}
static void
-use_texture_program (GdkGLContextPaintData *paint_data)
+use_texture_2d_program (GdkGLContextPaintData *paint_data,
+ guint *position_location,
+ guint *uv_location,
+ guint *map_location)
{
const char *vertex_shader_code =
"#version 120\n"
@@ -165,6 +168,7 @@ use_texture_program (GdkGLContextPaintData *paint_data)
paint_data->texture_quad_program = make_program (vertex_shader_code, fragment_shader_code);
paint_data->texture_quad_program_position_location = glGetAttribLocation
(paint_data->texture_quad_program, "position");
paint_data->texture_quad_program_uv_location = glGetAttribLocation (paint_data->texture_quad_program,
"uv");
+ paint_data->texture_quad_program_map_location = glGetUniformLocation
(paint_data->texture_quad_program, "map");
}
if (paint_data->current_program != paint_data->texture_quad_program)
@@ -172,10 +176,59 @@ use_texture_program (GdkGLContextPaintData *paint_data)
glUseProgram (paint_data->texture_quad_program);
paint_data->current_program = paint_data->texture_quad_program;
}
+
+ *position_location = paint_data->texture_quad_program_position_location;
+ *uv_location = paint_data->texture_quad_program_uv_location;
+ *map_location = paint_data->texture_quad_program_map_location;
}
+static void
+use_texture_rect_program (GdkGLContextPaintData *paint_data,
+ guint *position_location,
+ guint *uv_location,
+ guint *map_location)
+{
+ const char *vertex_shader_code =
+ "#version 120\n"
+ "uniform sampler2DRect map;"
+ "attribute vec2 position;\n"
+ "attribute vec2 uv;\n"
+ "varying vec2 vUv;\n"
+ "void main() {\n"
+ " gl_Position = vec4(position, 0, 1);\n"
+ " vUv = uv;\n"
+ "}\n";
+ const char *fragment_shader_code =
+ "#version 120\n"
+ "varying vec2 vUv;\n"
+ "uniform sampler2DRect map;\n"
+ "void main() {\n"
+ " gl_FragColor = texture2DRect (map, vUv);\n"
+ "}\n";
+
+ if (paint_data->texture_quad_rect_program == 0)
+ {
+ paint_data->texture_quad_rect_program = make_program (vertex_shader_code, fragment_shader_code);
+ paint_data->texture_quad_rect_program_position_location = glGetAttribLocation
(paint_data->texture_quad_rect_program, "position");
+ paint_data->texture_quad_rect_program_uv_location = glGetAttribLocation
(paint_data->texture_quad_rect_program, "uv");
+ paint_data->texture_quad_rect_program_map_location = glGetUniformLocation
(paint_data->texture_quad_rect_program, "map");
+ }
+
+ if (paint_data->current_program != paint_data->texture_quad_rect_program)
+ {
+ glUseProgram (paint_data->texture_quad_rect_program);
+ paint_data->current_program = paint_data->texture_quad_rect_program;
+ }
+
+ *position_location = paint_data->texture_quad_rect_program_position_location;
+ *uv_location = paint_data->texture_quad_rect_program_uv_location;
+ *map_location = paint_data->texture_quad_rect_program_map_location;
+}
+
+
void
gdk_gl_texture_quad (GdkGLContext *paint_context,
+ guint texture_target,
float x1, float y1,
float x2, float y2,
float u1, float v1,
@@ -197,6 +250,7 @@ gdk_gl_texture_quad (GdkGLContext *paint_context,
u1, v2,
u1, v1,
};
+ guint position_location, uv_location, map_location;
bind_vao (paint_data);
@@ -206,19 +260,22 @@ gdk_gl_texture_quad (GdkGLContext *paint_context,
if (paint_data->tmp_uv_buffer == 0)
glGenBuffers(1, &paint_data->tmp_uv_buffer);
- use_texture_program (paint_data);
+ if (texture_target == GL_TEXTURE_RECTANGLE_ARB)
+ use_texture_rect_program (paint_data, &position_location, &uv_location, &map_location);
+ else
+ use_texture_2d_program (paint_data, &position_location, &uv_location, &map_location);
glActiveTexture (GL_TEXTURE0);
+ glUniform1i(map_location, 0); /* Use texture unit 0 */
+
glEnableVertexAttribArray (0);
glBindBuffer (GL_ARRAY_BUFFER, paint_data->tmp_vertex_buffer);
glBufferData (GL_ARRAY_BUFFER, sizeof(vertex_buffer_data), vertex_buffer_data, GL_STREAM_DRAW);
- glVertexAttribPointer (paint_data->texture_quad_program_position_location,
- 2, GL_FLOAT, GL_FALSE, 0, NULL);
+ glVertexAttribPointer (position_location, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray (1);
glBindBuffer (GL_ARRAY_BUFFER, paint_data->tmp_uv_buffer);
glBufferData (GL_ARRAY_BUFFER, sizeof(uv_buffer_data), uv_buffer_data, GL_STREAM_DRAW);
- glVertexAttribPointer (paint_data->texture_quad_program_uv_location,
- 2, GL_FLOAT, GL_FALSE, 0, NULL);
+ glVertexAttribPointer (uv_location, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glDrawArrays (GL_TRIANGLE_FAN, 0, 4);
glDisableVertexAttribArray (0);
glDisableVertexAttribArray (1);
@@ -497,6 +554,7 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
int clipped_src_y = y + (height - dest.height - (dest.y - dy * window_scale));
gdk_gl_texture_quad (paint_context,
+ GL_TEXTURE_2D,
dest.x, FLIP_Y(dest.y),
dest.x + dest.width, FLIP_Y(dest.y + dest.height),
clipped_src_x / (float)texture_width, (clipped_src_y + dest.height) /
(float)texture_height,
@@ -634,10 +692,10 @@ gdk_gl_texture_from_surface (cairo_surface_t *surface,
glBindTexture (target, texture_id);
glEnable (target);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri (target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri (target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
n_rects = cairo_region_num_rectangles (region);
for (i = 0; i < n_rects; i++)
@@ -677,7 +735,7 @@ gdk_gl_texture_from_surface (cairo_surface_t *surface,
vmax = 1.0;
}
- gdk_gl_texture_quad (paint_context,
+ gdk_gl_texture_quad (paint_context, target,
rect.x * window_scale, FLIP_Y(rect.y) * window_scale,
(rect.x + rect.width) * window_scale, FLIP_Y(rect.y + rect.height) * window_scale,
0, 0,
diff --git a/gdk/gdkglcontextprivate.h b/gdk/gdkglcontextprivate.h
index c738fa5..ec4ab33 100644
--- a/gdk/gdkglcontextprivate.h
+++ b/gdk/gdkglcontextprivate.h
@@ -65,6 +65,11 @@ typedef struct {
guint texture_quad_program;
guint texture_quad_program_position_location;
guint texture_quad_program_uv_location;
+ guint texture_quad_program_map_location;
+ guint texture_quad_rect_program;
+ guint texture_quad_rect_program_position_location;
+ guint texture_quad_rect_program_uv_location;
+ guint texture_quad_rect_program_map_location;
} GdkGLContextPaintData;
GdkGLContextPaintData *gdk_gl_context_get_paint_data (GdkGLContext *context);
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index 14141bd..6543f55 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -351,6 +351,7 @@ gboolean _gdk_cairo_surface_extents (cairo_surface_t *surface,
void gdk_gl_texture_from_surface (cairo_surface_t *surface,
cairo_region_t *region);
void gdk_gl_texture_quad (GdkGLContext *paint_context,
+ guint texture_target,
float x1, float y1,
float x2, float y2,
float u1, float v1,
diff --git a/gdk/x11/gdkglcontext-x11.c b/gdk/x11/gdkglcontext-x11.c
index a0258b9..fe1b18a 100644
--- a/gdk/x11/gdkglcontext-x11.c
+++ b/gdk/x11/gdkglcontext-x11.c
@@ -280,7 +280,7 @@ glx_pixmap_destroy (void *data)
}
static GdkGLXPixmap *
-glx_pixmap_get (cairo_surface_t *surface)
+glx_pixmap_get (cairo_surface_t *surface, guint texture_target)
{
Display *display = cairo_xlib_surface_get_display (surface);
Screen *screen = cairo_xlib_surface_get_screen (surface);
@@ -324,12 +324,22 @@ glx_pixmap_get (cairo_surface_t *surface)
glXGetFBConfigAttrib (display, fbconfigs[i],
GLX_BIND_TO_TEXTURE_TARGETS_EXT,
&value);
- if ((value & (GLX_TEXTURE_RECTANGLE_BIT_EXT | GLX_TEXTURE_2D_BIT_EXT)) == 0)
- continue;
- if ((value & GLX_TEXTURE_2D_BIT_EXT))
- target = GLX_TEXTURE_2D_EXT;
+ if (texture_target == GL_TEXTURE_2D)
+ {
+ if (value & GLX_TEXTURE_2D_BIT_EXT)
+ target = GLX_TEXTURE_2D_EXT;
+ else
+ continue;
+ }
+ else if (texture_target == GL_TEXTURE_RECTANGLE_ARB)
+ {
+ if (value & GLX_TEXTURE_RECTANGLE_BIT_EXT)
+ target = GLX_TEXTURE_RECTANGLE_EXT;
+ else
+ continue;
+ }
else
- target = GLX_TEXTURE_RECTANGLE_EXT;
+ continue;
if (!with_alpha)
{
@@ -400,12 +410,16 @@ gdk_x11_gl_context_texture_from_surface (GdkGLContext *paint_context,
if (cairo_surface_get_type (surface) != CAIRO_SURFACE_TYPE_XLIB)
return FALSE;
- glx_pixmap = glx_pixmap_get (surface);
+ use_texture_rectangle = gdk_gl_context_use_texture_rectangle (paint_context);
+ if (use_texture_rectangle)
+ target = GL_TEXTURE_RECTANGLE_ARB;
+ else
+ target = GL_TEXTURE_2D;
+
+ glx_pixmap = glx_pixmap_get (surface, target);
if (glx_pixmap == NULL)
return FALSE;
- use_texture_rectangle = gdk_gl_context_use_texture_rectangle (paint_context);
-
window = gdk_gl_context_get_window (paint_context)->impl_window;
window_scale = gdk_window_get_scale_factor (window);
window_height = gdk_window_get_height (window);
@@ -421,19 +435,14 @@ gdk_x11_gl_context_texture_from_surface (GdkGLContext *paint_context,
/* Ensure all the X stuff are synced before we read it back via texture-from-pixmap */
glXWaitX();
- if (use_texture_rectangle)
- target = GL_TEXTURE_RECTANGLE_ARB;
- else
- target = GL_TEXTURE_2D;
-
glGenTextures (1, &texture_id);
glBindTexture (target, texture_id);
glEnable (target);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri (target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri (target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glXBindTexImageEXT (glx_pixmap->display, glx_pixmap->drawable,
GLX_FRONT_LEFT_EXT, NULL);
@@ -466,7 +475,7 @@ gdk_x11_gl_context_texture_from_surface (GdkGLContext *paint_context,
vscale = 1.0 / cairo_xlib_surface_get_height (surface);
}
- gdk_gl_texture_quad (paint_context,
+ gdk_gl_texture_quad (paint_context, target,
rect.x * window_scale, FLIP_Y(rect.y) * window_scale,
(rect.x + rect.width) * window_scale, FLIP_Y(rect.y + rect.height) * window_scale,
uscale * src_x, vscale * src_y,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]