package com.jogl.myproject; import java.nio.Buffer; import java.util.ArrayList; import java.util.List; 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 com.jogamp.common.nio.Buffers; import com.jogamp.newt.event.WindowAdapter; import com.jogamp.newt.event.WindowEvent; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opengl.util.FPSAnimator; public class JOGL2NewtOpenGL33 implements GLEventListener { private static String TITLE = "JOGL 2 with NEWT"; private static final int WINDOW_WIDTH = 640; private static final int WINDOW_HEIGHT = 480; private static final int FPS = 60; private int[] vaoId = new int[1]; private int[] vboId = new int[1]; private static final float[] VERTEX_POSITIONS = { 0.75f, 0.75f, 0.5f, 1.0f, 0.75f, -0.75f, 0.5f, 1.0f, -0.75f, -0.75f, 0.5f, 1.0f, }; private static Buffer VERTEX_BUFFER = Buffers.newDirectFloatBuffer( VERTEX_POSITIONS ); private static final String VERTEX_SHADER = "#version 330\n" + "layout(location = 0) in vec4 position; \n" + "void main() \n" + "{ \n" + "gl_Position = position; \n" + "}"; private static final String FRAGMENT_SHADER = "#version 330\n" + "out vec4 outputColor; \n" + "void main() \n" + "{ \n" + " outputColor = vec4( 1.0F, 1.0F, 1.0F, 1.0F ); \n" + "}"; private int theProgram; /** Constructor */ public JOGL2NewtOpenGL33() {} /** The entry main() method */ public static void main(String[] args) { GLProfile glp = GLProfile.get( GLProfile.GL3 ); GLCapabilities caps = new GLCapabilities(glp); GLWindow window = GLWindow.create(caps); final FPSAnimator animator = new FPSAnimator(window, FPS, true); window.addWindowListener(new WindowAdapter() { @Override public void windowDestroyNotify(WindowEvent arg0) { new Thread() { @Override public void run() { animator.stop(); System.exit(0); } }.start(); }; }); window.addGLEventListener(new JOGL2NewtOpenGL33()); window.setSize(WINDOW_WIDTH, WINDOW_HEIGHT); window.setTitle(TITLE); window.setVisible(true); animator.start(); } /** Called back by the drawable to render OpenGL graphics */ @Override public void display(GLAutoDrawable drawable) { render(drawable); } /** Render the shape (triangle) */ private void render(GLAutoDrawable drawable) { GL3 gl = drawable.getGL().getGL3(); gl.glClearColor( 0.0F, 0.0F, 0.0F, 0.0F ); gl.glClear( GL3.GL_COLOR_BUFFER_BIT ); gl.glUseProgram( theProgram ); gl.glBindBuffer( GL3.GL_ARRAY_BUFFER, 1 ); gl.glEnableVertexAttribArray( 0 ); gl.glVertexAttribPointer( 0, 4, GL3.GL_FLOAT, false, 0, 0 ); gl.glDrawArrays( GL3.GL_TRIANGLES, 0, 3 ); gl.glDisableVertexAttribArray( 0 ); gl.glUseProgram( 0 ); } /** Called back immediately after the OpenGL context is initialized */ @Override public void init(GLAutoDrawable drawable) { GL3 gl = drawable.getGL().getGL3(); initializeProgram( gl ); gl.glGenVertexArrays(1, vaoId, 0 ); gl.glBindVertexArray( vaoId[0] ); initializeVertexBuffer( gl ); } /** Called back before the OpenGL context is destroyed. */ @Override public void dispose(GLAutoDrawable drawable) { } /** Called back by the drawable when it is first set to visible, and during the first repaint after the it has been resized. */ @Override public void reshape(GLAutoDrawable drawable, int x, int y, int weight, int height) { } private void initializeVertexBuffer( GL3 gl ) { gl.glGenBuffers( 1, vboId, 0 ); gl.glBindBuffer( GL3.GL_ARRAY_BUFFER, vboId[0] ); gl.glBufferData( GL3.GL_ARRAY_BUFFER, VERTEX_POSITIONS.length, VERTEX_BUFFER, GL3.GL_STATIC_DRAW ); gl.glBindBuffer( GL3.GL_ARRAY_BUFFER, 0 ); } private void initializeProgram( GL3 gl ) { List shaderList = new ArrayList<>(); shaderList.add( CreateShader( gl, GL3.GL_VERTEX_SHADER, VERTEX_SHADER ) ); shaderList.add( CreateShader( gl, GL3.GL_FRAGMENT_SHADER, FRAGMENT_SHADER ) ); theProgram = CreateProgram( gl, shaderList ); for ( Integer shader : shaderList ) { gl.glDeleteShader( shader ); } } private Integer CreateShader( GL3 gl, int shaderType, String shaderFile ) { int shader = gl.glCreateShader( shaderType ); gl.glShaderSource( shader, 1, new String[] { shaderFile }, (int[]) null, 0 ); gl.glCompileShader( shader ); int[] status = new int[1]; gl.glGetShaderiv( shader, GL3.GL_COMPILE_STATUS, status, 0 ); if ( status[0] == GL3.GL_FALSE ) { int[] logLength = new int[1]; gl.glGetShaderiv( shader, GL3.GL_INFO_LOG_LENGTH, logLength, 0 ); byte[] log = new byte[logLength[0]]; gl.glGetShaderInfoLog( shader, logLength[0], (int[]) null, 0, log, 0 ); String shaderTypeName = null; switch ( shaderType ) { case GL3.GL_VERTEX_SHADER: shaderTypeName = "vertex"; break; case GL3.GL_GEOMETRY_SHADER: shaderTypeName = "geometry"; break; case GL3.GL_FRAGMENT_SHADER: shaderTypeName = "fragment"; break; default: shaderTypeName = "unknown"; break; } System.err.printf( "Compile failure in %s shader:\n%s\n", shaderTypeName, new String( log ) ); } return shader; } private int CreateProgram( GL3 gl, List shaderList ) { int program = gl.glCreateProgram(); for ( Integer shader : shaderList ) { gl.glAttachShader( program, shader ); } gl.glLinkProgram( program ); int[] status = new int[1]; gl.glGetProgramiv( program, GL3.GL_LINK_STATUS, status, 0 ); if ( status[0] == GL3.GL_FALSE ) { int[] logLength = new int[1]; gl.glGetProgramiv( program, GL3.GL_INFO_LOG_LENGTH, logLength, 0 ); byte[] log = new byte[logLength[0]]; gl.glGetProgramInfoLog( program, logLength[0], (int[]) null, 0, log, 0 ); System.err.printf( "Linker failure: %s\n", new String( log ) ); } for ( Integer shader : shaderList ) { gl.glDetachShader( program, shader ); } return program; } }