// This code example is created for educational purpose // by Thorsten Thormaehlen (contact: www.thormae.de). // It is distributed without any warranty. import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.ByteBuffer; import java.nio.FloatBuffer; import java.nio.IntBuffer; import com.jogamp.opengl.GL3; import com.jogamp.opengl.GLAutoDrawable; import com.jogamp.opengl.GLCapabilities; import com.jogamp.opengl.GLEventListener; import com.jogamp.opengl.GLProfile; import com.jogamp.opengl.awt.GLCanvas; import javax.swing.JFrame; import com.jogamp.common.nio.Buffers; import com.jogamp.opengl.util.FPSAnimator; class Renderer { public float t = 0.0f; public int modeVal = 1; public boolean loadNext = false; public boolean loadNextShader = false; private enum VAOs { Scene, numVAOs }; private enum VBOs { SceneAll, numVBOs }; private int[] vaoID = new int[VAOs.numVAOs.ordinal()]; private int[] bufID = new int[VBOs.numVBOs.ordinal()]; private int sceneVertNo = 0; private int progID = 0; private int vertID = 0; private int fragID = 0; private int vertexLoc = 0; private int texCoordLoc = 0; private int normalLoc = 0; private int projectionLoc = 0; private int modelviewLoc = 0; private int normalMatrixLoc = 0; private int modeLoc = 0; private int lightDirectionLoc = 0; private int camPosLoc = 0; private int lookAtLoc = 0; private int camProjectionLoc = 0; private int meshTransformLoc = 0; private int meshTransformTransposeInvLoc = 0; private float[] projection = new float[16]; private float[] modelview = new float[16]; private String filename = "./knot.vbo"; private String shaderFilename = "./PhongBrdfCameraSpace"; private int file = 0; private int shaderFile = 0; public void nextModel(GLAutoDrawable d) { loadNext = false; file++; if (file > 4) file = 0; if (file == 0) filename = "./knot.vbo"; if (file == 1) filename = "./teapot.vbo"; if (file == 2) filename = "./sphere.vbo"; if (file == 3) filename = "./hose.vbo"; if (file == 4) filename = "./cube.vbo"; deleteAll(d); init(d); } public void nextShaderExample(GLAutoDrawable d) { loadNextShader = false; shaderFile++; if (shaderFile > 4) shaderFile = 0; if (shaderFile == 0) shaderFilename = "./PhongBrdfCameraSpace"; if (shaderFile == 1) shaderFilename = "./PhongBrdfWorldSpace"; if (shaderFile == 2) shaderFilename = "./BlinnPhongBrdfCameraSpace"; if (shaderFile == 3) shaderFilename = "./BlinnPhongBrdfWorldSpace"; if (shaderFile == 4) shaderFilename = "./PhongBrdfPerVertex"; System.out.println("loading shader: " + shaderFilename); deleteAll(d); init(d); } public void init(GLAutoDrawable d) { GL3 gl = d.getGL().getGL3(); // get the OpenGL 3 graphics context gl.glEnable(GL3.GL_DEPTH_TEST); setupShaders(d); // create a Vertex Array Objects (VAO) gl.glGenVertexArrays(VAOs.numVAOs.ordinal(), vaoID, 0); // generate a Vertex Buffer Object (VBO) gl.glGenBuffers(VBOs.numVBOs.ordinal(), bufID, 0); // binding the Triangle VAO gl.glBindVertexArray(vaoID[VAOs.Scene.ordinal()]); int perVertexFloats = (3 + 2 + 3); float data[] = loadVertexData(filename, perVertexFloats); sceneVertNo = data.length / perVertexFloats; FloatBuffer sceneVertexFB = Buffers.newDirectFloatBuffer(data.length); sceneVertexFB.put(data); sceneVertexFB.flip(); gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, bufID[VBOs.SceneAll.ordinal()]); gl.glBufferData(GL3.GL_ARRAY_BUFFER, sceneVertexFB.capacity() * Buffers.SIZEOF_FLOAT, sceneVertexFB, GL3.GL_STATIC_DRAW); int stride = (3 + 2 + 3) * Buffers.SIZEOF_FLOAT; int offset = 0; // position if (vertexLoc != -1) { gl.glVertexAttribPointer(vertexLoc, 3, GL3.GL_FLOAT, false, stride, offset); gl.glEnableVertexAttribArray(vertexLoc); } // texCoord if (texCoordLoc != -1) { offset = 0 + 3 * Buffers.SIZEOF_FLOAT; gl.glVertexAttribPointer(texCoordLoc, 2, GL3.GL_FLOAT, false, stride, offset); gl.glEnableVertexAttribArray(texCoordLoc); } // normal if (normalLoc != -1) { offset = 0 + (3 + 2) * Buffers.SIZEOF_FLOAT; gl.glVertexAttribPointer(normalLoc, 3, GL3.GL_FLOAT, false, stride, offset); gl.glEnableVertexAttribArray(normalLoc); } System.out.println("Press 1-5 to switch mode, 9 to switch shader, 0 to switch 3D mesh"); } public void resize(GLAutoDrawable d, int w, int h) { GL3 gl = d.getGL().getGL3(); // get the OpenGL 3 graphics context gl.glViewport(0, 0, w, h); // this function replaces gluPerspective mat4Perspective(projection, 45.0f, (float) w / (float) h, 0.5f, 4.0f); // mat4Print(projection); } public void display(GLAutoDrawable d) { if (loadNext) nextModel(d); if (loadNextShader) nextShaderExample(d); GL3 gl = d.getGL().getGL3(); // get the OpenGL >= 3 graphics context gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); gl.glClear(GL3.GL_COLOR_BUFFER_BIT | GL3.GL_DEPTH_BUFFER_BIT); float lightDirection[] = { 0.0f, -1.0f, -1.0f, 0.0f}; float cameraPos[] = { 1.5f, 0.0f, 1.5f}; float lightDirectionTrans[] = new float[4]; float modelviewInv[] = new float[16]; float normalmatrix[] = new float[16]; float lookAt[] = new float[16]; float lookAtInv[] = new float[16]; float m[] = new float[16]; float meshTransform[] = new float[16]; float meshTransformInv[] = new float[16]; float meshTransformTransposeInv[] = new float[16]; // mat4LookAt replaces gluLookAt mat4LookAt(lookAt, cameraPos[0], cameraPos[1], cameraPos[2], // eye 0.0f, 0.0f, 0.0f, // look at 0.0f, 0.0f, 1.0f); // up // apply lookAt matrix to light direction mat4Invert(lookAt, lookAtInv); mat4Transpose(lookAtInv, m); applyMatrixToVec4(m, lightDirection, lightDirectionTrans); // rotate mesh rotateZ(meshTransform, -t); // compute meshTransformTransposeInv mat4Invert(meshTransform, meshTransformInv); mat4Transpose(meshTransformInv, meshTransformTransposeInv); // compute modelview and normalmatrix mat4Multiply(lookAt, meshTransform, modelview); mat4Invert(modelview, modelviewInv); mat4Transpose(modelviewInv, normalmatrix); gl.glUseProgram(progID); // load the current projection and modelview matrix into the // corresponding UNIFORM variables of the shader //gl.glUniformMatrix4fv(projectionLoc, 1, false, projection, 0); //gl.glUniformMatrix4fv(modelviewLoc, 1, false, modelview, 0); //gl.glUniformMatrix4fv(normalMatrixLoc, 1, false, normalmatrix, 0); //gl.glUniform1i(modeLoc, modeVal); // load the current projection and modelview matrix into the // corresponding UNIFORM variables of the shader if(projectionLoc != -1) gl.glUniformMatrix4fv(projectionLoc, 1, false, projection, 0); if(camProjectionLoc != -1) gl.glUniformMatrix4fv(camProjectionLoc, 1, false, projection, 0); if(modelviewLoc != -1) gl.glUniformMatrix4fv(modelviewLoc, 1, false, modelview, 0); if(normalMatrixLoc != -1) gl.glUniformMatrix4fv(normalMatrixLoc, 1, false, normalmatrix, 0); if(modeLoc != -1) gl.glUniform1i(modeLoc, modeVal); if(lightDirectionLoc != -1) gl.glUniform3fv(lightDirectionLoc, 1, lightDirectionTrans, 0); if(camPosLoc != -1) gl.glUniform3fv(camPosLoc, 1, cameraPos, 0); if(lookAtLoc != -1)gl. glUniformMatrix4fv(lookAtLoc, 1, false, lookAt, 0); if(meshTransformLoc != -1) gl.glUniformMatrix4fv(meshTransformLoc, 1, false, meshTransform, 0); if(meshTransformTransposeInvLoc != -1) gl.glUniformMatrix4fv(meshTransformTransposeInvLoc, 1, false, meshTransformTransposeInv, 0); // bind scene VAO gl.glBindVertexArray(vaoID[VAOs.Scene.ordinal()]); // render data gl.glDrawArrays(GL3.GL_TRIANGLES, 0, sceneVertNo); gl.glFlush(); } public void deleteAll(GLAutoDrawable d) { GL3 gl = d.getGL().getGL3(); // get the OpenGL 3 graphics context gl.glDeleteVertexArrays(VAOs.numVAOs.ordinal(), vaoID, 0); gl.glDeleteBuffers(VBOs.numVBOs.ordinal(), bufID, 0); gl.glDeleteProgram(progID); gl.glDeleteShader(vertID); gl.glDeleteShader(fragID); } private void setupShaders(GLAutoDrawable d) { GL3 gl = d.getGL().getGL3(); // get the OpenGL 3 graphics context vertID = gl.glCreateShader(GL3.GL_VERTEX_SHADER); fragID = gl.glCreateShader(GL3.GL_FRAGMENT_SHADER); String[] vs = loadShaderSrc(shaderFilename + ".vert"); String[] fs = loadShaderSrc(shaderFilename + ".frag"); gl.glShaderSource(vertID, 1, vs, null, 0); gl.glShaderSource(fragID, 1, fs, null, 0); // compile the shader gl.glCompileShader(vertID); gl.glCompileShader(fragID); // check for errors printShaderInfoLog(d, vertID); printShaderInfoLog(d, fragID); // create program and attach shaders progID = gl.glCreateProgram(); gl.glAttachShader(progID, vertID); gl.glAttachShader(progID, fragID); // "outColor" is a user-provided OUT variable // of the fragment shader. // Its output is bound to the first color buffer // in the framebuffer gl.glBindFragDataLocation(progID, 0, "outputColor"); // link the program gl.glLinkProgram(progID); // output error messages printProgramInfoLog(d, progID); // retrieve the location of the IN variables of the vertex shader vertexLoc = gl.glGetAttribLocation(progID, "position"); texCoordLoc = gl.glGetAttribLocation(progID, "texcoord"); normalLoc = gl.glGetAttribLocation(progID, "normal"); // retrieve the location of the UNIFORM variables of the vertex shader camProjectionLoc = gl.glGetUniformLocation(progID, "cameraProjection"); projectionLoc = gl.glGetUniformLocation(progID, "projection"); modelviewLoc = gl.glGetUniformLocation(progID, "modelview"); normalMatrixLoc = gl.glGetUniformLocation(progID, "normalMat"); modeLoc = gl.glGetUniformLocation(progID, "mode"); lightDirectionLoc = gl.glGetUniformLocation(progID, "lightDirection"); camPosLoc = gl.glGetUniformLocation(progID, "cameraPosition"); lookAtLoc = gl.glGetUniformLocation(progID, "cameraLookAt"); meshTransformLoc = gl.glGetUniformLocation(progID, "meshTransform"); meshTransformTransposeInvLoc = gl.glGetUniformLocation(progID, "meshTransformTransposedInverse"); } private String[] loadShaderSrc(String name) { StringBuilder sb = new StringBuilder(); try { InputStream is = getClass().getResourceAsStream(name); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String line; while ((line = br.readLine()) != null) { sb.append(line); sb.append('\n'); } is.close(); } catch (Exception e) { e.printStackTrace(); } return new String[] { sb.toString() }; } private void printShaderInfoLog(GLAutoDrawable d, int obj) { GL3 gl = d.getGL().getGL3(); // get the OpenGL 3 graphics context IntBuffer infoLogLengthBuf = IntBuffer.allocate(1); int infoLogLength; gl.glGetShaderiv(obj, GL3.GL_INFO_LOG_LENGTH, infoLogLengthBuf); infoLogLength = infoLogLengthBuf.get(0); if (infoLogLength > 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 d, int obj) { GL3 gl = d.getGL().getGL3(); // get the OpenGL 3 graphics context IntBuffer infoLogLengthBuf = IntBuffer.allocate(1); int infoLogLength; gl.glGetProgramiv(obj, GL3.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 float[] loadVertexData(String filename, int perVertexFloats) { float[] floatArray = new float[0]; // read vertex data from file int vertSize = 0; try { InputStream is = getClass().getResourceAsStream(filename); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String line = br.readLine(); if (line != null) { vertSize = Integer.parseInt(line); floatArray = new float[vertSize]; } int i = 0; while ((line = br.readLine()) != null && i < floatArray.length) { floatArray[i] = Float.parseFloat(line); i++; } if (i != vertSize || (vertSize % perVertexFloats) != 0) { floatArray = new float[0]; } br.close(); } catch (FileNotFoundException e) { System.out.println("Can not find vbo data file " + filename); } catch (IOException e) { e.printStackTrace(); } return floatArray; } // the following functions are some matrix and vector helpers // they work for this demo but in general it is recommended // to use more advanced matrix libraries private float vec3Dot(float[] a, float[] b) { return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; } private void vec3Cross(float[] a, float[] b, float[] res) { res[0] = a[1] * b[2] - b[1] * a[2]; res[1] = a[2] * b[0] - b[2] * a[0]; res[2] = a[0] * b[1] - b[0] * a[1]; } private void vec3Normalize(float[] a) { float mag = (float) Math.sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]); a[0] /= mag; a[1] /= mag; a[2] /= mag; } private void mat4Identity(float[] a) { for (int i = 0; i < 16; ++i) a[i] = 0.0f; for (int i = 0; i < 4; ++i) a[i + i * 4] = 1.0f; } private void mat4Multiply(float[] a, float[] b, float[] res) { for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) { res[j * 4 + i] = 0.0f; for (int k = 0; k < 4; ++k) { res[j * 4 + i] += a[k * 4 + i] * b[j * 4 + k]; } } } } private void mat4Perspective(float[] a, float fov, float aspect, float zNear, float zFar) { float f = 1.0f / (float) (Math.tan(fov / 2.0f * (Math.PI / 180.0f))); mat4Identity(a); a[0] = f / aspect; a[1 * 4 + 1] = f; a[2 * 4 + 2] = (zFar + zNear) / (zNear - zFar); a[3 * 4 + 2] = (2.0f * zFar * zNear) / (zNear - zFar); a[2 * 4 + 3] = -1.0f; a[3 * 4 + 3] = 0.0f; } private void mat4LookAt(float[] viewMatrix, float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ) { float dir[] = new float[3]; float right[] = new float[3]; float up[] = new float[3]; float eye[] = new float[3]; up[0] = upX; up[1] = upY; up[2] = upZ; eye[0] = eyeX; eye[1] = eyeY; eye[2] = eyeZ; dir[0] = centerX - eyeX; dir[1] = centerY - eyeY; dir[2] = centerZ - eyeZ; vec3Normalize(dir); vec3Cross(dir, up, right); vec3Normalize(right); vec3Cross(right, dir, up); vec3Normalize(up); // first row viewMatrix[0] = right[0]; viewMatrix[4] = right[1]; viewMatrix[8] = right[2]; viewMatrix[12] = -vec3Dot(right, eye); // second row viewMatrix[1] = up[0]; viewMatrix[5] = up[1]; viewMatrix[9] = up[2]; viewMatrix[13] = -vec3Dot(up, eye); // third row viewMatrix[2] = -dir[0]; viewMatrix[6] = -dir[1]; viewMatrix[10] = -dir[2]; viewMatrix[14] = vec3Dot(dir, eye); // forth row viewMatrix[3] = 0.0f; viewMatrix[7] = 0.0f; viewMatrix[11] = 0.0f; viewMatrix[15] = 1.0f; } private void mat4Print(float[] a) { // opengl uses column major order for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) { System.out.print(a[j * 4 + i] + " "); } System.out.println(" "); } } private void mat4Transpose(float[] a, float[] transposed) { int t = 0; for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) { transposed[t++] = a[j * 4 + i]; } } } private boolean mat4Invert(float[] m, float[] inverse) { float inv[] = new float[16]; inv[0] = m[5] * m[10] * m[15] - m[5] * m[11] * m[14] - m[9] * m[6] * m[15] + m[9] * m[7] * m[14] + m[13] * m[6] * m[11] - m[13] * m[7] * m[10]; inv[4] = -m[4] * m[10] * m[15] + m[4] * m[11] * m[14] + m[8] * m[6] * m[15] - m[8] * m[7] * m[14] - m[12] * m[6] * m[11] + m[12] * m[7] * m[10]; inv[8] = m[4] * m[9] * m[15] - m[4] * m[11] * m[13] - m[8] * m[5] * m[15] + m[8] * m[7] * m[13] + m[12] * m[5] * m[11] - m[12] * m[7] * m[9]; inv[12] = -m[4] * m[9] * m[14] + m[4] * m[10] * m[13] + m[8] * m[5] * m[14] - m[8] * m[6] * m[13] - m[12] * m[5] * m[10] + m[12] * m[6] * m[9]; inv[1] = -m[1] * m[10] * m[15] + m[1] * m[11] * m[14] + m[9] * m[2] * m[15] - m[9] * m[3] * m[14] - m[13] * m[2] * m[11] + m[13] * m[3] * m[10]; inv[5] = m[0] * m[10] * m[15] - m[0] * m[11] * m[14] - m[8] * m[2] * m[15] + m[8] * m[3] * m[14] + m[12] * m[2] * m[11] - m[12] * m[3] * m[10]; inv[9] = -m[0] * m[9] * m[15] + m[0] * m[11] * m[13] + m[8] * m[1] * m[15] - m[8] * m[3] * m[13] - m[12] * m[1] * m[11] + m[12] * m[3] * m[9]; inv[13] = m[0] * m[9] * m[14] - m[0] * m[10] * m[13] - m[8] * m[1] * m[14] + m[8] * m[2] * m[13] + m[12] * m[1] * m[10] - m[12] * m[2] * m[9]; inv[2] = m[1] * m[6] * m[15] - m[1] * m[7] * m[14] - m[5] * m[2] * m[15] + m[5] * m[3] * m[14] + m[13] * m[2] * m[7] - m[13] * m[3] * m[6]; inv[6] = -m[0] * m[6] * m[15] + m[0] * m[7] * m[14] + m[4] * m[2] * m[15] - m[4] * m[3] * m[14] - m[12] * m[2] * m[7] + m[12] * m[3] * m[6]; inv[10] = m[0] * m[5] * m[15] - m[0] * m[7] * m[13] - m[4] * m[1] * m[15] + m[4] * m[3] * m[13] + m[12] * m[1] * m[7] - m[12] * m[3] * m[5]; inv[14] = -m[0] * m[5] * m[14] + m[0] * m[6] * m[13] + m[4] * m[1] * m[14] - m[4] * m[2] * m[13] - m[12] * m[1] * m[6] + m[12] * m[2] * m[5]; inv[3] = -m[1] * m[6] * m[11] + m[1] * m[7] * m[10] + m[5] * m[2] * m[11] - m[5] * m[3] * m[10] - m[9] * m[2] * m[7] + m[9] * m[3] * m[6]; inv[7] = m[0] * m[6] * m[11] - m[0] * m[7] * m[10] - m[4] * m[2] * m[11] + m[4] * m[3] * m[10] + m[8] * m[2] * m[7] - m[8] * m[3] * m[6]; inv[11] = -m[0] * m[5] * m[11] + m[0] * m[7] * m[9] + m[4] * m[1] * m[11] - m[4] * m[3] * m[9] - m[8] * m[1] * m[7] + m[8] * m[3] * m[5]; inv[15] = m[0] * m[5] * m[10] - m[0] * m[6] * m[9] - m[4] * m[1] * m[10] + m[4] * m[2] * m[9] + m[8] * m[1] * m[6] - m[8] * m[2] * m[5]; float det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12]; if (det == 0) return false; det = 1.0f / det; for (int i = 0; i < 16; i++) inverse[i] = inv[i] * det; return true; } private void applyMatrixToVec4(float[] m, float[] vector, float[] result) { result[0] = m[0 + 4 * 0] * vector[0] + m[0 + 4 * 1] * vector[1] + m[0 + 4 * 2] * vector[2] + m[0 + 4 * 3] * vector[3]; result[1] = m[1 + 4 * 0] * vector[0] + m[1 + 4 * 1] * vector[1] + m[1 + 4 * 2] * vector[2] + m[1 + 4 * 3] * vector[3]; result[2] = m[2 + 4 * 0] * vector[0] + m[2 + 4 * 1] * vector[1] + m[2 + 4 * 2] * vector[2] + m[2 + 4 * 3] * vector[3]; result[3] = m[3 + 4 * 0] * vector[0] + m[3 + 4 * 1] * vector[1] + m[3 + 4 * 2] * vector[2] + m[3 + 4 * 3] * vector[3]; } private void rotateZ(float[] rot, float degree) { mat4Identity(rot); float rad = (float)Math.PI / 180.0f * degree; rot[0 + 4 * 0] = (float)Math.cos(rad); rot[1 + 4 * 0] = (float)Math.sin(rad); rot[0 + 4 * 1] = -(float)Math.sin(rad); rot[1 + 4 *1] = (float)Math.cos(rad); } } class MyGui extends JFrame implements GLEventListener { private Renderer renderer; public void createGUI() { setTitle("Shader Light/Material"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); GLProfile glp = GLProfile.getDefault(); GLCapabilities caps = new GLCapabilities(glp); GLCanvas canvas = new GLCanvas(caps); setSize(320, 320); getContentPane().add(canvas); final FPSAnimator ani = new FPSAnimator(canvas, 60, true); canvas.addGLEventListener(this); setVisible(true); renderer = new Renderer(); canvas.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent event) { boolean redraw = false; String modeStr = ""; switch (event.getKeyCode()) { case '1': renderer.modeVal = 1; redraw = true; modeStr = "mode = 1"; break; case '2': renderer.modeVal = 2; redraw = true; modeStr = "mode = 2"; break; case '3': renderer.modeVal = 3; redraw = true; modeStr = "mode = 3"; break; case '4': renderer.modeVal = 4; redraw = true; modeStr = "mode = 4"; break; case '5': renderer.modeVal = 5; redraw = true; modeStr = "mode = 5"; break; case '9': renderer.loadNextShader = true; redraw = true; modeStr = "Shader Light/Material"; break; case '0': renderer.loadNext = true; redraw = true; modeStr = "Shader Light/Material"; break; } if (redraw) { setTitle(modeStr); } } }); ani.start(); } @Override public void init(GLAutoDrawable d) { renderer.init(d); } @Override public void reshape(GLAutoDrawable d, int x, int y, int width, int height) { renderer.resize(d, width, height); } @Override public void display(GLAutoDrawable d) { float offset = 1.0f; renderer.t += offset; renderer.display(d); } @Override public void dispose(GLAutoDrawable d) { renderer.deleteAll(d); } } public class ShaderLightMat { public static void main(String[] args) { System.setProperty("sun.java2d.uiScale", "1.0"); javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { MyGui myGUI = new MyGui(); myGUI.createGUI(); } }); } }