From 5d8ed178fb7259936ad824c12b148d541840fa73 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Thu, 15 Mar 2012 09:52:50 +0100 Subject: wimmel_gl: Use a second texture unit for search region Speeds up calulation from ~11s to ~10s. --- wimmel.frag | 3 ++- wimmel_gl.c | 48 +++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/wimmel.frag b/wimmel.frag index b148852..42b0139 100644 --- a/wimmel.frag +++ b/wimmel.frag @@ -1,5 +1,6 @@ varying vec2 v_texcoord; uniform sampler2D tex; +uniform sampler2D tex2; uniform vec2 pixelsize; /* The rect to match against */ uniform vec4 srect; @@ -13,8 +14,8 @@ main() for (i = 0.0; i < srect[2] && diff < barrier; i += pixelsize.x) { for (j = 0.0; j < srect[3] && diff < barrier; j += pixelsize.y) { - vec4 match = texture2D(tex, srect.xy + vec2(i,j)); vec4 orig = texture2D(tex, v_texcoord + vec2(i,j)); + vec4 match = texture2D(tex2, vec2(i, j) / srect.zw); diff += int(any(greaterThan(abs(orig - match), vec4(0.2)))); } diff --git a/wimmel_gl.c b/wimmel_gl.c index 0432823..2d33edb 100644 --- a/wimmel_gl.c +++ b/wimmel_gl.c @@ -16,9 +16,10 @@ EGLDisplay dpy; GLuint vbo; -GLint proj_uniform, tex_uniform, pixelsize_uniform, +GLint proj_uniform, tex_uniform, tex2_uniform, pixelsize_uniform, search_rect_uniform, barrier_uniform; GLuint texture; +GLuint texture2; int width, height; GLuint program; GdkPixbuf *pixbuf; @@ -78,6 +79,7 @@ init_shaders() glUseProgram(program); proj_uniform = glGetUniformLocation(program, "proj"); tex_uniform = glGetUniformLocation(program, "tex"); + tex2_uniform = glGetUniformLocation(program, "tex2"); pixelsize_uniform = glGetUniformLocation(program, "pixelsize"); search_rect_uniform = glGetUniformLocation(program, "srect"); barrier_uniform = glGetUniformLocation(program, "barrier"); @@ -113,14 +115,22 @@ init_shaders() return 0; } +static inline int +align(int value, int alignment) +{ + return (value + alignment - 1) & ~(alignment - 1); +} + static void -create_texture(GdkPixbuf *pixbuf) +create_texture(GdkPixbuf *pixbuf, GLuint *texture, int i) { - void *data; + guchar *data, *buffer = NULL; + int width, height, stride, nch, new_stride; GLenum format; - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); + glActiveTexture(GL_TEXTURE0 + i); + glGenTextures(1, texture); + glBindTexture(GL_TEXTURE_2D, *texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -132,10 +142,28 @@ create_texture(GdkPixbuf *pixbuf) format = GL_RGBA; else format = GL_RGB; + + width = gdk_pixbuf_get_width(pixbuf); + height = gdk_pixbuf_get_height(pixbuf); + stride = gdk_pixbuf_get_rowstride(pixbuf); + nch = gdk_pixbuf_get_n_channels(pixbuf); + + new_stride = align(nch * width, 4); + + if (stride != new_stride) { + buffer = malloc(new_stride * height); + for (int row = 0; row < height; ++row) + memcpy(buffer + row * new_stride, + data + row * stride, + width * nch); + data = buffer; + } glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, format, GL_UNSIGNED_BYTE, data); + if (buffer != NULL) + free(buffer); } static void @@ -155,6 +183,7 @@ draw(void) glUniformMatrix4fv(proj_uniform, 1, GL_FALSE, proj); glUniform1i(tex_uniform, 0); + glUniform1i(tex2_uniform, 1); glUniform2fv(pixelsize_uniform, 1, pixelsize); search[0] = 1.0 * x1 / width; @@ -167,7 +196,6 @@ draw(void) glDisable(GL_BLEND); - glBindTexture(GL_TEXTURE_2D, texture); glBindBuffer(GL_ARRAY_BUFFER, vbo); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GL_FLOAT), NULL); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GL_FLOAT), (GLfloat *)0 + 3); @@ -233,6 +261,7 @@ main(int argc, char **argv) { gint stride; guchar *buffer; + GdkPixbuf *match; g_type_init(); @@ -254,7 +283,12 @@ main(int argc, char **argv) mheight = atoi(argv[5]); init_shaders(); - create_texture(pixbuf); + create_texture(pixbuf, &texture, 0); + + match = gdk_pixbuf_new_subpixbuf(pixbuf, x1, y1, mwidth, mheight); + create_texture(match, &texture2, 1); + g_object_unref(match); + glViewport(0,0,width,height); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); -- cgit