!7 // seems to run only when cd'ing to program dir first lib 1400432 // jogl-all lib 1400430 // jogl-win64 lib 1400433 // jogl gluegen lib 1400434 // gluegen-rt-natives-windows-amd64 !include once #1029753 // JOGL framework.Semantic import com.jogamp.newt.event.*; import com.jogamp.newt.event.KeyEvent; import com.jogamp.newt.event.KeyListener; import com.jogamp.newt.event.WindowAdapter; import com.jogamp.newt.event.WindowEvent; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opengl.*; import com.jogamp.opengl.math.FloatUtil; import com.jogamp.opengl.util.Animator; import com.jogamp.opengl.util.GLBuffers; import com.jogamp.opengl.util.glsl.ShaderCode; import com.jogamp.opengl.util.glsl.ShaderProgram; import java.nio.ByteBuffer; import java.nio.FloatBuffer; replace IntBuffer with java.nio.IntBuffer. import java.nio.ShortBuffer; import static com.jogamp.opengl.GL.*; replace GL_FLOAT with com.jogamp.opengl.GL.GL_FLOAT. replace GL_TRIANGLES with com.jogamp.opengl.GL.GL_TRIANGLES. replace GL_UNSIGNED_SHORT with com.jogamp.opengl.GL.GL_UNSIGNED_SHORT. replace GL_DEBUG_SEVERITY_HIGH with com.jogamp.opengl.GL2ES2.GL_DEBUG_SEVERITY_HIGH. replace GL_DEBUG_SEVERITY_MEDIUM with com.jogamp.opengl.GL2ES2.GL_DEBUG_SEVERITY_MEDIUM. import static com.jogamp.opengl.GL2ES3.*; replace GL_UNIFORM_BUFFER with com.jogamp.opengl.GL2ES3.GL_UNIFORM_BUFFER. replace GL_MAP_COHERENT_BIT with com.jogamp.opengl.GL4.GL_MAP_COHERENT_BIT. replace GL_MAP_PERSISTENT_BIT with com.jogamp.opengl.GL4.GL_MAP_PERSISTENT_BIT. /** * Created by GBarbieri on 16.03.2017. */ p/*-exp*/ { fixContextClassLoader(); if (isWindows()) { extractResourceWithPath("natives/windows-amd64/gluegen-rt.dll", programDir()); extractResourceWithPath("natives/windows-amd64/nativewindow_awt.dll", programDir()); extractResourceWithPath("natives/windows-amd64/nativewindow_win32.dll", programDir()); //loadNativeLibrary(); addToNativeLibraryPath(programDir()); } new HelloTriangleSimple().setup(); } sclass HelloTriangleSimple implements GLEventListener, KeyListener { private static GLWindow window; private static Animator animator; private float[] vertexData = { -1, -1, 1, 0, 0, +0, +2, 0, 0, 1, +1, -1, 0, 1, 0}; private short[] elementData = {0, 2, 1}; private interface Buffer { int VERTEX = 0; int ELEMENT = 1; int GLOBAL_MATRICES = 2; int MODEL_MATRIX = 3; int MAX = 4; } private IntBuffer bufferName = GLBuffers.newDirectIntBuffer(Buffer.MAX); private IntBuffer vertexArrayName = GLBuffers.newDirectIntBuffer(1); private FloatBuffer clearColor = GLBuffers.newDirectFloatBuffer(4); private FloatBuffer clearDepth = GLBuffers.newDirectFloatBuffer(1); private FloatBuffer matBuffer = GLBuffers.newDirectFloatBuffer(16); private ByteBuffer globalMatricesPointer, modelMatrixPointer; // https://jogamp.org/bugzilla/show_bug.cgi?id=1287 private boolean bug1287 = true; private Program program; private long start; private void setup() { GLProfile glProfile = GLProfile.get(GLProfile.GL3); GLCapabilities glCapabilities = new GLCapabilities(glProfile); window = GLWindow.create(glCapabilities); window.setTitle("Hello Triangle (enhanced)"); window.setSize(1024, 768); window.setContextCreationFlags(GLContext.CTX_OPTION_DEBUG); window.setVisible(true); window.addGLEventListener(this); window.addKeyListener(this); animator = new Animator(window); animator.start(); window.addWindowListener(new WindowAdapter() { @Override public void windowDestroyed(WindowEvent e) { animator.stop(); System.exit(1); } }); } @Override public void init(GLAutoDrawable drawable) { GL4 gl = drawable.getGL().getGL4(); initDebug(gl); initBuffers(gl); initVertexArray(gl); program = new Program(gl, "shaders/gl4", "hello-triangle", "hello-triangle"); gl.glEnable(GL_DEPTH_TEST); start = System.currentTimeMillis(); } private void initDebug(GL4 gl) { window.getContext().addGLDebugListener(new GLDebugListener() { @Override public void messageSent(GLDebugMessage event) { System.out.println(event); } }); gl.glDebugMessageControl( GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, null, false); gl.glDebugMessageControl( GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0, null, true); gl.glDebugMessageControl( GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM, 0, null, true); } private void initBuffers(GL4 gl) { FloatBuffer vertexBuffer = GLBuffers.newDirectFloatBuffer(vertexData); ShortBuffer elementBuffer = GLBuffers.newDirectShortBuffer(elementData); gl.glCreateBuffers(Buffer.MAX, bufferName); if (!bug1287) { gl.glNamedBufferStorage(bufferName.get(Buffer.VERTEX), vertexBuffer.capacity() * Float.BYTES, vertexBuffer, GL_STATIC_DRAW); gl.glNamedBufferStorage(bufferName.get(Buffer.ELEMENT), elementBuffer.capacity() * Short.BYTES, elementBuffer, GL_STATIC_DRAW); gl.glNamedBufferStorage(bufferName.get(Buffer.GLOBAL_MATRICES), 16 * 4 * 2, null, GL_MAP_WRITE_BIT); gl.glNamedBufferStorage(bufferName.get(Buffer.MODEL_MATRIX), 16 * 4, null, GL_MAP_WRITE_BIT); } else { gl.glBindBuffer(GL_ARRAY_BUFFER, bufferName.get(Buffer.VERTEX)); gl.glBufferStorage(GL_ARRAY_BUFFER, vertexBuffer.capacity() * Float.BYTES, vertexBuffer, 0); gl.glBindBuffer(GL_ARRAY_BUFFER, 0); gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferName.get(Buffer.ELEMENT)); gl.glBufferStorage(GL_ELEMENT_ARRAY_BUFFER, elementBuffer.capacity() * Short.BYTES, elementBuffer, 0); gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); IntBuffer uniformBufferOffset = GLBuffers.newDirectIntBuffer(1); gl.glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, uniformBufferOffset); int globalBlockSize = Math.max(16 * 4 * 2, uniformBufferOffset.get(0)); int modelBlockSize = Math.max(16 * 4, uniformBufferOffset.get(0)); gl.glBindBuffer(GL_UNIFORM_BUFFER, bufferName.get(Buffer.GLOBAL_MATRICES)); gl.glBufferStorage(GL_UNIFORM_BUFFER, globalBlockSize, null, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); gl.glBindBuffer(GL_UNIFORM_BUFFER, 0); gl.glBindBuffer(GL_UNIFORM_BUFFER, bufferName.get(Buffer.MODEL_MATRIX)); gl.glBufferStorage(GL_UNIFORM_BUFFER, modelBlockSize, null, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); gl.glBindBuffer(GL_UNIFORM_BUFFER, 0); } // map the transform buffers and keep them mapped globalMatricesPointer = gl.glMapNamedBufferRange( bufferName.get(Buffer.GLOBAL_MATRICES), 0, 16 * 4 * 2, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); // flags modelMatrixPointer = gl.glMapNamedBufferRange( bufferName.get(Buffer.MODEL_MATRIX), 0, 16 * 4, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); } private void initVertexArray(GL4 gl) { gl.glCreateVertexArrays(1, vertexArrayName); gl.glVertexArrayAttribBinding(vertexArrayName.get(0), Semantic.Attr.POSITION, Semantic.Stream.A); gl.glVertexArrayAttribBinding(vertexArrayName.get(0), Semantic.Attr.COLOR, Semantic.Stream.A); gl.glVertexArrayAttribFormat(vertexArrayName.get(0), Semantic.Attr.POSITION, 2, GL_FLOAT, false, 0); gl.glVertexArrayAttribFormat(vertexArrayName.get(0), Semantic.Attr.COLOR, 3, GL_FLOAT, false, 2 * 4); gl.glEnableVertexArrayAttrib(vertexArrayName.get(0), Semantic.Attr.POSITION); gl.glEnableVertexArrayAttrib(vertexArrayName.get(0), Semantic.Attr.COLOR); gl.glVertexArrayElementBuffer(vertexArrayName.get(0), bufferName.get(Buffer.ELEMENT)); gl.glVertexArrayVertexBuffer(vertexArrayName.get(0), Semantic.Stream.A, bufferName.get(Buffer.VERTEX), 0, (2 + 3) * 4); } @Override public void display(GLAutoDrawable drawable) { GL4 gl = drawable.getGL().getGL4(); // view matrix { float[] view = FloatUtil.makeIdentity(new float[16]); for (int i = 0; i < 16; i++) globalMatricesPointer.putFloat(16 * 4 + i * 4, view[i]); } gl.glClearBufferfv(GL_COLOR, 0, clearColor.put(0, 1f).put(1, .5f).put(2, 0f).put(3, 1f)); gl.glClearBufferfv(GL_DEPTH, 0, clearDepth.put(0, 1f)); // model matrix { long now = System.currentTimeMillis(); float diff = (float) (now - start) / 1_000; float[] scale = FloatUtil.makeScale(new float[16], true, 0.5f, 0.5f, 0.5f); float[] rotateZ = FloatUtil.makeRotationAxis(new float[16], 0, diff, 0f, 0f, 1f, new float[3]); float[] model = FloatUtil.multMatrix(scale, rotateZ); modelMatrixPointer.asFloatBuffer().put(model); } gl.glUseProgram(program.name); gl.glBindVertexArray(vertexArrayName.get(0)); gl.glBindBufferBase( GL_UNIFORM_BUFFER, Semantic.Uniform.TRANSFORM0, bufferName.get(Buffer.GLOBAL_MATRICES)); gl.glBindBufferBase( GL_UNIFORM_BUFFER, Semantic.Uniform.TRANSFORM1, bufferName.get(Buffer.MODEL_MATRIX)); gl.glDrawElements( GL_TRIANGLES, elementData.length, GL_UNSIGNED_SHORT, 0); gl.glUseProgram(0); gl.glBindVertexArray(0); } @Override public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { GL4 gl = drawable.getGL().getGL4(); // ortho matrix float[] ortho = FloatUtil.makeOrtho(new float[16], 0, false, -1f, 1f, -1f, 1f, 1f, -1f); globalMatricesPointer.asFloatBuffer().put(ortho); gl.glViewport(x, y, width, height); } @Override public void dispose(GLAutoDrawable drawable) { GL4 gl = drawable.getGL().getGL4(); gl.glUnmapNamedBuffer(bufferName.get(Buffer.GLOBAL_MATRICES)); gl.glUnmapNamedBuffer(bufferName.get(Buffer.MODEL_MATRIX)); gl.glDeleteProgram(program.name); gl.glDeleteVertexArrays(1, vertexArrayName); gl.glDeleteBuffers(Buffer.MAX, bufferName); } @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { new Thread(() -> { window.destroy(); }).start(); } } @Override public void keyReleased(KeyEvent e) { } private class Program { public int name = 0; public Program(GL4 gl, String root, String vertex, String fragment) { ShaderCode vertShader = ShaderCode.create(gl, GL_VERTEX_SHADER, this.getClass(), root, null, vertex, "vert", null, true); ShaderCode fragShader = ShaderCode.create(gl, GL_FRAGMENT_SHADER, this.getClass(), root, null, fragment, "frag", null, true); ShaderProgram shaderProgram = new ShaderProgram(); shaderProgram.add(vertShader); shaderProgram.add(fragShader); shaderProgram.init(gl); name = shaderProgram.program(); shaderProgram.link(gl, System.err); } } private class GlDebugOutput implements GLDebugListener { private int source = 0; private int type = 0; private int id = 0; private int severity = 0; private int length = 0; private String message = null; private boolean received = false; public GlDebugOutput() { } public GlDebugOutput(int source, int type, int severity) { this.source = source; this.type = type; this.severity = severity; this.message = null; this.id = -1; } public GlDebugOutput(String message, int id) { this.source = -1; this.type = -1; this.severity = -1; this.message = message; this.id = id; } @Override public void messageSent(GLDebugMessage event) { if (event.getDbgSeverity() == GL_DEBUG_SEVERITY_LOW || event.getDbgSeverity() == GL_DEBUG_SEVERITY_NOTIFICATION) System.out.println("GlDebugOutput.messageSent(): " + event); else System.err.println("GlDebugOutput.messageSent(): " + event); if (null != message && message == event.getDbgMsg() && id == event.getDbgId()) received = true; else if (0 <= source && source == event.getDbgSource() && type == event.getDbgType() && severity == event.getDbgSeverity()) received = true; } } }