summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--wimmel.frag3
-rw-r--r--wimmel_gl.c48
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);