Created
February 19, 2009 09:49
-
-
Save takedasoft/66829 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* scala で OpenGLのためし。 | |
* Java OpenGL ライブラリ JOGL を使っています。 | |
* | |
* scalac -classpath \ | |
* "/jogl/lib/gluegen-rt.jar:/jogl/lib/jogl.jar" JOGLDemo.scala | |
* java -Djava.library.path="/jogl/lib" -classpath \ | |
* "./classes:scala-library.jar:\ | |
* /jogl/lib/gluegen-rt.jar:/jogl/lib/jogl.jar" takedasoft.JOGLDemo | |
* | |
* @see https://jogl.dev.java.net/ | |
*/ | |
package takedasoft | |
import javax.swing._ | |
import java.util.ArrayList | |
import java.awt.event._ | |
import javax.media.opengl._ | |
import scala.collection.mutable.Queue | |
import com.sun.opengl.util._ | |
/****************************** | |
Simple 3D Animation Framework | |
*******************************/ | |
class WorldConfig(gl:GL) { | |
val CAMERA = -10.0f | |
// Light | |
val LPOSITION = Array( -2.0f, 2.0f, -3.0f, 0.0f ) | |
val LSPECULAR = Array( 0.2f, 0.2f, 0.2f, 1.0f ) | |
val LDIFFUSE = Array( 0.5f, 0.5f, 0.5f, 1.0f ) | |
val LAMBIENT = Array( 0.8f, 0.8f, 0.8f, 1.0f ) | |
// reflection | |
val MSPECULAR = Array( 0.5f, 0.5f, 0.8f, 1.0f ) | |
val MDIFFUSE = Array( 0.5f, 0.5f, 0.8f, 1.0f ) | |
val MAMBIENT = Array( 0.8f, 0.8f, 1.0f, 1.0f ) | |
val MSHININESS = 10.0f | |
def base = { | |
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); | |
gl.glEnable(GL.GL_DEPTH_TEST); | |
gl.glEnable(GL.GL_CULL_FACE); | |
gl.glEnable(GL.GL_LIGHTING); | |
gl.glEnable(GL.GL_LIGHT0); | |
gl.glEnable(GL.GL_NORMALIZE); | |
} | |
def lighting = { | |
gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, LPOSITION, 0); | |
gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, LSPECULAR, 0); | |
gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, LDIFFUSE, 0); | |
gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, LAMBIENT, 0); | |
} | |
def refrection = { | |
gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, MSPECULAR, 0); | |
gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, MDIFFUSE, 0); | |
gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, MAMBIENT, 0); | |
gl.glMaterialf(GL.GL_FRONT, GL.GL_SHININESS, MSHININESS); | |
} | |
def configurate = { | |
base | |
lighting | |
refrection | |
} | |
def viewport(width:Int,height:Int) = { | |
val ratio:Float = height.toFloat / width.toFloat; | |
gl.glViewport(0, 0, width, height) | |
gl.glMatrixMode(GL.GL_PROJECTION) | |
gl.glLoadIdentity | |
gl.glFrustum(-1.0f, 1.0f, -ratio, ratio, 5.0f, 40.0f) | |
gl.glMatrixMode(GL.GL_MODELVIEW); | |
gl.glLoadIdentity | |
gl.glTranslatef(0.0f, 0.0f, -30.0f) | |
} | |
} | |
trait SimpleSprite{ | |
var gl:GL = _ | |
def setGL(gl:GL) = this.gl = gl | |
def rotateX(dx:Int) { | |
//gl.glPushMatrix(); | |
gl.glRotatef(dx, 1.0f, 0.0f, 0.0f) | |
//gl.glPopMatrix(); | |
} | |
def rotateY(dy:Int) = gl.glRotatef(dy, 0.0f, 1.0f, 0.0f) | |
def rotateZ(dz:Int) = gl.glRotatef(dz, 0.0f, 0.0f, 1.0f) | |
def moveX(dx:Int)={} | |
def moveY(dy:Int)={} | |
def moveZ(dz:Int)={} | |
def rotateXTo(px:Int) { | |
gl.glPushMatrix(); | |
gl.glRotatef(px, 1.0f, 0.0f, 0.0f) | |
gl.glPopMatrix(); | |
} | |
def rotateYTo(py:Int) = gl.glRotatef(py, 0.0f, 1.0f, 0.0f) | |
def rotateZTo(pz:Int) = gl.glRotatef(pz, 0.0f, 0.0f, 1.0f) | |
def moveXTo(px:Int)={} | |
def moveYTo(py:Int)={} | |
def moveZTo(pz:Int)={} | |
def update() | |
val glut:GLUT = new GLUT | |
def getGLUT:GLUT = glut | |
} | |
class World extends GLEventListener { | |
implicit def config(gl:GL) = new WorldConfig(gl) | |
var items:Queue[SimpleSprite] = new Queue | |
var gl:GL = _ | |
def addItem(item:SimpleSprite) = items += item | |
override def init(drawable:GLAutoDrawable) { | |
gl = drawable.getGL | |
items.foreach{ _.setGL(this.gl) } | |
gl.configurate | |
} | |
override def reshape( drawable:GLAutoDrawable, | |
x:Int, y:Int, width:Int, height:Int) { | |
// called on windowsize changed. | |
gl.viewport(width,height) | |
} | |
override def display(drawable:GLAutoDrawable) { | |
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); | |
items.foreach{ _.update } | |
} | |
override def displayChanged( drawable:GLAutoDrawable , | |
modeChanged:boolean , deviceChanged:boolean ) { | |
} | |
} | |
class WorldFrame extends JFrame { | |
val canvas:GLCanvas = new GLCanvas | |
val world:World = new World | |
val animator:Animator = new Animator(canvas) | |
canvas.addGLEventListener(world) | |
add(canvas) | |
setSize(500, 500) | |
addWindowListener(new WindowAdapter{ | |
override def windowClosing( e:WindowEvent ){ | |
animator.stop | |
System.exit(0) | |
} | |
}) | |
def addItem(item:SimpleSprite) = world.addItem(item) | |
def start = { | |
animator.start // repeat GLEventListener.display | |
this.setVisible(true) | |
} | |
} | |
/****************************** | |
Sample | |
*******************************/ | |
class TeaPot(size:Double) extends SimpleSprite { | |
override def update(){ | |
rotateZ(-1) | |
rotateX(-1) | |
getGLUT.glutSolidTeapot(size) | |
} | |
} | |
object JOGLDemo extends WorldFrame { | |
def main(args: Array[String]){ | |
addItem(new TeaPot(3.0d) ) | |
addItem(new TeaPot(2.0d) ) | |
addItem(new TeaPot(1.0d) ) | |
start | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment