This tip demonstrates the different blending functions available with the OpenGL imaging subset. This program demonstrates use of the glBlendEquation() call. The following keys change the selected blend equation function:

  • 'a' -> GL_FUNC_ADD
  • 's' -> GL_FUNC_SUBTRACT
  • 'r' -> GL_FUNC_REVERSE_SUBTRACT
  • 'm' -> GL_MIN 'x' -> GL_MAX

The example is ported from C examples in the OpenGL Programming Guide (known as the "red book").

-> Copyright and Permission Notice

 package glredbook12x;

/**
 * Demonstrate the different blending functions available with the OpenGL
 * imaging subset. This program demonstrates use of the glBlendEquation() call.
 * The following keys change the selected blend equation function: <br>
 * <ul>
 * <li>'a' -> GL_FUNC_ADD
 * <li>'s' -> GL_FUNC_SUBTRACT
 * <li>'r' -> GL_FUNC_REVERSE_SUBTRACT
 * <li>'m' -> GL_MIN 'x' -> GL_MAX
 * </ul>
 * 
 * @author Kiet Le (java port)
 */

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.*;
import javax.media.opengl.*;
import javax.media.opengl.glu.*;

public class blendeqn
  extends JFrame
    implements GLEventListener//
    , KeyListener
{
  private GLCapabilities caps;
  private GLCanvas canvas;
  private GLU glu;
  private KeyEvent key;

  public blendeqn()
  {
    super("blendeqn");
    //
    canvas = new GLCanvas();
    canvas.addGLEventListener(this);
    canvas.addKeyListener(this);
    add(canvas);
    
  }

  public void run()
  {
    setSize(512, 512);
    setLocationRelativeTo(null);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);
    canvas.requestFocusInWindow();
  }

  public static void main(String[] args)
  {
    new blendeqn().run();
  }

  public void init(GLAutoDrawable drawable)
  {
    GL gl = drawable.getGL();
    //
    gl.glClearColor(1.0f, 1.0f, 0.0f, 0.0f);

    gl.glBlendFunc(GL.GL_ONE, GL.GL_ONE);
    gl.glEnable(GL.GL_BLEND);
  }

  public void display(GLAutoDrawable drawable)
  {
    GL gl = drawable.getGL();
    //
    gl.glClear(GL.GL_COLOR_BUFFER_BIT);

    if (key != null)
    {
      switch (key.getKeyCode()) {
        case KeyEvent.VK_A:
          /*
           * Colors are added as: (1, 1, 0) + (0, 0, 1) = (1, 1, 1) which will
           * produce a white square on a yellow background.
           */
          gl.glBlendEquation(GL.GL_FUNC_ADD);
          break;

        case KeyEvent.VK_S:
          /*
           * Colors are subtracted as: (0, 0, 1) - (1, 1, 0) = (-1, -1, 1) which
           * is clamped to (0, 0, 1), producing a blue square on a yellow
           * background
           */
          gl.glBlendEquation(GL.GL_FUNC_SUBTRACT);
          break;

        case KeyEvent.VK_R:
          /*
           * Colors are subtracted as: (1, 1, 0) - (0, 0, 1) = (1, 1, -1) which
           * is clamed to (1, 1, 0). This produces yellow for both the square
           * and the background.
           */
          gl.glBlendEquation(GL.GL_FUNC_REVERSE_SUBTRACT);
          break;

        case KeyEvent.VK_M:

          /*
           * The minimum of each component is computed, as [min(1, 0), min(1,
           * 0), min(0, 1)] which equates to (0, 0, 0). This will produce a
           * black square on the yellow background.
           */
          gl.glBlendEquation(GL.GL_MIN);
          break;

        case KeyEvent.VK_X:
          /*
           * The minimum of each component is computed, as [max(1, 0), max(1,
           * 0), max(0, 1)] which equates to (1, 1, 1) This will produce a white
           * square on the yellow background.
           */
          gl.glBlendEquation(GL.GL_MAX);
          break;  
      }
      key = null;
    }
    gl.glColor3f(0.0f, 0.0f, 1.0f);
    gl.glRectf(-0.5f, -0.5f, 0.5f, 0.5f);

    gl.glFlush();

  }

  public void reshape(GLAutoDrawable drawable, //
      int x, int y, int w, int h)
  {
    GL gl = drawable.getGL();
    //
    double aspect = (double) w / (double) h;

    gl.glViewport(0, 0, w, h);
    gl.glMatrixMode(GL.GL_PROJECTION);
    gl.glLoadIdentity();
    if (aspect < 1.0)
    {
      aspect = 1.0 / aspect;
      gl.glOrtho(-aspect, aspect, -1.0, 1.0, -1.0, 1.0);
    }
    else gl.glOrtho(-1.0, 1.0, -aspect, aspect, -1.0, 1.0);
    gl.glMatrixMode(GL.GL_MODELVIEW);

  }

  public void displayChanged(GLAutoDrawable drawable, //
      boolean deviceChanged, boolean modeChanged)
  {
  }

  public void keyTyped(KeyEvent e)
  {
  }

  public void keyPressed(KeyEvent e)
  {
    this.key = e;
    switch (e.getKeyCode()) {
      case KeyEvent.VK_ESCAPE:
        System.exit(0);
        break;
    }
    canvas.display();
  }

  public void keyReleased(KeyEvent e)
  {
  }
}

Source: Kiet Le's The Red Book Examples using JOGL