[gegl/gsoc2009-gpu] gegl:levels: implement GPU processor
- From: Jerson Michael Perpetua <jperpetua src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gegl/gsoc2009-gpu] gegl:levels: implement GPU processor
- Date: Sun, 23 Aug 2009 14:32:40 +0000 (UTC)
commit 187429f349f285222d526e40d96f1c4f85b2e5a4
Author: Jerson Michael Perpetua <jersonperpetua gmail com>
Date: Sun Aug 23 22:27:08 2009 +0800
gegl:levels: implement GPU processor
operations/common/levels.c | 123 ++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 123 insertions(+), 0 deletions(-)
---
diff --git a/operations/common/levels.c b/operations/common/levels.c
index 1ff37fc..330b85b 100644
--- a/operations/common/levels.c
+++ b/operations/common/levels.c
@@ -17,6 +17,8 @@
*/
+#include <GL/glew.h>
+
#include "config.h"
#include <glib/gi18n-lib.h>
@@ -39,6 +41,47 @@ gegl_chant_double (out_high, _("High output"),
#include "gegl-chant.h"
+#include "gegl-gpu-types.h"
+#include "gegl-gpu-init.h"
+
+static const char* shader_program_str = " \
+uniform sampler2DRect pixels; \
+uniform float in_offset, out_offset, scale; \
+ \
+void main() \
+{ \
+ vec4 pixel = texture2DRect(pixels, gl_TexCoord[0].st); \
+ vec3 color = (pixel.rgb - in_offset) * scale + out_offset; \
+ gl_FragColor = vec4 (color, pixel.a); \
+} ";
+
+static GLuint shader_program = 0;
+static GLuint pixels_param;
+static GLuint in_offset_param;
+static GLuint out_offset_param;
+static GLuint scale_param;
+
+static GLuint
+create_shader_program (void)
+{
+ GLuint shader = glCreateShader (GL_FRAGMENT_SHADER);
+ GLuint program;
+
+ glShaderSource (shader, 1, &shader_program_str, NULL);
+ glCompileShader (shader);
+
+ program = glCreateProgram ();
+ glAttachShader (program, shader);
+ glLinkProgram (program);
+
+ pixels_param = glGetUniformLocation (program, "pixels");
+ in_offset_param = glGetUniformLocation (program, "in_offset");
+ out_offset_param = glGetUniformLocation (program, "out_offset");
+ scale_param = glGetUniformLocation (program, "scale");
+
+ return program;
+}
+
/* GeglOperationPointFilter gives us a linear buffer to operate on
* in our requested pixel format
*/
@@ -84,6 +127,82 @@ process (GeglOperation *op,
return TRUE;
}
+static gboolean
+process_gpu (GeglOperation *op,
+ GeglGpuTexture *in,
+ GeglGpuTexture *out,
+ glong samples,
+ const GeglRectangle *roi)
+{
+ /* Retrieve a pointer to GeglChantO structure which contains all the
+ * chanted properties
+ */
+ GeglChantO *o = GEGL_CHANT_PROPERTIES (op);
+ gfloat in_range = o->in_high - o->in_low;
+ gfloat out_range = o->out_high - o->out_low;
+ gfloat in_offset = o->in_low * 1.0;
+ gfloat out_offset = o->out_low * 1.0;
+ gfloat scale;
+
+ if (in_range == 0.0)
+ in_range = 0.00000001;
+
+ scale = out_range / in_range;
+
+ /* attach *out* texture to offscreen framebuffer */
+ glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT,
+ GL_COLOR_ATTACHMENT0_EXT,
+ GL_TEXTURE_RECTANGLE_ARB,
+ out->handle,
+ 0);
+
+ /* set *out* texture as render target */
+ glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT);
+
+ /* create and register shader program, all shader programs will be deleted
+ * after GEGL terminates
+ */
+ if (shader_program == 0)
+ {
+ shader_program = create_shader_program ();
+ gegl_gpu_register_shader_program (shader_program);
+ }
+ glUseProgram (shader_program);
+
+ /* setup shader parameters */
+ glActiveTexture (GL_TEXTURE0);
+ glBindTexture (GL_TEXTURE_RECTANGLE_ARB, in->handle);
+ glUniform1i (pixels_param, 0);
+ glUniform1f (in_offset_param, in_offset);
+ glUniform1f (out_offset_param, out_offset);
+ glUniform1f (scale_param, scale);
+
+ /* viewport transform for 1:1 pixel=texel=data mapping */
+ glMatrixMode (GL_PROJECTION);
+ glLoadIdentity ();
+ gluOrtho2D (0.0, roi->width, 0.0, roi->height);
+ glMatrixMode (GL_MODELVIEW);
+ glLoadIdentity ();
+ glViewport (0, 0, roi->width, roi->height);
+
+ /* make quad filled to hit every pixel/texel */
+ glPolygonMode (GL_FRONT, GL_FILL);
+
+ /* and render quad */
+ glBegin (GL_QUADS);
+ glTexCoord2f (0.0, 0.0);
+ glVertex2f (0.0, 0.0);
+ glTexCoord2f (roi->width, 0.0);
+ glVertex2f (roi->width, 0.0);
+ glTexCoord2f (roi->width, roi->height);
+ glVertex2f (roi->width, roi->height);
+ glTexCoord2f (0.0, roi->height);
+ glVertex2f (0.0, roi->height);
+ glEnd ();
+
+ return TRUE;
+}
+
static void
gegl_chant_class_init (GeglChantClass *klass)
@@ -100,6 +219,10 @@ gegl_chant_class_init (GeglChantClass *klass)
operation_class->categories = "color";
operation_class->description =
_("Remaps the intensity range of the image");
+
+ gegl_operation_class_add_processor (operation_class,
+ G_CALLBACK (process_gpu),
+ "gpu:reference");
}
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]