import java.awt.Frame; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.IOException; import java.util.Vector; import javax.media.opengl.GL; import javax.media.opengl.GLAutoDrawable; import javax.media.opengl.GLCanvas; import javax.media.opengl.GLEventListener; import javax.media.opengl.glu.GLU; import javax.media.opengl.glu.GLUquadric; import com.sun.opengl.util.Animator; import com.sun.opengl.util.GLUT; import com.sun.opengl.util.texture.Texture; import com.sun.opengl.util.texture.TextureIO; public class VagueGUI implements GLEventListener, KeyListener, MouseListener, MouseMotionListener, MouseWheelListener { /********************** * ATTRIBUTS * **********************/ private GLU glu = new GLU(); private GLUT glut = new GLUT(); private static GLCanvas canvas; private static Frame frame; private static Animator animator; private boolean rotationAllowed; // Verouillage de la rotation de la caméra private boolean motionEnable; private boolean displayFilled = true; private boolean drawNormals=false; private float diffY = 6; private int oldX = 0; // Variable temporaire utilisée pour la rotation autour de l'axe Y private int oldY = 0; // Variable temporaire utilisée pour la rotation autour de l'axe X private static int zoom = 50; // Zoom de la caméra, une valeur négative = caméra reculée par rapport a la scène private float timeT = 0; // Timer utilisé pour le calcul de l'animation des vagues private double theta; private float xTextureCoordinate=0; private float yTextureCoordinate=0; private double[] pos = new double[3]; private double[] dir = new double[3]; private Vector> oceanMesh = new Vector>(); // Le maillage de l'océan private Vague V; private static Point3D poscam= new Point3D(0.0f,0.0f,zoom); Point3D boat=new Point3D(0.0f,0.0f,0.0f); private GLUquadric g_quadratic; // Storage For Our Quadratic Objects private final double far=1000; private double farDistance=Math.log(far/1.5); Point3D vertex_to_light=new Point3D(0,0,0); Point3D vertex_position=new Point3D(0,0,0); // LIGHT SETTINGS private float[] global_ambient = new float[]{0.8f, 0.8f, 0.8f, 1.0f}; // Model Ambient Lighting To Fairly Dark Light (No Color) private float[] light0pos = new float[]{0.0f, 50.0f, -50.0f, 0.0f}; // The Light Position private float[] light0ambient = new float[]{0.3f, 0.3f, 0.3f, 1.0f}; // Ambient Light private float[] light0diffuse = new float[]{0.5f, 0.5f, 0.5f, 1.0f}; // Diffuse Light A Bit Brighter private float[] light0specular = new float[]{0.7f, 0.7f, 0.7f, 1.0f}; // Fairly Bright Specular Lighting // MATERIALS // private float matAmbiantRed[]={1.0f,0.0f,0.0f,1.0f}; private float matAmbiantBlue[]={0.0f,0.5f,1.0f,0.8f}; // private float matAmbiantGreen[]={0.0f,1.0f,0.0f,1.0f}; // private float matAmbiantBlack[]={0.0f,0.0f,0.0f,1.0f}; private float matAmbiantwhite[]={1.0f,1.0f,1.0f,1.0f}; // private float matSpecularf[]={0.0f,0.0f,0.5f,0.5f}; // private float matNoSpecularf[]={0.0f,0.0f,0.0f,0.0f}; // private float matShininessf[]={1.0f,1.0f,1.0f,1.0f}; // TEXTURES private int[] skyTexture = new int[1]; // Storage For 1 sky Textures private int[] waterTexture = new int[2]; // Storage For 1 sky Textures private double difX; private double difY2; private float textureMotion=0; // private int timeT; /*********************** * CONSTRUCTEUR * ***********************/ public VagueGUI(String NomFichier, char separateur1, char separateur2) { pos[0] = pos[1] = pos[2] = 0.0; dir[0] = pos[0]; dir[1] = pos[1]; dir[2] = pos[2] + zoom; V = new Vague(NomFichier, separateur1, separateur2); System.err.println(V.getNbLigne()); // oceanSize=100; createRoundOceanMesh(40, 40); } /************************************ * Loading Texture method * ************************************/ Texture createTexture(String filename) { Texture t = null; try { t = TextureIO.newTexture(getClass().getResource(filename), false, ".jpg"); t.setTexParameteri(GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); t.setTexParameteri(GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); } catch (IOException e) { System.err.println("Error loading " + filename ); System.err.println(e); } return t; } /*************************************************** * Méthode de normalisation de vecteur * ***************************************************/ void vectorNormalize (Point3D vector) { double size=Math.sqrt(vector.getX()*vector.getX()+vector.getY()*vector.getY()+vector.getZ()*vector.getZ()); vector.setX((float) (vector.getX()/size)); vector.setY((float) (vector.getY()/size)); vector.setZ((float) (vector.getZ()/size)); } /******************************************* * Square mesh ocean creation * *******************************************/ void createSquareOceanMesh(int x, int y) { for (int i = -x / 2; i < x / 2; i++) { Vector temp = new Vector(); for (int j = -y / 2; j < y / 2; j++) { Point3D point3D = new Point3D((float) i, 0.0f, (float) j); temp.add(point3D); } oceanMesh.add(temp); } } /***************************************** * Round mesh ocean creation * *****************************************/ void createRoundOceanMesh(double d, float r) { oceanMesh.clear(); double dis=farDistance/r; for (float j = 0; j <= r;j++) { Vector temp = new Vector(); for (double i = 1; i <= d; i++) { Point3D point3D = new Point3D((float) (poscam.getX()+Math.exp(dis*j) * MathRappid.tr_cos(i * 2.0 * Math.PI / d)), 0.0f, (float) (poscam.getZ()+Math.exp(dis*j)* MathRappid.tr_sin(i * 2.0 * Math.PI / d))); temp.add(point3D); } oceanMesh.add(temp); } } /******************************************************* * Méthode de d'angle entre deux vecteurs * *******************************************************/ public double computeVectorsAngle(Point3D V1, Point3D V2) { if((V1.getX()*V2.getX()+V1.getY()*V2.getY()+V1.getZ()*V2.getZ())>0) { return Double.NaN; } double tailleV1 = Math.pow(V1.getX(), 2) + Math.pow(V1.getY(), 2) + Math.pow(V1.getZ(), 2); double tailleV2 = Math.pow(V2.getX(), 2) + Math.pow(V2.getY(), 2) + Math.pow(V2.getZ(), 2); double tailledeproduitVectoriel = Math.pow((V1.getY() * V2.getZ() - V1.getZ() * V2.getY()), 2) + Math.pow((V1.getZ() * V2.getX() - V1.getX() * V2.getZ()), 2) + Math.pow((V1.getX() * V2.getY() - V1.getY() * V2.getX()), 2); // Angle entre V1 et V2 return Math.asin(Math.sqrt(tailledeproduitVectoriel / (tailleV1 * tailleV2))); } /******************************************************* * Méthode de d'angle entre deux vecteurs * *******************************************************/ public double computeVectorAngle2(Point3D V1, Point3D V2) { double tailleV1 = Math.pow(V1.getX(), 2) + Math.pow(V1.getY(), 2) + Math.pow(V1.getZ(), 2); double tailleV2 = Math.pow(V2.getX(), 2) + Math.pow(V2.getY(), 2) + Math.pow(V2.getZ(), 2); return Math.acos((V1.getX()*V2.getX()+V1.getY()*V2.getY()+V1.getZ()*V2.getZ())/ Math.sqrt(tailleV1 * tailleV2)); } /********************** * DISPLAY * **********************/ public void display(GLAutoDrawable gLDrawable) { GL gl = gLDrawable.getGL(); // Delete hidden surfaces gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glLoadIdentity(); // CAMERA MOVMENTS glu.gluLookAt(dir[0], dir[1], dir[2],pos[0], pos[1], pos[2], 0.0, 1.0, 0.0); // LIGHT AND BLENDING MODELS gl.glLightModelfv(GL.GL_LIGHT_MODEL_AMBIENT, global_ambient, 0); // Set The Global Ambient Light Model gl.glLightModeli(GL.GL_LIGHT_MODEL_COLOR_CONTROL, GL.GL_SEPARATE_SPECULAR_COLOR); // Compute specular light after texture binding gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA); // Select blending function gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE); // LIGHT gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, light0pos, 0); // Set The Lights Position gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, light0ambient, 0); // Set The Ambient Light gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, light0diffuse, 0); // Set The Diffuse Light gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, light0specular, 0); // Set Up Specular Lighting // SPHERE THAT REPRESENT THE LIGHT gl.glColor3f(0, 0, 0); gl.glBegin(GL.GL_LINE); gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE); gl.glTranslatef(light0pos[0],light0pos[1],light0pos[2]); glut.glutSolidSphere(0.5f, 10, 10); gl.glEnd(); gl.glTranslatef(-light0pos[0],-light0pos[1],-light0pos[2]); /** Creation du repère X, Y, Z Repère créé à l'origine de la scène * Les lignes ont une longueurs de 1 */ // Creation du repere en X gl.glDisable(GL.GL_LIGHTING); gl.glColor3f(1.0f, 0, 0); gl.glBegin(GL.GL_LINE_STRIP); gl.glVertex3f(0, 0, 0); gl.glVertex3f(1, 0, 0); gl.glEnd(); // Creation du repere en Y gl.glColor3f(0, 1.0f, 0); gl.glBegin(GL.GL_LINE_STRIP); gl.glVertex3f(0, 0, 0); gl.glVertex3f(0, 1, 0); gl.glEnd(); // Creation du repere en Z gl.glColor3f(0, 0, 1.0f); gl.glBegin(GL.GL_LINE_STRIP); gl.glVertex3f(0, 0, 0); gl.glVertex3f(0, 0, 1); gl.glEnd(); gl.glColor3f(1.0f, 1.0f, 1.0f); gl.glEnable(GL.GL_LIGHTING); // Enable Lighting gl.glEnable(GL.GL_LIGHT0); // Enable Light0 if (displayFilled) { gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL); /** Skydome display * Create a glu sphere and map sky texture */ gl.glPushMatrix(); //gl.glDisable(GL.GL_LIGHTING); glu.gluQuadricOrientation(g_quadratic, GLU.GLU_CW); glu.gluQuadricNormals(g_quadratic, GLU.GLU_SMOOTH); glu.gluQuadricTexture(g_quadratic, true); glu.gluQuadricDrawStyle(g_quadratic, GLU.GLU_FILL); gl.glTranslatef(poscam.getX(), poscam.getY(), poscam.getZ()); gl.glRotatef(-90f, 1.0f, 0f, 0f); gl.glEnable(GL.GL_TEXTURE_2D); gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT_AND_DIFFUSE,matAmbiantwhite, 0); gl.glActiveTexture(GL.GL_TEXTURE3); glu.gluSphere(g_quadratic,far,50,100); gl.glPopMatrix(); gl.glEnable(GL.GL_DEPTH_TEST); gl.glDepthMask(true); // gl.glEnable(GL.GL_LIGHTING); // gl.glDisable(GL.GL_TEXTURE_2D); textureMotion=(float)((textureMotion+0.0002f)%far); } else { gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE); } /** Boat Display * Display and compute boat position on the ocean */ if(motionEnable) { timeT+=0.04; V.calcul(boat, timeT); Point3D bd=new Point3D(boat.getX()+0.5f,0,boat.getZ()); Point3D bg=new Point3D(boat.getX()-0.5f,0,boat.getZ()); V.calcul(bd, timeT);V.calcul(bg, timeT); difX = Math.atan(-bg.getY()+bd.getY()); Point3D bdev=new Point3D(boat.getX(),0,boat.getZ()+.5f); Point3D bder=new Point3D(boat.getX(),0,boat.getZ()-.5f); V.calcul(bdev, timeT);V.calcul(bder, timeT); difY2 = Math.atan(-bdev.getY()+bder.getY()); // System.out.println(difX+" - "+difY2); } gl.glPushMatrix(); gl.glTranslatef(0.0f, boat.getY(), 0.0f); gl.glRotated(Math.toDegrees(difX), 1.0, 0.0, 0.0); gl.glRotated(Math.toDegrees(difY2), 0.0, 0.0, 1.0); gl.glEnable(GL.GL_LIGHTING); glut.glutSolidTeapot(1); gl.glPopMatrix(); /** Ocean display * Display ocean wired or textured * Display normals if specified */ gl.glPointSize(3.0f); gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT_AND_DIFFUSE,matAmbiantBlue, 0); // OCEAN TEXTURE if (oceanMesh != null) { if (displayFilled) { gl.glEnable(GL.GL_TEXTURE_2D); gl.glBindTexture(GL.GL_TEXTURE_2D, waterTexture[0]); } int tailllesP=oceanMesh.size(); for (int temp = 0; temp < tailllesP-1; temp++) { int tailllesP1=oceanMesh.elementAt(temp).size(); for (int temp2 = 0; temp2 < tailllesP1; temp2++) { Point3D P1 = new Point3D((float)((oceanMesh.elementAt(temp).elementAt(temp2).getX()+oceanMesh.elementAt(temp).elementAt((temp2+1)%tailllesP1).getX()+oceanMesh.elementAt(( temp+1 )%tailllesP).elementAt(temp2).getX()+oceanMesh.elementAt(( temp+1 )%tailllesP).elementAt((temp2+1)%tailllesP1).getX())/4.0), (float)((oceanMesh.elementAt(temp).elementAt(temp2).getY()+oceanMesh.elementAt(temp).elementAt((temp2+1)%tailllesP1).getY()+oceanMesh.elementAt(( temp+1 )%tailllesP).elementAt(temp2).getY()+oceanMesh.elementAt(( temp+1 )%tailllesP).elementAt((temp2+1)%tailllesP1).getY())/4.0), (float)((oceanMesh.elementAt(temp).elementAt(temp2).getZ()+oceanMesh.elementAt(temp).elementAt((temp2+1)%tailllesP1).getZ()+oceanMesh.elementAt(( temp+1 )%tailllesP).elementAt(temp2).getZ()+oceanMesh.elementAt(( temp+1 )%tailllesP).elementAt((temp2+1)%tailllesP1).getZ())/4.0)); Point3D V3 = new Point3D(P1.getX()-(float)dir[0], P1.getY()-(float)dir[1],P1.getZ()-(float)dir[2]); Point3D point3D=new Point3D((float)dir[0],(float)dir[1],(float)dir[2]); double angle2V1V2= computeVectorsAngle(V3,point3D); if (!Double.isNaN(angle2V1V2)) { if((angle2V1V2<(50.0*Math.PI/180.0))) { if((motionEnable)&&(oceanMesh.elementAt(temp).elementAt(temp2).getTour()!=timeT)) V.calcul(oceanMesh.elementAt(temp).elementAt(temp2), timeT,timeT); // Affichage du polygoneprivate float xTextureCoordinate=0; gl.glBegin(GL.GL_QUADS); gl.glNormal3f(oceanMesh.elementAt(temp).elementAt(temp2).getNormalX(), oceanMesh.elementAt(temp).elementAt(temp2).getNormalY(), oceanMesh.elementAt(temp).elementAt(temp2).getNormalZ()); // Compute texture coordinate if (displayFilled) { xTextureCoordinate=(float) ((oceanMesh.elementAt(temp).elementAt(temp2).getX()+far)/(far*2)); yTextureCoordinate=(float) ((oceanMesh.elementAt(temp).elementAt(temp2).getZ()+far)/(far*2)); gl.glMultiTexCoord2f(GL.GL_TEXTURE1, xTextureCoordinate*10-textureMotion,yTextureCoordinate*10-textureMotion); gl.glMultiTexCoord2f(GL.GL_TEXTURE2, xTextureCoordinate*10+textureMotion,yTextureCoordinate*10+textureMotion); } gl.glVertex3f(oceanMesh.elementAt(temp).elementAt(temp2).getX(), oceanMesh.elementAt(temp).elementAt(temp2).getY(), oceanMesh.elementAt(temp).elementAt(temp2).getZ()); if((motionEnable)&&(oceanMesh.elementAt(temp).elementAt((temp2+1)%tailllesP1).getTour()!=timeT)) V.calcul(oceanMesh.elementAt(temp).elementAt((temp2+1)%tailllesP1), timeT); gl.glNormal3f(oceanMesh.elementAt(temp).elementAt((temp2 + 1)%tailllesP1).getNormalX(), oceanMesh.elementAt(temp).elementAt((temp2 + 1)%tailllesP1).getNormalY(), oceanMesh.elementAt(temp).elementAt((temp2 + 1)%tailllesP1).getNormalZ()); // Compute texture coordinate if (displayFilled) { xTextureCoordinate=(float) ((oceanMesh.elementAt(temp).elementAt((temp2 + 1)%tailllesP1).getX()+far)/(far*2)); yTextureCoordinate=(float) ((oceanMesh.elementAt(temp).elementAt((temp2 + 1)%tailllesP1).getZ()+far)/(far*2)); // gl.glTexCoord2f(xTextureCoordinate, yTextureCoordinate); gl.glMultiTexCoord2f(GL.GL_TEXTURE1, xTextureCoordinate*10-textureMotion,yTextureCoordinate*10-textureMotion); gl.glMultiTexCoord2f(GL.GL_TEXTURE2, xTextureCoordinate*10+textureMotion,yTextureCoordinate*10+textureMotion); } gl.glVertex3f(oceanMesh.elementAt(temp).elementAt((temp2 + 1)%tailllesP1).getX(), oceanMesh.elementAt(temp).elementAt((temp2 + 1)%tailllesP1).getY(), oceanMesh.elementAt(temp).elementAt((temp2 + 1)%tailllesP1).getZ()); if((motionEnable)&&(oceanMesh.elementAt(temp+1).elementAt((temp2+1)%tailllesP1).getTour()!=timeT)) V.calcul(oceanMesh.elementAt(temp+1).elementAt((temp2+1)%tailllesP1), timeT,timeT); gl.glNormal3f(oceanMesh.elementAt(temp + 1).elementAt((temp2 + 1)%tailllesP1).getNormalX(), oceanMesh.elementAt(temp + 1).elementAt((temp2 + 1)%tailllesP1).getNormalY(), oceanMesh.elementAt(temp + 1).elementAt((temp2 + 1)%tailllesP1).getNormalZ()); // Compute texture coordinate if (displayFilled) { xTextureCoordinate=(oceanMesh.elementAt(temp + 1).elementAt((temp2 + 1)%tailllesP1).getX()+(float)far)/((float)far*2); yTextureCoordinate=(oceanMesh.elementAt(temp + 1).elementAt((temp2 + 1)%tailllesP1).getZ()+(float)far)/((float)far*2); // // vertex_position.setX(oceanMesh.elementAt(temp + 1).elementAt((temp2 + 1)%tailllesP1).getX()); // vertex_position.setY(oceanMesh.elementAt(temp + 1).elementAt((temp2 + 1)%tailllesP1).getY()); // vertex_position.setZ(oceanMesh.elementAt(temp + 1).elementAt((temp2 + 1)%tailllesP1).getZ()); // vertex_to_light.setX(light0pos[0]-vertex_position.getX()); // vertex_to_light.setY(light0pos[1]-vertex_position.getY()); // vertex_to_light.setZ(light0pos[2]-vertex_position.getZ()); // gl.glMultiTexCoord2f(GL.GL_TEXTURE1, xTextureCoordinate*10-textureMotion,yTextureCoordinate*10-textureMotion); gl.glMultiTexCoord2f(GL.GL_TEXTURE2, xTextureCoordinate*10+textureMotion,yTextureCoordinate*10+textureMotion); // gl.glTexCoord2f(xTextureCoordinate, yTextureCoordinate); } gl.glVertex3f(oceanMesh.elementAt(temp + 1).elementAt((temp2 + 1)%tailllesP1).getX(), oceanMesh.elementAt(temp + 1).elementAt((temp2 + 1)%tailllesP1).getY(), oceanMesh.elementAt(temp + 1).elementAt((temp2 + 1)%tailllesP1).getZ()); if((motionEnable)&&(oceanMesh.elementAt(temp+1).elementAt(temp2).getTour()!=timeT)) V.calcul(oceanMesh.elementAt(temp+1).elementAt(temp2), timeT,timeT); gl.glNormal3f(oceanMesh.elementAt(temp + 1).elementAt(temp2).getNormalX(), oceanMesh.elementAt(temp + 1).elementAt(temp2).getNormalY(), oceanMesh.elementAt(temp + 1).elementAt(temp2).getNormalZ()); // Compute texture coordinate if (displayFilled) { xTextureCoordinate=(float) ((oceanMesh.elementAt(temp+1).elementAt(temp2).getX()+far)/(far*2)); yTextureCoordinate=(float) ((oceanMesh.elementAt(temp+1).elementAt(temp2).getZ()+far)/(far*2)); // gl.glTexCoord2f(xTextureCoordinate, yTextureCoordinate); // vertex_position.setX(oceanMesh.elementAt(temp + 1).elementAt(temp2).getX()); // vertex_position.setY(oceanMesh.elementAt(temp + 1).elementAt(temp2).getY()); // vertex_position.setZ(oceanMesh.elementAt(temp + 1).elementAt(temp2).getZ()); //// vertex_to_light.setX(light0pos[0]-vertex_position.getX()); // vertex_to_light.setY(light0pos[1]-vertex_position.getY()); // vertex_to_light.setZ(light0pos[2]-vertex_position.getZ()); // // gl.glMultiTexCoord2f(GL.GL_TEXTURE1, xTextureCoordinate*10-textureMotion,yTextureCoordinate*10-textureMotion); gl.glMultiTexCoord2f(GL.GL_TEXTURE2, xTextureCoordinate*10+textureMotion,yTextureCoordinate*10+textureMotion); } gl.glVertex3f(oceanMesh.elementAt(temp + 1).elementAt(temp2).getX(), oceanMesh.elementAt(temp + 1).elementAt(temp2).getY(), oceanMesh.elementAt(temp + 1).elementAt(temp2).getZ()); gl.glEnd(); if(drawNormals) { // drawing normals with red lines gl.glDisable(GL.GL_LIGHT0); if (displayFilled) gl.glDisable(GL.GL_TEXTURE_2D); //gl.glColor3f( 1.0f, 0, 0); gl.glBegin(GL.GL_LINE_STRIP); gl.glVertex3f(oceanMesh.elementAt(temp).elementAt(temp2 ).getX(), oceanMesh.elementAt(temp).elementAt(temp2 ).getY(), oceanMesh.elementAt(temp).elementAt(temp2 ).getZ()); gl.glVertex3f(oceanMesh.elementAt(temp).elementAt(temp2 ).getNormalX()+oceanMesh.elementAt(temp).elementAt(temp2 ).getX(), oceanMesh.elementAt(temp).elementAt(temp2 ).getNormalY()+oceanMesh.elementAt(temp).elementAt(temp2 ).getY(), oceanMesh.elementAt(temp).elementAt(temp2 ).getNormalZ()+oceanMesh.elementAt(temp).elementAt(temp2 ).getZ()); gl.glEnd(); gl.glEnable(GL.GL_LIGHT0); if (displayFilled) gl.glEnable(GL.GL_TEXTURE_2D); } } } } } gl.glBegin(GL.GL_POLYGON); if(oceanMesh.size()>0) for (int i = 0 ;i 0) { diffY = 90; } if (diffY > -90 && diffY < 0) { diffY = -90; } if (diffY > 270) { diffY = 270; } double gama=Math.toRadians(diffY ); dir[0] = MathRappid.tr_sin(theta) * zoom * MathRappid.tr_sin(gama); dir[1] = -MathRappid.tr_cos(gama) * zoom; dir[2] = MathRappid.tr_cos(theta) * zoom * MathRappid.tr_sin(gama); poscam=new Point3D((float)dir[0], (float)dir[1], (float)dir[2]); } public void displayChanged(GLAutoDrawable gLDrawable, boolean modeChanged, boolean deviceChanged) { //animate(); } /********************** * KEYBOARD EVENTS * **********************/ public void keyPressed(KeyEvent e) { switch (e.getKeyCode()) { // Start / Stop animation case KeyEvent.VK_C: { motionEnable = (!motionEnable); break; } // Draw normals case KeyEvent.VK_N: { drawNormals = (!drawNormals); break; } // Arret du prog. si on appuie sur 'Q' ou 'q' case KeyEvent.VK_Q: case KeyEvent.VK_ESCAPE: { exit(); break; } // Modification du Zoom case KeyEvent.VK_Z: { if (e.isShiftDown()) zoom++; else if(zoom>1) zoom--; break; } // Control de la hauteur de la caméra case KeyEvent.VK_P: { displayFilled = !displayFilled; break; } case KeyEvent.VK_LEFT: { theta += Math.PI / 180.0; break; } case KeyEvent.VK_RIGHT: { theta -= Math.PI / 180.0; break; } case KeyEvent.VK_UP: { diffY++; break; } case KeyEvent.VK_DOWN: { diffY--; break; } } if(motionEnable) createRoundOceanMesh(40, 40); // Mise à jour de l'affichage canvas.display(); } public void keyReleased(KeyEvent e) { cameraSettingsUpdate(); } public void keyTyped(KeyEvent e) { } /********************** * MOUSE EVENTS * **********************/ public void mousePressed(MouseEvent e) { oldX = e.getX(); oldY = e.getY(); if ((e.getModifiers() & InputEvent.BUTTON3_MASK) != 0) { rotationAllowed = true; } } public void mouseWheelMoved(MouseWheelEvent e) { zoom=zoom+e.getWheelRotation(); cameraSettingsUpdate(); } public void mouseReleased(MouseEvent e) { if ((e.getModifiers() & InputEvent.BUTTON3_MASK) != 0) { rotationAllowed = false; oldX = e.getX(); oldY = e.getY(); } } public void mouseDragged(MouseEvent e) { int x = e.getX(); int y = e.getY(); if (rotationAllowed) { theta += Math.PI / 180.0 * ((1.0 / 1000.0) * (x - oldX)); diffY += (float) (1.0 / 1000.0) * (y - oldY); cameraSettingsUpdate(); } else { oldX = x; oldY = y; } } public void mouseMoved(MouseEvent e) { int x = e.getX(); int y = e.getY(); if (rotationAllowed) { diffY = (float) (y - oldY); } else { oldX = x; oldY = y; } } public void mouseClicked(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } /********************** * RESHAPE * **********************/ public void reshape(GLAutoDrawable gLDrawable, int x, int y, int width, int height) { GL gl = gLDrawable.getGL(); if (height <= 0) { height = 1; } float h = (float) width / (float) height; gl.glMatrixMode(GL.GL_PROJECTION); gl.glLoadIdentity(); glu.gluPerspective(50.0f, h, 1.0, far); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); System.err.println(pos[0]+","+ pos[1]+","+ pos[2]+","+ dir[0]+","+ dir[1]+","+ dir[2]); glu.gluLookAt( dir[0], dir[1], dir[2],pos[0], pos[1], pos[2], 0.0, 1.0, 0.0); } /********************** * EXIT * **********************/ public static void exit() { animator.stop(); frame.dispose(); System.exit(0); } /******************************* * TEXTURES INITIALISATION * *******************************/ private void loadGLTextures(GL gl, GLU glu) throws IOException { // Skydome texture gl.glGenTextures(1, skyTexture, 0); // Create one Textures TextureReader.Texture texture = TextureReader.readTexture("sky_MD.jpg"); gl.glBindTexture(GL.GL_TEXTURE_2D, skyTexture[0]); gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB8, texture.getWidth(),texture.getHeight(), 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE,texture.getPixels()); gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); System.err.println("Texture : sky_MD.jpg "+texture.getWidth()+"x"+texture.getHeight()+" LOADED"); // Load Water texture texture = TextureReader.readTexture("waterTextureHD.jpg"); gl.glGenTextures(2, waterTexture, 0); // Create Three Textures gl.glBindTexture(GL.GL_TEXTURE_2D, waterTexture[0]); // Create Nearest Filtered Texture gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, 3, texture.getWidth(), texture.getHeight(), 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, texture.getPixels()); gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MIN_FILTER,GL.GL_LINEAR); // Linear Filtering gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MAG_FILTER,GL.GL_LINEAR); // Linear Filtering System.err.println("Texture : waterTextureHD.jpg "+texture.getWidth()+"x"+texture.getHeight()+" LOADED"); // Load The Bumpmaps texture = TextureReader.readTexture("waterTextureHDNormalMap2.jpg"); gl.glBindTexture(GL.GL_TEXTURE_2D, waterTexture[1]); // Create Nearest Filtered Texture gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB8, texture.getWidth(), texture.getHeight(), 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, texture.getPixels()); gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MIN_FILTER,GL.GL_LINEAR); // Linear Filtering gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MAG_FILTER,GL.GL_LINEAR); // Linear Filtering System.err.println("Texture : waterTextureHDNormalMap.jpg "+texture.getWidth()+"x"+texture.getHeight()+" LOADED"); gl.glActiveTexture(GL.GL_TEXTURE1); gl.glEnable(GL.GL_TEXTURE_2D); gl.glBindTexture(GL.GL_TEXTURE_2D, waterTexture[1]); gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_COMBINE); gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_COMBINE_RGB, GL.GL_DOT3_RGB) ; gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_SOURCE0_RGB, GL.GL_PREVIOUS) ; gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_SOURCE1_RGB, GL.GL_TEXTURE) ; gl.glActiveTexture(GL.GL_TEXTURE2); gl.glEnable(GL.GL_TEXTURE_2D); gl.glBindTexture(GL.GL_TEXTURE_2D, waterTexture[0]); gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE); gl.glActiveTexture(GL.GL_TEXTURE3); gl.glEnable(GL.GL_TEXTURE_2D); gl.glBindTexture(GL.GL_TEXTURE_2D, skyTexture[0]); gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE); } /********************** * INITIALISATION * **********************/ public void init(GLAutoDrawable gLDrawable) { GL gl = gLDrawable.getGL(); gl.glEnable(GL.GL_DEPTH_TEST); // Enables Depth Testing gl.glShadeModel(GL.GL_SMOOTH); // Define shading model gl.glClearColor(1.0f, 1.0f, 1.0f, 0.0f); // Background color gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST); // Nice perspective computation gl.glEnable(GL.GL_BLEND); // Enable blending gl.glEnable(GL.GL_TEXTURE_2D); // Listeners gLDrawable.addKeyListener(this); gLDrawable.addMouseListener(this); gLDrawable.addMouseMotionListener(this); gLDrawable.addMouseWheelListener(this); // Textures try { loadGLTextures(gl, glu); } catch (IOException e) { throw new RuntimeException(e); } g_quadratic = glu.gluNewQuadric(); // Create A Pointer To The Quadric Object (Return 0 If No Memory) glu.gluQuadricNormals(g_quadratic, GLU.GLU_SMOOTH); // Create Smooth Normals glu.gluQuadricTexture(g_quadratic, true); // Create Texture Coords } /********************** * MAIN * **********************/ public static void main(String[] args) { VagueGUI Vg = new VagueGUI("jonswap2.txt", ':', ' '); canvas = new GLCanvas(); canvas.addGLEventListener(Vg); frame = new Frame("VOR2"); animator = new Animator(canvas); frame.add(canvas); frame.setSize(800, 600); frame.setUndecorated(false); frame.setExtendedState(Frame.MAXIMIZED_BOTH); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { exit(); } }); frame.setVisible(true); animator.start(); canvas.requestFocus(); } }