[grits] Use glBlendFuncSeparate for alpha masking in tex.c



commit 474d8fa06cb68a91acdf81c89d3bfe6dd2d7ba68
Author: Andy Spencer <andy753421 gmail com>
Date:   Mon Jan 30 06:39:15 2012 +0000

    Use glBlendFuncSeparate for alpha masking in tex.c
    
    The draw happens in two steps:
    
    1. Copy the alpha mask to the framebuffer without changing the color
       channels: glBlendFuncSeparate(GL_ZERO, GL_ONE, GL_ONE, GL_ZERO)
    
       This uses GL_LINEAR filtering and GL_CLAMP_TO_BORDER to create a
       alpha mask with hard edges as opposed to blurred edges.
    
    2. Copy the texture color to the framebuffer using the alpha mask
       stored in the frame buffer as the mask:
       glBlendFuncSeparate(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_ZERO, GL_ZERO);
    
       We can turn on GL_LINEAR filtering and GL_CLAMP here because the
       alpha mask is taken from the framebuffer instead of the filtered
       alpha component of the texture.
    
    This creates a nice looking image without having to do any fancy setup.
    The previous version also has issues if the texture is not split in the
    middle of the polygon.
    
    Unfortunately glBlendFuncSeparate depends on OpenGL 2.0 and requires
    twice as many draws.

 examples/tex/tex.c |   71 ++++++++++++++++++++++++++++++----------------------
 1 files changed, 41 insertions(+), 30 deletions(-)
---
diff --git a/examples/tex/tex.c b/examples/tex/tex.c
index bef3a34..5041226 100644
--- a/examples/tex/tex.c
+++ b/examples/tex/tex.c
@@ -21,6 +21,28 @@
 #include <GL/gl.h>
 #include <GL/glu.h>
 
+#define crazy_draw(tex) \
+	for (int _i = 0; ({ \
+		if (_i == 0) { \
+			/* Clear alpha buffer */ \
+			glBindTexture(GL_TEXTURE_2D, tex); \
+			glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); \
+			glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); \
+			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); \
+			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); \
+			glBlendFuncSeparate(GL_ZERO, GL_ONE, GL_ONE, GL_ZERO); \
+		} else if (_i == 1) { \
+			/* Draw pixels */ \
+			glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); \
+			glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); \
+			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); \
+			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); \
+			glBlendFuncSeparate(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_ZERO, GL_ZERO); \
+		} else { \
+			glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); \
+		} \
+	}), _i < 2; _i++)
+
 guint tex, texl, texr;
 
 gboolean on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer _)
@@ -32,7 +54,7 @@ gboolean on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer _)
 
 gboolean on_expose(GtkWidget *drawing, GdkEventExpose *event, gpointer _)
 {
-	gdouble y = 0.875;
+	gdouble y = 0;
 
 	/* Setup view */
 	glMatrixMode(GL_PROJECTION);
@@ -55,44 +77,33 @@ gboolean on_expose(GtkWidget *drawing, GdkEventExpose *event, gpointer _)
 	glVertex3f( 0.25, -0.75, 0.0);
 	glEnd();
 
-	/* Clear background for GL_ONE */
-	glEnable(GL_COLOR_MATERIAL);
-	glDisable(GL_TEXTURE_2D);
-	glColor4f(0.0, 0.0, 0.0, 0.0);
-	glBegin(GL_QUADS);
-	glVertex3f(-0.75,  0.0, 0.0);
-	glVertex3f(-0.75,  0.5, 0.0);
-	glVertex3f( 0.75,  0.5, 0.0);
-	glVertex3f( 0.75,  0.0, 0.0);
-	glEnd();
-
 	/* Setup for textures */
 	glEnable(GL_TEXTURE_2D);
 	glEnable(GL_BLEND);
 	glColor4f(1.0, 1.0, 1.0, 1.0);
 	glDisable(GL_COLOR_MATERIAL);
-	glBlendFunc(GL_ONE, GL_ONE);
 
 	/* Left */
-	glBindTexture(GL_TEXTURE_2D, texl);
-	glBegin(GL_QUADS);
-	glTexCoord2f( 0.0, y);     glVertex3f(-0.75,  0.0, 0.0);
-	glTexCoord2f( 0.0, 1.0);   glVertex3f(-0.75,  0.5, 0.0);
-	glTexCoord2f( 2.0, 1.0);   glVertex3f( 0.75,  0.5, 0.0);
-	glTexCoord2f( 2.0, y);     glVertex3f( 0.75,  0.0, 0.0);
-	glEnd();
+	crazy_draw(texl) {
+		glBegin(GL_QUADS);
+		glTexCoord2f( 0.0, y);     glVertex3f(-0.75,  0.0, 0.0);
+		glTexCoord2f( 0.0, 1.0);   glVertex3f(-0.75,  0.5, 0.0);
+		glTexCoord2f( 2.0, 1.0);   glVertex3f( 0.75,  0.5, 0.0);
+		glTexCoord2f( 2.0, y);     glVertex3f( 0.75,  0.0, 0.0);
+		glEnd();
+	}
 
 	/* Right */
-	glBindTexture(GL_TEXTURE_2D, texr);
-	glBegin(GL_QUADS);
-	glTexCoord2f(-1.0, y);     glVertex3f(-0.75, 0.0, 0.0);
-	glTexCoord2f(-1.0, 1.0);   glVertex3f(-0.75, 0.5, 0.0);
-	glTexCoord2f( 1.0, 1.0);   glVertex3f( 0.75, 0.5, 0.0);
-	glTexCoord2f( 1.0, y);     glVertex3f( 0.75, 0.0, 0.0);
-	glEnd();
+	crazy_draw(texr) {
+		glBegin(GL_QUADS);
+		glTexCoord2f(-1.0, y);     glVertex3f(-0.75, 0.0, 0.0);
+		glTexCoord2f(-1.0, 1.0);   glVertex3f(-0.75, 0.5, 0.0);
+		glTexCoord2f( 1.0, 1.0);   glVertex3f( 0.75, 0.5, 0.0);
+		glTexCoord2f( 1.0, y);     glVertex3f( 0.75, 0.0, 0.0);
+		glEnd();
+	}
 
 	/* Bottom */
-	glBlendFunc(GL_ONE, GL_ZERO);
 	glBindTexture(GL_TEXTURE_2D, tex);
 	glBegin(GL_QUADS);
 	glTexCoord2f( 0.0, 0.0);   glVertex3f(-0.75, -0.5, 0.0);
@@ -132,8 +143,8 @@ guint load_tex(gchar *filename)
 	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
 	g_object_unref(pixbuf);
 	return tex;
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]