diff options
author | Michael Bien <[email protected]> | 2010-04-12 22:27:03 +0200 |
---|---|---|
committer | Michael Bien <[email protected]> | 2010-04-12 22:27:03 +0200 |
commit | 2c85c416d85205ab98b33e1a0b0daab32d4d81ff (patch) | |
tree | 4187ba06dec81da46495a300bb4f914e931f0c58 /src/com/jogamp/opencl/demos/joglinterop | |
parent | b51f2e1c254cdd74c9e43904c62694f64e6ae7e6 (diff) |
changes due to package renaming in jocl.
Diffstat (limited to 'src/com/jogamp/opencl/demos/joglinterop')
3 files changed, 403 insertions, 0 deletions
diff --git a/src/com/jogamp/opencl/demos/joglinterop/GLCLInteroperabilityDemo.java b/src/com/jogamp/opencl/demos/joglinterop/GLCLInteroperabilityDemo.java new file mode 100644 index 0000000..24af1fe --- /dev/null +++ b/src/com/jogamp/opencl/demos/joglinterop/GLCLInteroperabilityDemo.java @@ -0,0 +1,277 @@ +package com.jogamp.opencl.demos.joglinterop; + +import com.jogamp.opencl.CLCommandQueue; +import com.jogamp.opencl.CLDevice; +import com.jogamp.opencl.gl.CLGLBuffer; +import com.jogamp.opencl.gl.CLGLContext; +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.DebugGL2; +import javax.media.opengl.GL2; +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.media.opengl.glu.gl2.GLUgl2; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +import static com.jogamp.common.nio.Buffers.*; + +/** + * JOCL - JOGL interoperability example. + * @author Michael Bien + */ +public class GLCLInteroperabilityDemo implements GLEventListener { + + private final GLUgl2 glu = new GLUgl2(); + + private final int MESH_SIZE = 256; + + private int width; + private int height; + +// private final FloatBuffer vb; +// private final IntBuffer ib; + + private final int[] glObjects = new int[2]; + private final int VERTICES = 0; +// private final int INDICES = 1; + + private final UserSceneInteraction usi; + + private CLGLContext clContext; + private CLKernel kernel; + private CLCommandQueue commandQueue; + private CLGLBuffer<?> clBuffer; + + private float step = 0; + + public GLCLInteroperabilityDemo() { + + this.usi = new UserSceneInteraction(); + + // create direct memory buffers +// vb = newFloatBuffer(MESH_SIZE * MESH_SIZE * 4); +// ib = newIntBuffer((MESH_SIZE - 1) * (MESH_SIZE - 1) * 2 * 3); +// +// // build indices +// // 0---3 +// // | \ | +// // 1---2 +// for (int h = 0; h < MESH_SIZE - 1; h++) { +// for (int w = 0; w < MESH_SIZE - 1; w++) { +// +// // 0 - 3 - 2 +// ib.put(w * 6 + h * (MESH_SIZE - 1) * 6, w + (h ) * (MESH_SIZE) ); +// ib.put(w * 6 + h * (MESH_SIZE - 1) * 6 + 1, w + (h ) * (MESH_SIZE) + 1); +// ib.put(w * 6 + h * (MESH_SIZE - 1) * 6 + 2, w + (h + 1) * (MESH_SIZE) + 1); +// +// // 0 - 2 - 1 +// ib.put(w * 6 + h * (MESH_SIZE - 1) * 6 + 3, w + (h ) * (MESH_SIZE) ); +// ib.put(w * 6 + h * (MESH_SIZE - 1) * 6 + 4, w + (h + 1) * (MESH_SIZE) + 1); +// ib.put(w * 6 + h * (MESH_SIZE - 1) * 6 + 5, w + (h + 1) * (MESH_SIZE) ); +// +// } +// } +// ib.rewind(); + + SwingUtilities.invokeLater(new Runnable() { + public void run() { + initUI(); + } + }); + + } + + private void initUI() { + + this.width = 600; + this.height = 400; + + GLCapabilities config = new GLCapabilities(GLProfile.get(GLProfile.GL2)); + config.setSampleBuffers(true); + config.setNumSamples(4); + + GLCanvas canvas = new GLCanvas(config); + canvas.addGLEventListener(this); + usi.init(canvas); + + JFrame frame = new JFrame("JOGL-JOCL Interoperability Example"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.add(canvas); + frame.setSize(width, height); + + frame.setVisible(true); + + } + + + public void init(GLAutoDrawable drawable) { + + if(clContext == null) { + + // find gl compatible device + CLDevice[] devices = CLPlatform.getDefault().listCLDevices(); + CLDevice device = null; + for (CLDevice d : devices) { + if(d.isGLMemorySharingSupported()) { + device = d; + break; + } + } + // create OpenCL context before creating any OpenGL objects + // you want to share with OpenCL (AMD driver requirement) + clContext = CLGLContext.create(drawable.getContext(), device); + + // enable GL error checking using the composable pipeline + drawable.setGL(new DebugGL2(drawable.getGL().getGL2())); + + // OpenGL initialization + GL2 gl = drawable.getGL().getGL2(); + + gl.setSwapInterval(1); + + gl.glPolygonMode(GL2.GL_FRONT_AND_BACK, GL2.GL_LINE); + + gl.glGenBuffers(glObjects.length, glObjects, 0); + + // gl.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, glObjects[INDICES]); + // gl.glBufferData(GL2.GL_ELEMENT_ARRAY_BUFFER, ib.capacity() * SIZEOF_INT, ib, GL2.GL_STATIC_DRAW); + // gl.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, 0); + + gl.glEnableClientState(GL2.GL_VERTEX_ARRAY); + gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, glObjects[VERTICES]); + gl.glBufferData(GL2.GL_ARRAY_BUFFER, MESH_SIZE * MESH_SIZE * 4 * SIZEOF_FLOAT, null, GL2.GL_DYNAMIC_DRAW); + gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0); + gl.glDisableClientState(GL2.GL_VERTEX_ARRAY); + + pushPerspectiveView(gl); + gl.glFinish(); + + // init OpenCL + initCL(); + + // start rendering thread + Animator animator = new Animator(drawable); + animator.start(); + + } + } + + private void initCL() { + + CLProgram program; + try { + program = clContext.createProgram(getClass().getResourceAsStream("JoglInterop.cl")); + program.build(); + System.out.println(program.getBuildStatus()); + System.out.println(program.isExecutable()); + System.out.println(program.getBuildLog()); + } catch (IOException ex) { + throw new RuntimeException("can not handle exception", ex); + } + + commandQueue = clContext.getMaxFlopsDevice().createCommandQueue(); + + clBuffer = clContext.createFromGLBuffer(glObjects[VERTICES], CLGLBuffer.Mem.WRITE_ONLY); + + System.out.println("cl buffer type: " + clBuffer.getGLObjectType()); + System.out.println("shared with gl buffer: " + clBuffer.getGLObjectID()); + + kernel = program.createCLKernel("sineWave") + .putArg(clBuffer) + .putArg(MESH_SIZE) + .rewind(); + + System.out.println("cl initialised"); + } + + + public void display(GLAutoDrawable drawable) { + + GL2 gl = drawable.getGL().getGL2(); + + // ensure pipeline is clean before doing cl work + gl.glFinish(); + + computeHeightfield(); + + gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT); + gl.glLoadIdentity(); + + usi.interact(gl); + + gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, glObjects[VERTICES]); + gl.glVertexPointer(4, GL2.GL_FLOAT, 0, 0); + +// gl.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, glObjects[INDICES]); + + gl.glEnableClientState(GL2.GL_VERTEX_ARRAY); + gl.glDrawArrays(GL2.GL_POINTS, 0, MESH_SIZE * MESH_SIZE); +// gl.glDrawElements(GL2.GL_TRIANGLES, ib.capacity(), GL2.GL_UNSIGNED_INT, 0); + gl.glDisableClientState(GL2.GL_VERTEX_ARRAY); + +// gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0); + + } + + /* + * Computes a heightfield using a OpenCL kernel. + */ + private void computeHeightfield() { + + kernel.setArg(2, step += 0.05f); + + commandQueue.putAcquireGLObject(clBuffer.ID) + .put2DRangeKernel(kernel, 0, 0, MESH_SIZE, MESH_SIZE, 0, 0) + .putReleaseGLObject(clBuffer.ID) + .finish(); + + } + + private void pushPerspectiveView(GL2 gl) { + + gl.glMatrixMode(GL2.GL_PROJECTION); + gl.glPushMatrix(); + + gl.glLoadIdentity(); + + glu.gluPerspective(60, width / (float)height, 1, 1000); + gl.glMatrixMode(GL2.GL_MODELVIEW); + + gl.glPushMatrix(); + gl.glLoadIdentity(); + + } + + private void popView(GL2 gl) { + + gl.glMatrixMode(GL2.GL_PROJECTION); + gl.glPopMatrix(); + + gl.glMatrixMode(GL2.GL_MODELVIEW); + gl.glPopMatrix(); + + } + + + public void reshape(GLAutoDrawable drawable, int arg1, int arg2, int width, int height) { + this.width = width; + this.height = height; + GL2 gl = drawable.getGL().getGL2(); + popView(gl); + pushPerspectiveView(gl); + } + + public void dispose(GLAutoDrawable drawable) { } + + public static void main(String[] args) { + new GLCLInteroperabilityDemo(); + } + +}
\ No newline at end of file diff --git a/src/com/jogamp/opencl/demos/joglinterop/JoglInterop.cl b/src/com/jogamp/opencl/demos/joglinterop/JoglInterop.cl new file mode 100644 index 0000000..0f0bcfc --- /dev/null +++ b/src/com/jogamp/opencl/demos/joglinterop/JoglInterop.cl @@ -0,0 +1,23 @@ + +/** +* animated 2D sine pattern. +*/ +kernel void sineWave(global float4 * vertex, int size, float time) { + + unsigned int x = get_global_id(0); + unsigned int y = get_global_id(1); + + // calculate uv coordinates + float u = x / (float) size; + float v = y / (float) size; + + u = u*2.0f - 1.0f; + v = v*2.0f - 1.0f; + + // calculate simple sine wave pattern + float freq = 4.0f; + float w = sin(u*freq + time) * cos(v*freq + time) * 0.5f; + + // write output vertex + vertex[y*size + x] = (float4)(u*10.0f, w*10.0f, v*10.0f, 1.0f); +} diff --git a/src/com/jogamp/opencl/demos/joglinterop/UserSceneInteraction.java b/src/com/jogamp/opencl/demos/joglinterop/UserSceneInteraction.java new file mode 100644 index 0000000..fc0f054 --- /dev/null +++ b/src/com/jogamp/opencl/demos/joglinterop/UserSceneInteraction.java @@ -0,0 +1,103 @@ +package com.jogamp.opencl.demos.joglinterop; + +import java.awt.Component; +import java.awt.Point; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; +import javax.media.opengl.GL2; + +/** + * Utility class for interacting with a scene. Supports rotation and zoom around origin. + * @author Michael Bien + */ +public class UserSceneInteraction { + + private float z = -20; + private float rotx = 45; + private float roty = 30; + + private Point dragstart; + private enum MOUSE_MODE { DRAG_ROTATE, DRAG_ZOOM } + private MOUSE_MODE dragmode = MOUSE_MODE.DRAG_ROTATE; + + + public void init(Component component) { + initMouseListeners(component); + } + + private void initMouseListeners(Component component) { + component.addMouseMotionListener(new MouseMotionAdapter() { + + @Override + public void mouseDragged(MouseEvent e) { + + if (dragstart != null) { + switch (dragmode) { + case DRAG_ROTATE: + rotx += e.getY() - dragstart.getY(); + roty += e.getX() - dragstart.getX(); + break; + case DRAG_ZOOM: + z += (e.getY() - dragstart.getY()) / 5.0f; + break; + } + } + + dragstart = e.getPoint(); + } + }); + component.addMouseWheelListener(new MouseWheelListener() { + + public void mouseWheelMoved(MouseWheelEvent e) { + z += e.getWheelRotation()*5; + } + + }); + component.addMouseListener(new MouseAdapter() { + + @Override + public void mousePressed(MouseEvent e) { + switch (e.getButton()) { + case (MouseEvent.BUTTON1): + dragmode = MOUSE_MODE.DRAG_ROTATE; + break; + case (MouseEvent.BUTTON2): + dragmode = MOUSE_MODE.DRAG_ZOOM; + break; + case (MouseEvent.BUTTON3): + dragmode = MOUSE_MODE.DRAG_ZOOM; + break; + } + } + + @Override + public void mouseReleased(MouseEvent e) { + switch (e.getButton()) { + case (MouseEvent.BUTTON1): + dragmode = MOUSE_MODE.DRAG_ZOOM; + break; + case (MouseEvent.BUTTON2): + dragmode = MOUSE_MODE.DRAG_ROTATE; + break; + case (MouseEvent.BUTTON3): + dragmode = MOUSE_MODE.DRAG_ROTATE; + break; + } + + dragstart = null; + } + }); + } + + + public void interact(GL2 gl) { + gl.glTranslatef(0, 0, z); + gl.glRotatef(rotx, 1f, 0f, 0f); + gl.glRotatef(roty, 0f, 1.0f, 0f); + } + + +}
\ No newline at end of file |