マウス操作まで作る
scalaで書く前にとりあえずjavaで、他の言語で作るときと同様のマウス操作まで作った。
ひとつ前で作ったパーサと合体して頂点配列を描画するようにしたらMQOビューワはできあがり予定。
JOGLAPP.java
import javax.swing.JFrame; import javax.swing.JFileChooser; import javax.swing.JMenuBar; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.Action; import javax.swing.AbstractAction; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.event.MouseWheelListener; import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; import javax.media.opengl.awt.GLJPanel; class MyFrame extends JFrame implements MouseListener, MouseMotionListener, MouseWheelListener { GLDriver driver; int mouseLastX; int mouseLastY; boolean mouseMiddlePressed; boolean mouseRightPressed; public MyFrame(String title){ super(title); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); driver=new GLDriver(); // initialize mouse state mouseRightPressed=false; mouseMiddlePressed=false; mouseLastX=0; mouseLastY=0; // GLJPanel GLJPanel glArea=new GLJPanel(); setContentPane(glArea); glArea.addGLEventListener(driver); // mouse event glArea.addMouseListener(this); glArea.addMouseMotionListener(this); addMouseWheelListener(this); // setup menu JMenuBar menuBar=new JMenuBar(); setJMenuBar(menuBar); // file menu JMenu menu=new JMenu("File"); menuBar.add(menu); // file open item final JFrame parentFrame=this; JMenuItem item=new JMenuItem(new AbstractAction(){ { putValue(NAME, "Open"); putValue(SHORT_DESCRIPTION, "open a file"); putValue(MNEMONIC_KEY, new Integer(KeyEvent.VK_O)); } public void actionPerformed(ActionEvent e){ final JFileChooser fc = new JFileChooser(); int returnVal=fc.showOpenDialog(parentFrame); if (returnVal == JFileChooser.APPROVE_OPTION) { driver.openFile(fc.getSelectedFile()); } } }); menu.add(item); } //////////////////////////////////////////////////////////// // MouseListener //////////////////////////////////////////////////////////// @Override public void mouseClicked(MouseEvent e) { } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseExited(MouseEvent e) { } @Override public void mousePressed(MouseEvent e) { int x=e.getX(); int y=e.getY(); switch(e.getButton()){ case MouseEvent.BUTTON1: break; case MouseEvent.BUTTON2: mouseMiddlePressed=true; break; case MouseEvent.BUTTON3: mouseRightPressed=true; break; } mouseLastX=x; mouseLastY=y; } @Override public void mouseReleased(MouseEvent e) { switch(e.getButton()){ case MouseEvent.BUTTON1: break; case MouseEvent.BUTTON2: mouseMiddlePressed=false; break; case MouseEvent.BUTTON3: mouseRightPressed=false; break; } } //////////////////////////////////////////////////////////// // MouseMotionListener //////////////////////////////////////////////////////////// @Override public void mouseDragged(MouseEvent e) { int x=e.getX(); int y=e.getY(); if(mouseMiddlePressed){ driver.onMouseMiddleDrag(x-mouseLastX, y-mouseLastY); repaint(); } if(mouseRightPressed){ driver.onMouseRightDrag(x-mouseLastX, y-mouseLastY); repaint(); } mouseLastX=x; mouseLastY=y; } @Override public void mouseMoved(MouseEvent e) { } //////////////////////////////////////////////////////////// // MouseWheelListener //////////////////////////////////////////////////////////// @Override public void mouseWheelMoved(MouseWheelEvent e) { driver.onMouseWheel(e.getWheelRotation()); repaint(); } } public class JOGLAPP { public static void main(String[] args) { // SWING JFrame frame=new MyFrame("SWING"); frame.setSize(300, 300); frame.setVisible(true); } }
JOGL2.0ではjavax.media.opengl.GL2を使うのがミソらしい?
GLDriver.java
import java.io.File; import javax.media.opengl.GL; import javax.media.opengl.GL2; import javax.media.opengl.glu.GLU; import javax.media.opengl.GLAutoDrawable; import javax.media.opengl.GLEventListener; import com.sun.opengl.util.Animator; class View { float head; float pitch; float distance; float shift_x; float shift_y; float fovy; float aspect; float near; float far; public View(){ head=0.0f; pitch=0.0f; distance=5.0f; shift_x=0.0f; shift_y=0.0f; fovy=45.0f; aspect=1.0f; near=1.0f; far=20.0f; } public void resize(GL gl, float width, float height){ gl.glViewport(0, 0, (int)width, (int)height); // avoid a divide by zero error! if (height <= 0){ height = 1; } aspect = width / height; applyProjection(gl.getGL2()); } public void applyProjection(GL2 gl){ GLU glu=GLU.createGLU(); gl.glMatrixMode(GL2.GL_PROJECTION); gl.glLoadIdentity(); glu.gluPerspective(fovy, aspect, near, far); } public void apply(GL2 gl){ gl.glMatrixMode(GL2.GL_MODELVIEW); gl.glTranslated(shift_x, shift_y, -distance); gl.glRotated(pitch, 1, 0, 0); gl.glRotated(head, 0, 1, 0); } public void head(float d){ head+=d; while(head>180.0f){ head-=360.0f; } while(head<-180.0f){ head+=360.0f; } } public void pitch(float d){ pitch+=d; if(pitch>90.0f){ pitch=90.0f; } if(pitch<-90.0f){ pitch=-90.0f; } } public void dolly(float d){ if(d>0){ distance*=1.1; } else if(d<0){ distance*=0.9; } } public void shift(float dx, float dy){ float FACTOR=0.005f; shift_x+=dx*distance*FACTOR; shift_y+=dy*distance*FACTOR; } } class GLDriver implements GLEventListener { View view; public GLDriver(){ view=new View(); Animator anim = new Animator(); anim.start(); } public void onMouseMiddleDrag(int x, int y){ view.shift(x, -y); } public void onMouseRightDrag(int x, int y){ view.head(x); view.pitch(y); } public void onMouseWheel(int d){ view.dolly(d); } public boolean openFile(File f){ System.out.println("open: "+f); return true; } private void drawCube(GL2 gl){ gl.glBegin(GL2.GL_QUADS); // Front Face gl.glColor3f(1.0f, 1.0f, 1.0f); gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, 1.0f); gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f, 1.0f); gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f( 1.0f, 1.0f, 1.0f); gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f(-1.0f, 1.0f, 1.0f); // Back Face gl.glColor3f(1.0f, 0.0f, 1.0f); gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, -1.0f); gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f(-1.0f, 1.0f, -1.0f); gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f( 1.0f, 1.0f, -1.0f); gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f, -1.0f); // Top Face gl.glColor3f(1.0f, 0.0f, 0.0f); gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f(-1.0f, 1.0f, -1.0f); gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f(-1.0f, 1.0f, 1.0f); gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f( 1.0f, 1.0f, 1.0f); gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f( 1.0f, 1.0f, -1.0f); // Bottom Face gl.glColor3f(1.0f, 1.0f, 0.0f); gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f(-1.0f, -1.0f, -1.0f); gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f( 1.0f, -1.0f, -1.0f); gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f, 1.0f); gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, 1.0f); // Right face gl.glColor3f(0.0f, 1.0f, 0.0f); gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f, -1.0f); gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f( 1.0f, 1.0f, -1.0f); gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f( 1.0f, 1.0f, 1.0f); gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f, 1.0f); // Left Face gl.glColor3f(0.0f, 0.0f, 1.0f); gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, -1.0f); gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, 1.0f); gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f(-1.0f, 1.0f, 1.0f); gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f(-1.0f, 1.0f, -1.0f); gl.glEnd(); } //////////////////////////////////////////////////////////// // GLEventListener //////////////////////////////////////////////////////////// @Override public void init(GLAutoDrawable drawable) { // init opengl here System.out.println("MyGLEventListener#init"); GL2 gl = drawable.getGL().getGL2(); //gl.glShadeModel(GL.GL_SMOOTH); gl.glClearColor(0.5f, 0.5f, 0.5f, 0.5f); gl.glClearDepth(1.0f); gl.glEnable(GL2.GL_DEPTH_TEST); gl.glDepthFunc(GL2.GL_LEQUAL); gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST); } @Override public void display(GLAutoDrawable drawable) { GL2 gl = drawable.getGL().getGL2(); // clear gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT); gl.glMatrixMode(GL2.GL_MODELVIEW); gl.glLoadIdentity(); // draw view.apply(gl); drawCube(gl); gl.glFinish(); } @Override public void dispose(GLAutoDrawable drawable) { } @Override public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { view.resize(drawable.getGL(), width, height); } }