/* JOGL - JOCL in Java. Demo by fifty. */ import com.jogamp.opencl.CLCommandQueue; import com.jogamp.opencl.CLDevice; import com.jogamp.opencl.gl.*; import com.jogamp.opencl.*; import com.jogamp.opencl.CLKernel; import com.jogamp.opencl.CLPlatform; import com.jogamp.opencl.CLProgram; import com.jogamp.opengl.util.Animator; import java.io.IOException; import javax.media.opengl.DebugGL3; import javax.media.opengl.GL2; import javax.media.opengl.GL3; import javax.media.opengl.GLAutoDrawable; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLEventListener; import javax.media.opengl.GLProfile; import javax.media.opengl.awt.GLCanvas; import javax.swing.JFrame; import javax.swing.SwingUtilities; import java.util.Scanner; import java.nio.*; import java.awt.image.*; import java.io.*; /** OpenGL texture generated by JOCL */ public class DemoViewer implements GLEventListener { private int bufferWidth = 512; // texture size private int bufferHeight = 512; private boolean GL_INTEROP = false; // switch for CL-GL transfers private float[] identity_matrix = new float[]{ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; private float[] projection_matrix = new float[]{ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; private float[] quadTexcoords = new float[]{ 0.0f, 1.0f, // note the t-coord in (s,t) is mirrored! 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f }; private float[] quadCoords = new float[]{ 0.0f, 0.0f, bufferWidth, 0.0f, bufferWidth, bufferHeight, 0.0f, bufferHeight }; private JFrame frame; private int texId; private int programId; private int vbo; private CLDevice device; private CLPlatform platform; private CLGLContext clContext2; // only used if GL_INTEROP==true private CLContext clContext; // always used; (clContext2 == clContext) iff GL_INTEROP==true private CLKernel kernel; private CLCommandQueue commandQueue; // only one is used: texBuffer (iff GL_INTEROP==false), or texBuffer2 (iff GL_INTEROP==true) private CLGLTexture2d texBuffer2; private CLImage2d texBuffer; //private CLBuffer texBuffer; private long prevTimeNS = 0; /** */ public DemoViewer () { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { initUI(); } }); } /** */ private void initUI() { GLCapabilities config = new GLCapabilities(GLProfile.get(GLProfile.GL3)); //config.setSampleBuffers(true); //config.setNumSamples(4); GLCanvas canvas = new GLCanvas(config); canvas.addGLEventListener(this); frame = new JFrame("DemoViewer"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add (canvas); frame.setSize (bufferWidth, bufferHeight); frame.setVisible(true); } /** */ @Override public void init (GLAutoDrawable drawable) { if (clContext == null) { CLPlatform[] platforms = CLPlatform.listCLPlatforms(); platform = CLPlatform.getDefault(); //platforms[0]; Intel platform on my computer CLDevice[] devices = platform.listCLDevices(); device = platform.getMaxFlopsDevice(CLDevice.Type.GPU); // default device used; switched inside the NVidia driver (if you have both) //devices[1]; Intel HD4600 on my computer if (platform == null || device == null) { throw new RuntimeException("couldn't find any CL device"); } System.out.println(platform.getName() + " platform: " + device.getName()); if (GL_INTEROP) { // create OpenCL context before creating any OpenGL objects clContext2 = CLGLContext.create(drawable.getContext(), device); clContext = clContext2; } else { clContext = CLContext .create(device); } // enable GL error checking using the composable pipeline drawable.setGL(new DebugGL3(drawable.getGL().getGL3())); // OpenGL initialization GL3 gl = drawable.getGL().getGL3(); gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl.glClearDepth(1.0f); gl.glDisable (GL2.GL_DEPTH_TEST); gl.glPixelStorei(GL2.GL_UNPACK_ALIGNMENT, 1); initShader (drawable); gl.glUseProgram(programId); System.out.println(String.format("%d/%d/%d", getLocation(gl, "M"), getLocation(gl, "P"), getLocation(gl, "tex"))); // generate data buffers for texcoords and coords int idArray[] = new int[2]; gl.glGenBuffers(2, IntBuffer.wrap(idArray)); // Create the vertex array object int vboArray[] = new int[1]; gl.glGenVertexArrays(1, IntBuffer.wrap(vboArray)); vbo = vboArray[0]; gl.glBindVertexArray(vbo); gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, idArray[0]); ByteBuffer texData = clone(quadTexcoords); gl.glBufferData(GL2.GL_ARRAY_BUFFER, quadTexcoords.length*4, texData, GL2.GL_STATIC_DRAW); gl.glVertexAttribPointer (getAttribLocation(gl, "texcoord"), 2, GL2.GL_FLOAT, false, 0, 0); gl.glEnableVertexAttribArray(getAttribLocation(gl, "texcoord")); gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, idArray[1]); ByteBuffer coordData = clone(quadCoords); System.out.println(String.format("%d/%d, %d/%d", getAttribLocation(gl, "vertex"), coordData.capacity(), getAttribLocation(gl, "texcoord"), texData.capacity())); gl.glBufferData(GL2.GL_ARRAY_BUFFER, quadCoords.length*4, coordData, GL2.GL_STATIC_DRAW); gl.glVertexAttribPointer (getAttribLocation(gl, "vertex"), 2, GL2.GL_FLOAT, false, 0, 0); gl.glEnableVertexAttribArray(getAttribLocation(gl, "vertex")); gl.glBindVertexArray(0); int[] texArray = new int[1]; // Create the texture object gl.glGenTextures(1, texArray, 0); texId = texArray[0]; gl.glActiveTexture(GL2.GL_TEXTURE0); gl.glBindTexture (GL2.GL_TEXTURE_2D, texId); gl.glUniform1i (getLocation(gl, "tex"), 0); // texture filter gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_LINEAR); gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_LINEAR); // texture wrap mode gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP_TO_EDGE); gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP_TO_EDGE); // set image size only gl.glTexImage2D (GL2.GL_TEXTURE_2D, 0, GL2.GL_RGBA, bufferWidth, bufferHeight, 0, GL2.GL_RGBA, GL2.GL_UNSIGNED_BYTE, null); gl.glBindTexture (GL2.GL_TEXTURE_2D, 0); // initialize OpenCL, creating a context for the given GL object initCL(gl); // start rendering thread Animator animator = new Animator(drawable); animator.start(); } } /** float-array to direct ByteBuffer. */ private ByteBuffer clone (float[] data) { int len = data.length; ByteBuffer direct = ByteBuffer.allocateDirect(len*4); direct.order(ByteOrder.nativeOrder()); // very important! for (int i=0; i 0) { ByteBuffer byteBuffer = ByteBuffer.allocate(infoLogLength); gl.glGetShaderInfoLog(obj, infoLogLength, infoLogLengthBuf, byteBuffer); for (byte b:byteBuffer.array()){ System.err.print((char)b); } } } /** */ private void printProgramInfoLog(GLAutoDrawable drawable, int obj) { GL3 gl = drawable.getGL().getGL3(); // get the OpenGL 3 graphics context IntBuffer infoLogLengthBuf = IntBuffer.allocate(1); int infoLogLength; gl.glGetProgramiv(obj, GL2.GL_INFO_LOG_LENGTH, infoLogLengthBuf); infoLogLength = infoLogLengthBuf.get(0); if (infoLogLength > 0) { ByteBuffer byteBuffer = ByteBuffer.allocate(infoLogLength); gl.glGetProgramInfoLog(obj, infoLogLength, infoLogLengthBuf, byteBuffer); for (byte b:byteBuffer.array()){ System.err.print((char)b); } } } /** */ private void initCL (GL3 gl) { // ensure pipeline is clean before doing cl work gl.glFinish(); String sourceCL = "__kernel void function (__write_only image2d_t store, unsigned w, unsigned h ) \n" + "{ \n" + " unsigned x = get_global_id(0); \n" + " float aspect = h/(float)w; \n" + " int2 ic; \n" + " ic.s0 = x; \n" + " uint4 color; \n" + " color.s012 = 0; \n" + " color.s3 = 255; \n" + " // clear image \n" + " for (uint y=0; y