// jogl conversion of the redbook convolution example. works in jogl 1.1. // modified jplewis jul06 blindly adapting to new jogl jsr231, // 1) using direct nio arrays rather than simple float arrays for // glConvolution2D, also use direct byte array for drawpixels. // 2) glDrawable -> glAutoDrawable // 3) way of obtaining canvas has changed. // seems to work. // It uses a non-standard image file looding library, you will need // to replace this. See "replace" comments /* * Copyright (c) 1993-2003, Silicon Graphics, Inc. * All Rights Reserved * * Permission to use, copy, modify, and distribute this software for any * purpose and without fee is hereby granted, provided that the above * copyright notice appear in all copies and that both the copyright * notice and this permission notice appear in supporting documentation, * and that the name of Silicon Graphics, Inc. not be used in * advertising or publicity pertaining to distribution of the software * without specific, written prior permission. * * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE * OR PERFORMANCE OF THIS SOFTWARE. * * US Government Users Restricted Rights * Use, duplication, or disclosure by the Government is subject to * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph * (c)(1)(ii) of the Rights in Technical Data and Computer Software * clause at DFARS 252.227-7013 and/or in similar or successor clauses * in the FAR or the DOD or NASA FAR Supplement. Unpublished - rights * reserved under the copyright laws of the United States. * * Contractor/manufacturer is: * Silicon Graphics, Inc. * 1500 Crittenden Lane * Mountain View, CA 94043 * United State of America * * OpenGL(R) is a registered trademark of Silicon Graphics, Inc. */ /* * convolution.c * Use various 2D convolutions filters to find edges in an image. * */ import java.awt.*; import java.awt.event.*; import java.nio.*; //import net.java.games.jogl.*; //import net.java.games.jogl.util.*; import javax.media.opengl.*; import com.sun.opengl.util.*; import GR.*; // custom image class, replace public class JoglConvolution { static GLCanvas canvas; static ByteBuffer pixels; static int width, height; static final int CONV_NONE = 100; static final int CONV_HORIZONTAL = 101; static final int CONV_VERTICAL = 102; static final int CONV_LAPLACE = 103; static int convType = CONV_NONE; static float[] horizontalarr = new float[] { 0.f, -1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f }; static float[] verticalarr = new float[] { 0.f, 0.f, 0.f, -1.f, 1.f, 0.f, 0.f, 0.f, 0.f }; static float[] laplacianarr = new float[] { -0.125f, -0.125f, -0.125f, -0.125f, 1.f , -0.125f, -0.125f, -0.125f, -0.125f }; // zilla 06 static ByteBuffer bbhorizontal = ByteBuffer.allocateDirect(9*4); static ByteBuffer bbvertical = ByteBuffer.allocateDirect(9*4); static ByteBuffer bblaplacian = ByteBuffer.allocateDirect(9*4); static { // needed! otherwise result is black! bbhorizontal.order(ByteOrder.nativeOrder()); bbvertical.order(ByteOrder.nativeOrder()); bblaplacian.order(ByteOrder.nativeOrder()); } static FloatBuffer horizontal = bbhorizontal.asFloatBuffer(); static FloatBuffer vertical = bbvertical.asFloatBuffer(); static FloatBuffer laplacian = bblaplacian.asFloatBuffer(); static { horizontal.put(horizontalarr); horizontal.rewind(); vertical.put(verticalarr); vertical.rewind(); laplacian.put(laplacianarr); laplacian.rewind(); } public static void main(String[] args) { gr[] pic = grUtil.load(args[0]); // replace byte[] pixels1 = tobyte3(pic); pixels = ByteBuffer.allocateDirect(pixels1.length); pixels.put(pixels1); pixels.rewind(); Frame frame = new Frame("convolution"); //frame.setUndecorated(true); // this was in 2005 version: //canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); canvas = new GLCanvas(new GLCapabilities()); canvas.addGLEventListener(new Renderer()); frame.add(canvas); frame.setSize(width, height); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { // calling System.exit() synchronously inside the draw, // reshape or init callbacks can lead to deadlocks on certain // platforms (in particular, X11) because the JAWT's locking // routines cause a global AWT lock to be grabbed. Run the // exit routine in another thread. new Thread(new Runnable() { public void run() { //animator.stop(); System.exit(0); } }).start(); }}); frame.setVisible(true); canvas.requestFocus(); } //main static class Renderer implements GLEventListener, KeyListener { public void init(GLAutoDrawable gLDrawable) // 2006 GLDrawable -> GLAuto.. { final GL gl = gLDrawable.getGL(); gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 1); gl.glClearColor(0.f, 0.f, 0.f, 1.f); // System.out.println("Using the horizontal filter"); gl.glConvolutionFilter2D(gl.GL_CONVOLUTION_2D, gl.GL_LUMINANCE, 3, 3, gl.GL_LUMINANCE, gl.GL_FLOAT, horizontal); gl.glEnable(gl.GL_CONVOLUTION_2D); gLDrawable.addKeyListener(this); } // 2005 version //public void display(GLDrawable gLDrawable) public void display(GLAutoDrawable gLDrawable) { final GL gl = gLDrawable.getGL(); switch(convType) { case CONV_NONE: gl.glDisable(gl.GL_CONVOLUTION_2D); break; case CONV_HORIZONTAL: gl.glEnable(gl.GL_CONVOLUTION_2D); horizontal.rewind(); gl.glConvolutionFilter2D(gl.GL_CONVOLUTION_2D, gl.GL_LUMINANCE, 3, 3, gl.GL_LUMINANCE, gl.GL_FLOAT, horizontal); break; case CONV_VERTICAL: gl.glEnable(gl.GL_CONVOLUTION_2D); vertical.rewind(); gl.glConvolutionFilter2D(gl.GL_CONVOLUTION_2D, gl.GL_LUMINANCE, 3, 3, gl.GL_LUMINANCE, gl.GL_FLOAT, vertical); break; case CONV_LAPLACE: gl.glEnable(gl.GL_CONVOLUTION_2D); laplacian.rewind(); gl.glConvolutionFilter2D(gl.GL_CONVOLUTION_2D, gl.GL_LUMINANCE, 3, 3, gl.GL_LUMINANCE, gl.GL_FLOAT, laplacian); break; } gl.glClear(gl.GL_COLOR_BUFFER_BIT); gl.glRasterPos2i( 0, 0); // original example was 1,1 but think 0,0 is correct pixels.rewind(); gl.glDrawPixels(width, height, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, pixels); gl.glFlush(); } public void displayChanged(GLAutoDrawable gLDrawable, boolean modeChanged, boolean deviceChanged) { } // this was in 2005 version //public void displayChanged(GLDrawable gLDrawable, boolean modeChanged, boolean deviceChanged) //{ //} // 2005 version //public void reshape(GLDrawable gLDrawable, int x, int y, int w, int h) public void reshape(GLAutoDrawable gLDrawable, int x, int y, int w, int h) { final GL gl = gLDrawable.getGL(); gl.glViewport(0, 0, w, h); gl.glMatrixMode(gl.GL_PROJECTION); gl.glLoadIdentity(); gl.glOrtho(0, w, 0, h, -1.0, 1.0); gl.glMatrixMode(gl.GL_MODELVIEW); } public void keyPressed(KeyEvent e) { System.out.println("keyPressed "+e); if (e.getKeyCode() == KeyEvent.VK_ESCAPE) System.exit(0); switch (e.getKeyCode()) { case KeyEvent.VK_H : System.out.println("Using a horizontal filter"); // signal convolution setup to happen in display() thread not here convType = CONV_HORIZONTAL; break; case KeyEvent.VK_V: System.out.println("Using the vertical filter"); convType = CONV_VERTICAL; break; case KeyEvent.VK_L: System.out.println("Using the laplacian filter"); convType = CONV_LAPLACE; break; case KeyEvent.VK_N: System.out.println("no convolution"); convType = CONV_NONE; break; } //switch //gl.glutPostRedisplay(); canvas.display(); } //keyPressed public void keyReleased(KeyEvent e) {} public void keyTyped(KeyEvent e) {} } //Renderer // replace this with your own image loader static byte[] tobyte3(gr[] pic) { width = pic[0].xres(); height = pic[0].yres(); System.out.println("res = "+width+","+height); byte[] pixels = new byte[3*width*height]; int off = 0; for( int iyy=0; iyy < height; iyy++ ) { int iy = (height-1) - iyy; for( int ix=0; ix < width; ix++ ) { int v = pic[0].rd(ix,iy); v = (int)((255.f / gr.DTMAX) * v); if (v > 127) v = v - 256; pixels[off++] = (byte)v; v = pic[1].rd(ix,iy); v = (int)((255.f / gr.DTMAX) * v); if (v > 127) v = v - 256; pixels[off++] = (byte)v; v = pic[2].rd(ix,iy); v = (int)((255.f / gr.DTMAX) * v); if (v > 127) v = v - 256; pixels[off++] = (byte)v; } } //iy return pixels; } //tobyte3 } //JoglConvolution