// JOGL/GLSL convolution example, adapted from jglmark GLSL example code // by Chris Brown. // Loads image as a texture, renders quad using it, with blur shader attached. // Works. // You will need to rewrite the tobyte3() image loading code however. // // next, need to setup to render the face, copytotex it, // then read back the results (readimage). //package GL.JOGL; import com.sun.opengl.util.texture.Texture; import com.sun.opengl.util.texture.TextureCoords; import com.sun.opengl.util.texture.TextureIO; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import javax.media.opengl.GLAutoDrawable; import javax.media.opengl.GLEventListener; import javax.media.opengl.GL; import javax.media.opengl.GLException; import javax.media.opengl.glu.GLU; import java.nio.*; import GR.*; // replace with your own image loading code /* * SimpleGLSLListener.java * SimpleGLSLListener Component * Created on May 17, 2006, 8:46 AM */ /** * @author Chris "Crash0veride007" Brown * crash0veride007@gmail.com * https://jglmark.dev.java.net/ */ public class SimpleGLSLListener implements GLEventListener { ByteBuffer _pixels; int _width; int _height; boolean _dotex = true; boolean _useshader = true; private long startTime; private long fps = 0; private long timeUsed; //String shadername = "tryout"; String shadername = "convolve"; private String VERTEX_SHADER_SOURCE_FILE = shadername + ".vert"; private String FRAGMENT_SHADER_SOURCE_FILE = shadername + ".frag"; public int VERTEX_SHADER_ID; public int FRAGMENT_SHADER_ID; public int SHADER_PROGRAM_ID; public SimpleGLSLListener(String imagepath) { gr[] pic = grUtil.load(imagepath); // replace byte[] pixels1 = tobyte3(pic); _pixels = ByteBuffer.allocateDirect(pixels1.length); _pixels.put(pixels1); _pixels.rewind(); } public void initshaders(GL gl) { GLSLShaderUtil.CheckShaderExtensions(gl); VERTEX_SHADER_ID = GLSLShaderUtil.InitVertexShaderID(gl); GLSLShaderUtil.CompileVertexShader(gl, VERTEX_SHADER_ID, VERTEX_SHADER_SOURCE_FILE); FRAGMENT_SHADER_ID = GLSLShaderUtil.InitFragmentShaderID(gl); GLSLShaderUtil.CompileFragmentShader(gl, FRAGMENT_SHADER_ID, FRAGMENT_SHADER_SOURCE_FILE); SHADER_PROGRAM_ID = GLSLShaderUtil.InitShaderProgramID(gl); GLSLShaderUtil.LinkShaderProgram(gl, VERTEX_SHADER_ID, FRAGMENT_SHADER_ID, SHADER_PROGRAM_ID); if (_useshader) gl.glUseProgramObjectARB(SHADER_PROGRAM_ID); // try to assign the width/height. // note that the width, height variables must actually be used // in the shader for this to work. Also, have to do it after // using the shader. if (true) { int width_id = GLSLShaderUtil.AllocateUniform(gl, SHADER_PROGRAM_ID, "width"); int height_id = GLSLShaderUtil.AllocateUniform(gl, SHADER_PROGRAM_ID, "height"); gl.glUniform1f(width_id, (float)_width); gl.glUniform1f(height_id, (float)_height); } } //initshaders public void init(GLAutoDrawable drawable) { GL gl = drawable.getGL(); initshaders(gl); gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); gl.glClearDepth(1.0f); gl.glEnable(GL.GL_DEPTH_TEST); gl.glDepthFunc(GL.GL_LEQUAL); gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST); if (_dotex) { gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 1); // added for image gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, 3, _width, _height, 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, _pixels); gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP); gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP); gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST); gl.glTexEnvf(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_DECAL); gl.glEnable(GL.GL_TEXTURE_2D); gl.glShadeModel(GL.GL_FLAT); } gl.setSwapInterval(0); // VSYNC Setting 1=ON 0=OFF startTime = System.currentTimeMillis() + 5000; fps = 0; } public void display(GLAutoDrawable drawable) { GL gl = drawable.getGL(); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT ); gl.glPushMatrix(); //if (_useshader) gl.glUseProgramObjectARB(SHADER_PROGRAM_ID); expensive? if (_dotex) { // draw a quad gl.glBegin(GL.GL_QUADS); gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f(0f, 0f, 0f); gl.glTexCoord2f(1.f, 0.0f); gl.glVertex3f(1.f, 0.0f, 0.f); gl.glTexCoord2f(1.f, 1.f); gl.glVertex3f(1.f, 1.f, 0.f); gl.glTexCoord2f(0.0f, 1.f); gl.glVertex3f(0.0f, 1.f, 0.f); gl.glEnd(); } if (false) { // draw the image. // but this is not what we do for GLSL, need to // draw a textured polygon! // original example was 1,1 but think 0,0 is correct gl.glRasterPos2i( 0, 0); _pixels.rewind(); gl.glDrawPixels(_width, _height, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, _pixels); } //if (_useshader) gl.glUseProgramObjectARB(0); // expensive? gl.glPopMatrix(); if (startTime > System.currentTimeMillis()) { fps++; } else { timeUsed = 5000 + (startTime - System.currentTimeMillis()); startTime = System.currentTimeMillis() + 5000; System.out.println(fps + " frames in " + (float) (timeUsed / 1000f) + " seconds = "+ (fps / (timeUsed / 1000f))+" FPS"); fps = 0; } gl.glFlush(); } //display public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {} public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { final GL gl = drawable.getGL(); gl.glViewport(0, 0, width, height); gl.glMatrixMode(gl.GL_PROJECTION); gl.glLoadIdentity(); gl.glOrtho(0, 1., 0, 1., -1.0, 1.0); gl.glMatrixMode(gl.GL_MODELVIEW); } //---------------------------------------------------------------- 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 } //SimpleGLSLListener