// 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.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import javax.imageio.ImageIO; import com.jogamp.opengl.GL2; 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 com.jogamp.opengl.glu.GLU; import javax.swing.JFrame; import com.jogamp.opengl.util.FPSAnimator; class Renderer { private GLU glu = new GLU(); public float t = -90.0f; public int wrapS = GL2.GL_REPEAT; public int wrapT = GL2.GL_REPEAT; public int magFilter = GL2.GL_LINEAR; public int minFilter = GL2.GL_LINEAR_MIPMAP_LINEAR; public int selectedTexID = 0; private int texID0 = 0; private int texID1 = 0; public void init(GLAutoDrawable d) { GL2 gl = d.getGL().getGL2(); // get the OpenGL 2 graphics context gl.glEnable(GL2.GL_DEPTH_TEST); texID0 = loadTexture(d, "checker_texture_512.png"); texID1 = loadTexture(d, "checker_texture_32.png"); } public void resize(GLAutoDrawable d, int w, int h) { GL2 gl = d.getGL().getGL2(); // get the OpenGL 2 graphics context gl.glViewport(0, 0, w, h); gl.glMatrixMode(GL2.GL_PROJECTION); gl.glLoadIdentity(); glu.gluPerspective (30.0, (float)w/(float)h, 0.1, 50.0); } public void display(GLAutoDrawable d) { GL2 gl = d.getGL().getGL2(); // get the OpenGL 2 graphics context gl.glClearColor(0.7f, 0.7f, 0.7f, 0.0f); gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT); gl.glMatrixMode(GL2.GL_MODELVIEW); gl.glLoadIdentity(); // set camera glu.gluLookAt(8.0, -2.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0); // draw scene gl.glRotatef(t, 0.0f, 0.0f, 1.0f); drawTexturedPlane(d); } // returns a valid textureID on success, otherwise 0 private int loadTexture(GLAutoDrawable d, String filename) { GL2 gl = d.getGL().getGL2(); // get the OpenGL 2 graphics context int width; int height; int level = 0; int border = 0; try{ // open file FileInputStream fileInputStream = new FileInputStream(new File(filename)); // read image BufferedImage bufferedImage = ImageIO.read(fileInputStream); fileInputStream.close(); width = bufferedImage.getWidth(); height = bufferedImage.getHeight(); // convert image to ByteBuffer int[] pixelIntData = new int[width * height]; bufferedImage.getRGB(0, 0, width, height, pixelIntData, 0, width); ByteBuffer buffer = ByteBuffer.allocateDirect(pixelIntData.length * 4); buffer.order(ByteOrder.nativeOrder()); // Unpack the data, each integer into 4 bytes of the ByteBuffer. // Also we need to vertically flip the image because the image origin // in OpenGL is the lower-left corner. for(int y=0; y < height; y++) { int k = (height-1-y) * width; for(int x=0; x < width; x++) { buffer.put((byte)(pixelIntData[k]>>> 16)); buffer.put((byte)(pixelIntData[k]>>> 8)); buffer.put((byte)(pixelIntData[k])); buffer.put((byte)(pixelIntData[k]>>> 24)); k++; } } buffer.rewind(); // data is aligned in byte order gl.glPixelStorei(GL2.GL_UNPACK_ALIGNMENT, 1); //request textureID final int[] textureID = new int[1]; gl.glGenTextures( 1, textureID, 0); // bind texture gl.glBindTexture(GL2.GL_TEXTURE_2D, textureID[0]); // parameters that define how to warp the texture gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_S, GL2.GL_REPEAT); gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_T, GL2.GL_REPEAT); float[] borderColor = {1.0f, 1.0f, 0.0f, 1.0f}; gl.glTexParameterfv(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_BORDER_COLOR, borderColor, 0); // parameters that define how to filter the texture 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_MIPMAP_LINEAR); gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_GENERATE_MIPMAP, GL2.GL_TRUE); // texture colors should replace the original color values gl.glTexEnvf(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_REPLACE); //GL_MODULATE // specify the 2D texture map gl.glTexImage2D(GL2.GL_TEXTURE_2D, level, GL2.GL_RGB, width, height, border, GL2.GL_RGBA, GL2.GL_UNSIGNED_BYTE, buffer); return textureID[0]; } catch( FileNotFoundException e) { System.out.println("Can not find texture data file " + filename); } catch(IOException e) { e.printStackTrace( ); } return 0; } private void setTextureParameters(GLAutoDrawable d) { GL2 gl = d.getGL().getGL2(); // get the OpenGL 2 graphics context gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_S, wrapS); gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_T, wrapT); gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, magFilter); gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, minFilter); } private void drawTexturedPlane(GLAutoDrawable d) { GL2 gl = d.getGL().getGL2(); // get the OpenGL 2 graphics context gl.glEnable(GL2.GL_TEXTURE_2D); if(selectedTexID == 0) { gl.glBindTexture(GL2.GL_TEXTURE_2D, texID0); }else{ gl.glBindTexture(GL2.GL_TEXTURE_2D, texID1); } setTextureParameters(d); gl.glColor3f(1.0f,0.0f,0.0f); gl.glBegin(GL2.GL_POLYGON); gl.glTexCoord2f( 5.00f, 5.00f); gl.glVertex3f(-10.0f, 10.0f, 0.0f); gl.glTexCoord2f( 5.00f, -4.00f); gl.glVertex3f(-10.0f,-10.0f, 0.0f); gl.glTexCoord2f(-4.00f, -4.00f); gl.glVertex3f( 10.0f,-10.0f, 0.0f); gl.glTexCoord2f(-4.00f, 5.00f); gl.glVertex3f( 10.0f, 10.0f, 0.0f); gl.glEnd(); gl.glDisable(GL2.GL_TEXTURE_2D); } } class MyGui extends JFrame implements GLEventListener { private Renderer renderer; public void createGUI() { setTitle("Use the 1 to 5 keys to change the texture parameters"); 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 mode = ""; switch(event.getKeyCode()) { case '1': if(renderer.wrapS == GL2.GL_REPEAT) { renderer.wrapS = GL2.GL_CLAMP; mode = "wrapS = GL_CLAMP"; } else if(renderer.wrapS == GL2.GL_CLAMP) { renderer.wrapS = GL2.GL_MIRRORED_REPEAT; mode = "wrapS = GL_MIRRORED_REPEAT"; } else if(renderer.wrapS == GL2.GL_MIRRORED_REPEAT) { renderer.wrapS = GL2.GL_CLAMP_TO_BORDER; mode = "wrapS = GL_CLAMP_TO_BORDER"; } else if(renderer.wrapS == GL2.GL_CLAMP_TO_BORDER) { renderer.wrapS = GL2.GL_REPEAT; mode = "wrapS = GL_REPEAT"; } redraw = true; break; case '2': if(renderer.wrapT == GL2.GL_REPEAT) { renderer.wrapT = GL2.GL_CLAMP; mode = "wrapT = GL_CLAMP"; } else if(renderer.wrapT == GL2.GL_CLAMP) { renderer.wrapT = GL2.GL_MIRRORED_REPEAT; mode = "wrapT = GL_MIRRORED_REPEAT"; } else if(renderer.wrapT == GL2.GL_MIRRORED_REPEAT) { renderer.wrapT = GL2.GL_CLAMP_TO_BORDER; mode = "wrapT = GL_CLAMP_TO_BORDER"; } else if(renderer.wrapT == GL2.GL_CLAMP_TO_BORDER) { renderer.wrapT = GL2.GL_REPEAT; mode = "wrapT = GL_REPEAT"; } redraw = true; break; case '3': if(renderer.minFilter == GL2.GL_NEAREST) { renderer.minFilter = GL2.GL_LINEAR; mode = "minFilter = GL_LINEAR"; } else if(renderer.minFilter == GL2.GL_LINEAR) { renderer.minFilter = GL2.GL_NEAREST_MIPMAP_NEAREST; mode = "minFilter = GL_NEAREST_MIPMAP_NEAREST"; } else if(renderer.minFilter == GL2.GL_NEAREST_MIPMAP_NEAREST) { renderer.minFilter = GL2.GL_LINEAR_MIPMAP_NEAREST; mode = "minFilter = GL_LINEAR_MIPMAP_NEAREST"; } else if(renderer.minFilter == GL2.GL_LINEAR_MIPMAP_NEAREST) { renderer.minFilter = GL2.GL_NEAREST_MIPMAP_LINEAR; mode = "minFilter = GL_NEAREST_MIPMAP_LINEAR"; } else if(renderer.minFilter == GL2.GL_NEAREST_MIPMAP_LINEAR) { renderer.minFilter = GL2.GL_LINEAR_MIPMAP_LINEAR; mode = "minFilter = GL_LINEAR_MIPMAP_LINEAR"; } else if(renderer.minFilter == GL2.GL_LINEAR_MIPMAP_LINEAR) { renderer.minFilter = GL2.GL_NEAREST; mode = "minFilter = GL_NEAREST"; } redraw = true; break; case '4': if(renderer.magFilter == GL2.GL_NEAREST) { renderer.magFilter = GL2.GL_LINEAR; mode = "magFilter = GL_LINEAR"; } else if(renderer.magFilter == GL2.GL_LINEAR) { renderer.magFilter = GL2.GL_NEAREST; mode = "magFilter = GL_NEAREST"; } redraw = true; break; case '5': if(renderer.selectedTexID == 0) { renderer.selectedTexID = 1; mode = "texture resolution 32x32 pixels"; } else { renderer.selectedTexID = 0; mode = "texture resolution 512x512 pixels"; } redraw = true; break; } if(redraw) { // done automatically setTitle(mode); } } }); 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 = 0.25f; renderer.t += offset; renderer.display(d); } @Override public void dispose(GLAutoDrawable d) { } } public class TextureParameter { public static void main(String[] args) { javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { MyGui myGUI = new MyGui(); myGUI.createGUI(); } }); } }