# Demo Programme bei verschiedenen Engines



## Xams (28. Aug 2007)

Eine kleine Demo Sammlung. Vielleicht erleichtert das Einsteigern die Wahl.
Alle Programme zeigen einen Würfel.

JPCT (Von Quaxil, mit ein paar Verbesserungen von mir)

```
import com.threed.jpct.*; 
import java.awt.*; 

public class Test1 extends Frame{ 

   private static final long   serialVersionUID   = 1L; 
    
   private World world; 
   private Camera camera; 
   private FrameBuffer buffer; 
   boolean running = true; 
   Object3D box; 
   TextureManager texman; 

   public static void main(String[] args){ 
      new Test1(); 
   } 
    
   public Test1(){ 

      //Engine konfigurieren 
      Config.maxPolysVisible = 10000;  //max. sichtbare Polygone 
      
     world  = new World();  // Hauptklasse instanziieren 
     world.setAmbientLight(0,255,0); //grünes Umgebungslicht 
      
     texman = TextureManager.getInstance(); 
    Texture spot=new Texture(getClass().getClassLoader().getResourceAsStream("textures/envmap.jpg"),false); 
    TextureManager.getInstance().addTexture("car", spot); 
    
    //Box erzeugen 
     box = Primitives.getBox(8f,1f); 
     box.setTexture("car"); 
     box.setSpecularLighting(true); 
     //   Textur als Umgebungs-Map. Noch keine so rechte Ahnung was gemeint ist, sieht 
     box.setEnvmapped(Object3D.ENVMAP_ENABLED); 
     box.build();      
     world.addObject(box); //Box in die Welt packen 
      
    camera = world.getCamera(); //Kamera abholen 
    camera.setPosition(50,-50,-5); //Position verändern 
    camera.lookAt(box.getTransformedCenter()); //auf die Box gucken 

     //Frame erzeugen 
    setTitle("jPCT "+Config.getVersion()); 
    pack(); 
    setSize(800,600); 
    setResizable(false); 
    setVisible(true); 

    loop();    
      
   } 
    
   private void loop(){ 
        
      World.setDefaultThread(Thread.currentThread());  //JPCT-Funktionen werde aus diese Thread aufgerufen 
      buffer = new FrameBuffer(800,600,FrameBuffer.SAMPLINGMODE_NORMAL); //FrameBuffer zum Zeichnen 
      buffer.enableRenderer(IRenderer.RENDERER_SOFTWARE); //Renderer zuweisen 
      buffer.optimizeBufferAccess();//schnellst Buffer-Zugriff ermitteln 
    
        
      while(running){ 
        
         buffer.clear(); //no comment 
       world.renderScene(buffer); 
    //world.drawWireframe(buffer, Color.green); um im Wireframe zu zeichnen 
       world.draw(buffer); //zeichne in den Buffer 
       buffer.update(); //gewährleistet, daß alle Änderungen übernommen werden. Update des Output-Buffers 
          buffer.display(getGraphics()); 
         Thread.yield(); 
          
         try { 
            Thread.sleep(20); 
         } catch (InterruptedException e) { 
            System.out.println(e); 
         } 
          
      } 
   } 
    
}
```

Java 3D (von hoon):


```
import java.applet.Applet; 
import java.awt.BorderLayout; 
import java.awt.GraphicsConfiguration; 
import com.sun.j3d.utils.applet.MainFrame; 
import com.sun.j3d.utils.universe.SimpleUniverse; 
import com.sun.j3d.utils.geometry.ColorCube; 
import com.sun.j3d.utils.behaviors.mouse.MouseRotate; 
import javax.media.j3d.*; 

public class MySimpleUniverse extends Applet 
{ 
   // Inhaltszweig 
   public BranchGroup erzeugeInhalt() 
   { 
      // Erzeugen einer (Wurzel)Gruppe die den geamten Inhalt des Universum aufnehmen soll 
      BranchGroup inhalt = new BranchGroup(); 
       
      // Erzeugen eines geometrischen Objektes inklusive voreingestellten Aussehens 
      ColorCube farbigerWuerfel = new ColorCube(0.4); 

      // Erzeugen einer Transformgruppe mit Zugriffsrechten fuer Maussteuerung 
      TransformGroup tg = new TransformGroup(); 
      tg.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); 
      tg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); 
       
      // Gebe dem verwaisten Wuerfel drehfreudige Eltern 
      tg.addChild(farbigerWuerfel); 
       
      // Erzeuge ein Mausdrehobjekt in einem geplanten Bereich mit Ziel-Transformgruppe 
      MouseRotate rotor = new MouseRotate(); 
      rotor.setSchedulingBounds(new BoundingSphere()); 
      rotor.setTransformGroup(tg); 
       
      // Einhaengen der Transformgruppe und des Mausverhaltens in die Wurzelgruppe 
      inhalt.addChild(tg); 
      inhalt.addChild(rotor); 

      // Optimiert den gesamten Inhaltszweig - nicht unbedingt erforderlich 
      inhalt.compile(); 

      return inhalt; // Los, gibs mir! 
   } 
    
   // Sichtzweig 
   public SimpleUniverse erzeugeSicht() 
   { 
      // Erzeugen eines minimalen virtuellen Universums mit Hilfe der SimpleUniverse-Klasse 
      SimpleUniverse minimalesUniversum = null; 

      // Besorgen der besten Konfiguration hinsichtlich der 
      // Anzeigeumgebung (Farbtiefe, Tranzparenzwerte der Pixel, ...) 
      GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration(); 

      // Erzeugen des aeusserst schweren Anzeigeflaeche-Objektes 
      Canvas3D canvas3d = new Canvas3D(config); 

      // Hinzufügen der Anzeigeflaeche zum Clientbereich des Fensters 
      add(canvas3d); 

      // Uebergabe des Canvas3D-Objekts als Anzeigeflaeche 
      minimalesUniversum = new SimpleUniverse(canvas3d); 

      // setNominalViewingTransform() stellt den Betrachter 2,41m auf die positive 
      // z-Achse mit Sichtrichtung nach unten in negative z-Achse 
      minimalesUniversum.getViewingPlatform().setNominalViewingTransform(); 

      return minimalesUniversum; // Her mit dem Mist! 
   } 

   // Diese Methode wird vom Browser beim Laden des Applets aufgerufen. 
   public void init() 
   { 
      // Erzeuge neues Layout für Container 
      setLayout(new BorderLayout()); 

      // Sei Gott und erzeuge ein minimales Universum mit Sicht auf den Inhalt 
      SimpleUniverse su = erzeugeSicht(); 

      // Sei Gott und erzeuge den Inhalt des Universums mit Maussteuerung 
      BranchGroup suInhalt = erzeugeInhalt(); 

      // Es werde Licht! - verbindet Universum inklusive Sicht mit Inhalt 
      su.addBranchGraph(suInhalt); 
   } 

   // Startpunkt fuer die Laufzeitumgebung 
   public static void main(String[] args) 
   { 
      new MainFrame(new MySimpleUniverse(), 800, 600); 
   } 
}
```

Vielleicht kann noch jemand Demos für jMe und weitere ergänzen.
MFG


----------



## merlin2 (28. Aug 2007)

JOGL:


```
import java.awt.Color;
import java.awt.Frame;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class RotatingCube {
  static boolean animated = true;
  static int width = 800, height = 800;
  static String title = "A rotating cube";
  static Animator anim = null;
  static GLCanvas canvas;
  static Frame frame;
  static float rot = 1f;
  static boolean rotate = true;
  public static void main(String[] args) {
    frame = new Frame(title);
    canvas = new GLCanvas();
    if(animated) {anim = new Animator(canvas); anim. start();}
    addEventListener();
    frame.add(canvas);
    frame.setSize(width, height);
    frame.addWindowListener(new WindowAdapter() {
    public void windowClosing(WindowEvent e) {
      if(animated)anim.stop();
      System.exit(0);
    }});
    frame.setVisible(true);
  }
  public static void addEventListener() {
    canvas.addGLEventListener(new JOGLEventListener() {public void display(GLAutoDrawable gld) {GL gl = gld.getGL(); paint(gl);}});
    frame.addKeyListener(new KeyAdapter() {public void keyPressed(KeyEvent evt) {changeRot(evt);}});
    frame.addFocusListener(new FocusAdapter() {public void focusLost(FocusEvent evt) {frame.requestFocus();}});
  }
  public static void paint(GL gl) {
    gl.glEnable(GL.GL_DEPTH_TEST);
    gl.glClear(GL.GL_COLOR_BUFFER_BIT|GL.GL_DEPTH_BUFFER_BIT);
    gl.glTranslatef(-0.5f, -0.5f, 0f);
    if(rotate)gl.glRotatef(rot, 1f, 1f, 1f);
    Cube.createCube(gl, 0f, 0f, 0f, 1f, 1f, 1f, new Color[] {new Color(255, 0, 0), new Color(0, 255, 0), new Color(0, 0, 255), new Color(255, 0, 0), new Color(0, 255, 0), new Color(0, 0, 255),});
    gl.glTranslatef(0.5f, 0.5f, 0f);
  }
  public static void changeRot(KeyEvent evt) {
    switch(evt.getKeyCode()) {
      case KeyEvent.VK_F: rot += 0.1;
      break;
      case KeyEvent.VK_S: rot -= 0.1;
      break;
      case KeyEvent.VK_P: rotate = !rotate;
      break;
      case KeyEvent.VK_ESCAPE: System.exit(0);
      break;
      case KeyEvent.VK_O: System.out.println("Rotation: " + rot + "° pro Frame");
    }
  }
}

import java.awt.Color;
import javax.media.opengl.GL;

class Cube {
  public static void createCube (GL gl, float xPos, float yPos, float zPos, float length, float height, float depth, Color[] c) {
    String exception = "";
    boolean thrown = false;
    if(length < 0 || height < 0 || depth < 0) {
      exception += "Only positive float values allowed!";
      thrown = true;
    }
    if(c.length != 6) {
      exception += ((exception.equals("")) ? "" : "\n") + "Color[].length must be 6!";
      thrown = true;
    }
    if(thrown) {
      throw new IllegalArgumentException(exception);
    }

    gl.glBegin(GL.GL_QUADS);
    /*unten*/gl.glColor3f((float)c[0].getRed()/255, (float)c[0].getGreen()/255, (float)c[0].getBlue()/255);
    gl.glVertex3f(xPos, yPos, zPos);
    gl.glVertex3f(xPos+length, yPos, zPos);
    gl.glVertex3f(xPos+length, yPos, zPos+depth);
    gl.glVertex3f(xPos, yPos, zPos+depth);

    /*links*/gl.glColor3f((float)c[1].getRed()/255, (float)c[1].getGreen()/255, (float)c[1].getBlue()/255);
    gl.glVertex3f(xPos, yPos+height, zPos);
    gl.glVertex3f(xPos, yPos+height, zPos+depth);
    gl.glVertex3f(xPos, yPos, zPos+depth);
    gl.glVertex3f(xPos, yPos, zPos);

    /*vorne*/gl.glColor3f((float)c[2].getRed()/255, (float)c[2].getGreen()/255, (float)c[2].getBlue()/255);
    gl.glVertex3f(xPos, yPos, zPos);
    gl.glVertex3f(xPos+length, yPos, zPos);
    gl.glVertex3f(xPos+length, yPos+height, zPos);
    gl.glVertex3f(xPos, yPos+height, zPos);

    /*oben*/gl.glColor3f((float)c[3].getRed()/255, (float)c[3].getGreen()/255, (float)c[3].getBlue()/255);
    gl.glVertex3f(xPos, yPos+height, zPos);
    gl.glVertex3f(xPos+length, yPos+height, zPos);
    gl.glVertex3f(xPos+length, yPos+height, zPos+depth);
    gl.glVertex3f(xPos, yPos+height, zPos+depth);

    /*rechts*/gl.glColor3f((float)c[4].getRed()/255, (float)c[4].getGreen()/255, (float)c[4].getBlue()/255);
    gl.glVertex3f(xPos+length, yPos+height, zPos);
    gl.glVertex3f(xPos+length, yPos+height, zPos+depth);
    gl.glVertex3f(xPos+length, yPos, zPos+depth);
    gl.glVertex3f(xPos+length, yPos, zPos);

    /*hinten*/gl.glColor3f((float)c[5].getRed()/255, (float)c[5].getGreen()/255, (float)c[5].getBlue()/255);
    gl.glVertex3f(xPos, yPos, zPos+depth);
    gl.glVertex3f(xPos+length, yPos, zPos+depth);
    gl.glVertex3f(xPos+length, yPos+height, zPos+depth);
    gl.glVertex3f(xPos, yPos+height, zPos+depth);
    gl.glEnd();
  }
}

import javax.media.opengl.*;

class JOGLEventListener implements GLEventListener {
  public void init(GLAutoDrawable gld) {}
  public void reshape(GLAutoDrawable gld, int x, int y, int width, int height) {}
  public void displayChanged(GLAutoDrawable gld, boolean modeChanged, boolean deviceChanged) {}
  public void display(GLAutoDrawable gld) {}
}
```

Für Verbesserungsvorschläge bin ich offen.


----------



## Evil-Devil (29. Aug 2007)

LWJGL: zur Quelle

```
package com.evildevil.tutorials.java.lwjgl;

/* =============================================================================
 * Copyright 2005 by Benjamin "Evil-Devil" Behrendt
 * Website: [url]http://www.evil-devil.com[/url]
 * eMail:   [email]evil_devil@gmx.net[/email]
 * -----------------------------------------------------------------------------
 * About: This file shall illustrate the basic usage of the LWJGL API and uses
 * as example a ordinary spinning and scaling cube lighted up with three lights.  
 * -------------------------------------------------------------------------- */

// JAVA Importe
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.ByteOrder;

// LWJGL Importe
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.GL11;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.glu.GLU;
import org.lwjgl.opengl.OpenGLException;

public class JavaLWJGL {
	private String title = "Java LWJGL Tutorial";
	private DisplayMode displayMode = null;	// der gewählte Displaymode
	private boolean fullscreen = false;		// Vollbild oder Fenster?
	private float rotX = 0.0f;				// für rotation um die X Achse
	private float rotY = 0.0f;				// für rotation um die Y Achse
	private float rotZ = 0.0f;				// für rotation um die Z Achse
    private float scale = 1.0f;
    private boolean scaleUp = true;         // skalieren wir unser objekt größer oder kleiner?
    
    // Werte für die Lichter
    private float[] redDiffuse = { 1.0f, 0.0f, 0.0f, 1.0f };
    private float[] greenDiffuse = { 0.0f, 1.0f, 0.0f, 1.0f };
    private float[] blueDiffuse = { 0.0f, 0.0f, 1.0f, 1.0f };    
    
    private float[] posTopLeft = {-2.0f, 2.0f, 0.0f, 1.0f };
    private float[] posTopRight = {2.0f, 2.0f, 0.0f, 1.0f };
    private float[] posBottomFront = {0.0f, -2.0f, 1.0f, 1.0f };

	// =========================================================================
	//	Konstruktoren für die Erzeugung der Class
	// -------------------------------------------------------------------------
	public JavaLWJGL() {
	}

	public JavaLWJGL(String title) {
		this.title = title;
	}

	// =========================================================================
	//	OpenGL, Initalisierungs und Render Funktionen
	// -------------------------------------------------------------------------
	public void init() {
		// initialisierung des Fensters
		initWindow();
		// initialisierung des Keyboards
		initKeyboard();
		// initialisierung von OGL
		initOpenGL();
		// scene neu skalieren
		reSizeGLScene(displayMode.getWidth(),displayMode.getHeight());
        initLight();
		// ab zur Hauptschleife        
		run();
	}

	//Erzeugung des Fensters	 
	private void initWindow() {
		try {
			displayMode = org.lwjgl.util.Display.getAvailableDisplayModes(
                                800,600,800,600,32,32,60,60)[0];
			Display.setDisplayMode(displayMode);
			Display.setFullscreen(fullscreen);
			Display.create();		// das Display erzeugen
			Display.setTitle(title);
		} catch (LWJGLException e) {
			e.printStackTrace();	// Exception ausgeben
		}
	}

    // Erzeugung der Tastatur
    private void initKeyboard() {
		try {
			if (!Keyboard.isCreated())
				Keyboard.create();		// Keyboard erzeugen
		} catch (LWJGLException e) {
			e.printStackTrace();	    // Exception ausgeben
		}
	}
    
    // Initialisierung von OpenGL
	private void initOpenGL() {
		GL11.glShadeModel(GL11.GL_SMOOTH);
		GL11.glClearColor(0.0f,0.0f,0.0f,0.0f);		// schwarzer Hintergrund
		GL11.glClearDepth(1.0f);					// Tiefe von 0 bis 1
		GL11.glEnable(GL11.GL_DEPTH_TEST);			// Tiefen Test aktivieren
		GL11.glDepthFunc(GL11.GL_LEQUAL);
		GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT,GL11.GL_NICEST);
	}
    
    // Erzeugung des Lichtes
    public void initLight() {        
        GL11.glLight(GL11.GL_LIGHT0,GL11.GL_DIFFUSE,arrayToBuffer(redDiffuse));
        GL11.glLight(GL11.GL_LIGHT0,GL11.GL_POSITION,arrayToBuffer(posTopLeft));
        
        GL11.glLight(GL11.GL_LIGHT1,GL11.GL_DIFFUSE,arrayToBuffer(greenDiffuse));
        GL11.glLight(GL11.GL_LIGHT1,GL11.GL_POSITION,arrayToBuffer(posTopRight));
        
        GL11.glLight(GL11.GL_LIGHT2,GL11.GL_DIFFUSE,arrayToBuffer(blueDiffuse));
        GL11.glLight(GL11.GL_LIGHT2,GL11.GL_POSITION,arrayToBuffer(posBottomFront));
        
        GL11.glEnable(GL11.GL_LIGHT0);
        GL11.glEnable(GL11.GL_LIGHT1);
        GL11.glEnable(GL11.GL_LIGHT2);
        GL11.glEnable(GL11.GL_LIGHTING);
    }

    // Resize Methode
	private void reSizeGLScene(int width, int height) {
		if (height == 0)
			height = 1;

        GL11.glViewport(0,0,width,height);                  // aktuellen viewport zurücksetzen
        GL11.glMatrixMode(GL11.GL_PROJECTION);              // Projection Matrix (PM) auswählen
        GL11.glLoadIdentity();                              // PM zurücksetzen
        GLU.gluPerspective(45.0f,(float)width/(float)height,0.1f,100.0f);   // 45° Perspektive
        GL11.glMatrixMode(GL11.GL_MODELVIEW);               // ModelView Matrix (MVM) auswählen
        GL11.glLoadIdentity();                              // MVM zurücksetzen
	}
    
    // rendern unsere Scene
	private void renderGLScene() {
		GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
        GL11.glLoadIdentity();
        GL11.glTranslatef(0.0f,0.0f,-5.0f);      
        GL11.glRotatef(rotX,1.0f,0.0f,0.0f);
        GL11.glRotatef(rotY,0.0f,1.0f,0.0f);
        GL11.glRotatef(rotZ,0.0f,0.0f,1.0f);        
        GL11.glScalef(scale,scale,scale);        
        // Der Würfel aller Würfel ^__^'
        GL11.glBegin(GL11.GL_QUADS);            
            // Front Side
            GL11.glNormal3f(0.0f,0.0f,1.0f);
            GL11.glVertex3f(-1.0f,-1.0f,1.0f);
            GL11.glVertex3f(1.0f,-1.0f,1.0f);
            GL11.glVertex3f(1.0f,1.0f,1.0f);
            GL11.glVertex3f(-1.0f,1.0f,1.0f);
            // Back Side
            GL11.glNormal3f(0.0f,0.0f,-1.0f);
            GL11.glVertex3f(1.0f,-1.0f,-1.0f);
            GL11.glVertex3f(-1.0f,-1.0f,-1.0f);
            GL11.glVertex3f(-1.0f,1.0f,-1.0f);
            GL11.glVertex3f(1.0f,1.0f,-1.0f);                                    
            // Left Side
            GL11.glNormal3f(-1.0f,0.0f,0.0f);
            GL11.glVertex3f(-1.0f,-1.0f,-1.0f);
            GL11.glVertex3f(-1.0f,-1.0f,1.0f);
            GL11.glVertex3f(-1.0f,1.0f,1.0f);
            GL11.glVertex3f(-1.0f,1.0f,-1.0f);
            // Right Side
            GL11.glNormal3f(1.0f,0.0f,0.0f);
            GL11.glVertex3f(1.0f,-1.0f,1.0f);
            GL11.glVertex3f(1.0f,-1.0f,-1.0f);
            GL11.glVertex3f(1.0f,1.0f,-1.0f);
            GL11.glVertex3f(1.0f,1.0f,1.0f);            
            // Top Side
            GL11.glNormal3f(0.0f,1.0f,0.0f);
            GL11.glVertex3f(-1.0f,1.0f,1.0f);
            GL11.glVertex3f(1.0f,1.0f,1.0f);
            GL11.glVertex3f(1.0f,1.0f,-1.0f);
            GL11.glVertex3f(-1.0f,1.0f,-1.0f);
            // Bottom Side
            GL11.glNormal3f(0.0f,-1.0f,0.0f);
            GL11.glVertex3f(1.0f,-1.0f,-1.0f);
            GL11.glVertex3f(-1.0f,-1.0f,-1.0f);
            GL11.glVertex3f(-1.0f,-1.0f,1.0f);
            GL11.glVertex3f(1.0f,-1.0f,1.0f);            
        GL11.glEnd();        
        
        if (rotX < 360)
            rotX += 0.2f;
        else rotX = 0.0f;
        
        if (rotY < 360)
            rotY += 0.3f;
        else rotY = 0.0f;
        
        if (rotZ < 360)
            rotZ += 0.1f;
        else rotZ = 0.0f;
        
        if (scale >= 1.5f)
            scaleUp = false;
        else if (scale <= 0.25f)
            scaleUp = true;
        
        if (scaleUp)
            scale += 0.0005f;
        else scale -= 0.0005f;
	}

	// =========================================================================
	//	alles was man zum Beenden/Zerstören braucht ;)
	// -------------------------------------------------------------------------
	private void cleanup() {
		destroyWindow();      // display zerstören
		System.exit(0);       // Beenden des Programms
	}

	private void destroyWindow() {
		if (Display.isCreated())
			Display.destroy();		// Display zerstören
	}

	// =========================================================================
	//	Sonstiges und Handling Funktionen
	// -------------------------------------------------------------------------
	public void setFullscreen(boolean fullscreen) {
		this.fullscreen = fullscreen;
	}
    
    private void switchFullscreen() {        
        try {
            Display.setFullscreen(!this.fullscreen);
        } catch (LWJGLException e) {
            e.printStackTrace();
        }
        setFullscreen(!this.fullscreen);
    }

	private void checkKeyboardInput() {
		if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE))
			cleanup();
        
        if (Keyboard.isKeyDown(Keyboard.KEY_F1))
            switchFullscreen();
	}
    
    /* =========================================================================
     * wandelt ein float array in einen direkt allozierten FloatBuffer um, der 
     * seine byte daten in nativer Reihenfolge gespeichert hat.
     * Für nähere Infos einfach in der Java Doku unter NIO und den Unterschied
     * zwischen direkten und indirekten Buffern schauen ;) 
     * ---------------------------------------------------------------------- */
    private FloatBuffer arrayToBuffer(float data[]) {
        FloatBuffer buffer = ByteBuffer.allocateDirect(data.length * 4).order(
                                ByteOrder.nativeOrder()).asFloatBuffer();        
        buffer.clear();
        buffer.put(data);
        buffer.rewind();
        return buffer;
    }

	// =========================================================================
	//	Unsere Hauptschleife wo alles nach der Initialisierung stattfindet
	// -------------------------------------------------------------------------
	private void run() {
		while (true) {
			if (Display.isCloseRequested()) {
                cleanup();
                break;
            }
            if (Display.isVisible() || Display.isDirty()) {
                try {
                    renderGLScene();		// zeichnen der überagenden Scene...
                    Display.update();		// Display updaten ^__^
                } catch (OpenGLException e) {
	                e.printStackTrace();
                }                
            }
            checkKeyboardInput();           // Keyboard Eingaben abfangen
		}
	}

	// =========================================================================
	//	Main function :)
	// -------------------------------------------------------------------------
	public static void main(String[] args) {
		JavaLWJGL jlwjgl = new JavaLWJGL();	// neue Instanz der Klasse erzeugen
        
        /* =====================================================================
		 * sofern ein Argument übergeben wurde und dieses auch
         * noch "fullscreen" heisst, dann soll das Programm
         * im Fullscreen Mode starten
         * ------------------------------------------------------------------ */
		if (args.length > 0) {
			for (int i=0; i<args.length; i++) {
				if (args[i].equalsIgnoreCase("fullscreen")) {
					jlwjgl.setFullscreen(true);
					break;
				}
			}
		}
		jlwjgl.init();		// init aufrufen und alles nimmt seinen Lauf
	}
}
```


----------



## Xams (29. Aug 2007)

Oh Mann 301 Zeilen für nen dummen Würfel. Da bleib ich doch lieber bei jPCT...


----------



## merlin2 (29. Aug 2007)

Die Java3D-Lösung ist, soweit ich das sehe, kürzer.
Zähl mal Kommentar-/Leerzeilen.
Ich bleib bei Java3D.


----------



## EgonOlsen (29. Aug 2007)

Und ich dachte immer, länger wäre besser... :wink: 
Obiges jPCT-Beispiel für den OpenGL-Renderer angepasst:


```
package tests;

import com.threed.jpct.*;

public class CubeTest {

	private World world;
	private FrameBuffer buffer;
	private Object3D box;
	private TextureManager texman;

	public static void main(String[] args) throws Exception {
		new CubeTest().loop();
	}

	public CubeTest() throws Exception {
		world = new World();
		world.setAmbientLight(0, 255, 0);

		texman = TextureManager.getInstance();
		TextureManager.getInstance().addTexture("car", new Texture(getClass().getClassLoader().getResourceAsStream("textures/envmap.jpg"), false));

		box = Primitives.getBox(8f, 1f);
		box.setTexture("car");
		box.setEnvmapped(Object3D.ENVMAP_ENABLED);
		box.build();
		world.addObject(box);

		world.getCamera().setPosition(50, -50, -5);
		world.getCamera().lookAt(box.getTransformedCenter());
	}

	private void loop() throws Exception {
		buffer = new FrameBuffer(800, 600, FrameBuffer.SAMPLINGMODE_NORMAL);
		buffer.disableRenderer(IRenderer.RENDERER_SOFTWARE);
		buffer.enableRenderer(IRenderer.RENDERER_OPENGL);

		while (!org.lwjgl.opengl.Display.isCloseRequested()) {
			box.rotateY(0.01f);
			buffer.clear(java.awt.Color.BLUE);
			world.renderScene(buffer);
			world.draw(buffer);
			buffer.update();
			buffer.displayGLOnly();
			Thread.sleep(20);
		}
		buffer.disableRenderer(IRenderer.RENDERER_OPENGL);
		buffer.dispose();
	}
}
```


----------



## Xams (30. Aug 2007)

merlin2 hat gesagt.:
			
		

> Die Java3D-Lösung ist, soweit ich das sehe, kürzer.
> Zähl mal Kommentar-/Leerzeilen.
> Ich bleib bei Java3D.


Ich hab nicht gesagt, dass jPCT kürzer ist, als Java3D, es ist aber wenigstens kürzer als LWJGL... 
Ausserdem will ich nicht wegen 10 Zeilen Code weniger, ne neue 3D-Engine lernen :wink:


----------



## merlin2 (30. Aug 2007)

13.


----------



## Quaxli (30. Aug 2007)

> JPCT (Von Quaxil, mit ein paar Verbesserungen von mir)




Kaufst Du Dir auch einen Rembrandt und pinselst noch dran rum?  :wink:


----------



## Quaxli (30. Aug 2007)

Einen Würfel in ein Universum zu packen sagt halt noch nicht so viel über die Engine aus. Ich fand z. B. Java3D sehr viel abstrakter vom Verständnis als andere Engines, mit denen ich rumgespielt habe. Das kann aber durchaus auch an mir liegen 

Ich persönlich würde ja zu JPCT tendieren, nachdem ich jetzt eine Weile mit verschiedenen Engines rumgespielt habe. 
Ich muß aber schon sagen, daß ich es etwas als Manko empfinde, daß es dafür kein Einsteiger-Tutorial gibt. Das würde den Zeitaufwand sehr erleichtern - gerade für Neueinsteiger in die 3D Welt (ich zum Beispiel).
Klar kann man es auch aus den Beispielen rausfrickeln - habe ich ja schließlich für das Beispiel gemacht. Aber das ist halt sehr zeitaufwändig.


----------



## merlin2 (30. Aug 2007)

Mich stört an der Organisation von JPCT z. B. das folgende Stück Code:

```
world.setAmbientLight(0,255,0);
```
In J3D ist ein Licht etwas, das man als Kindknoten hinzufügt, nicht setzt.


Übrigens könnte man das

```
private static final long   serialVersionUID   = 1L;
```
im JPCT-Code entfernen, eine Serialisation tritt ja nicht auf.

Und Quaxli hat es als Autor des ursprünglichen Codes wohl verdient, dass der Schreibfehler in seinem Namen korrigiert wird.


----------



## EgonOlsen (30. Aug 2007)

merlin2 hat gesagt.:
			
		

> In J3D ist ein Licht etwas, das man als Kindknoten hinzufügt, nicht setzt.


Weil es eben vollständig als Graph organisiert ist. Das muss man mögen, ich mag's nicht. Ich habe nie verstanden, was das Licht im Graphen verloren hat, aber das ist eben Ansichtssache.


----------



## merlin2 (30. Aug 2007)

Und warum gibt man setAmbient() dann int-Werte und kein Objekt, dass eine Farbe repräsentiert?


----------



## EgonOlsen (30. Aug 2007)

merlin2 hat gesagt.:
			
		

> Und warum gibt man setAmbient() dann int-Werte und kein Objekt, dass eine Farbe repräsentiert?


Weil ich das an dieser Stelle für überflüssig halte. Es gibt ein paar Methoden fürs Licht, die nehmen Color entgegen. Für das Umgebungslicht geht das aber nicht, weil es durchaus >255 sein kann (und wenn man den Software-Renderer im Legacy-Modus benutzt, dann kann es auch negativ sein). Also hätte ich quasi ein Color-Objekt ohne die Beschränkung auf 0-255 bauen müssen. Wozu? Um sagen zu können: Wie cool, ein Objekt? 
Um manche Dinge bei jPCT zu verstehen, muss man die Historie betrachten. Es war ursprünglich für Applets gebaut, die über Modem geladen wurden. Entsprechend musste es klein sein (was es ja bis heute noch ist). Ziel damals war, unter 100KB zu bleiben. Und jedes zusätzliche Objekt, das nicht nötig war, hätte das nur aufgeblasen.
Ich würde heute auch manches anders bauen an dem Teil, aber einen konkreten Anlass für solche Änderungen gibt es nicht (außer dem Gefühl, dass dann alles "schöner" wäre). Es gibt schon so viele "schöne" APIs, die niemand benutzen kann, weil sie zu verkopft gebaut sind und sich bei jedem Update ändern (ist jetzt nicht auf J3D bezogen, sondern so ganz allgemein). Ich würde niemals sagen, dass bei jPCT alles eitel Sonnenschein ist. Das Erzeugen neuer Lichtquellen ist z.B. Grütze, weswegen es eine aufgesetzte Hilfsklasse dafür in util gibt. Die ganze Config-Kiste ist fragwürdig...sie war nett für ein paar Werte, aber es ist irgendwie außer Kontrolle geraten... :wink: Aber was soll's? Was mit einer Zeile Code geht, dass habe ich mit einer Zeile gemacht. Dazu gehört z.B. das Setzen der Lichtquellen aber auch Kollisionsberechnung, projezierte Texturen usw. Man kann viel mit machen, aber man muss nicht...


----------



## merlin2 (30. Aug 2007)

Das mit dem > 255 wussste ich nicht.
Aber da bleibe ich doch lieber beim stärker mit Objekten arbeitenden J3D.


----------



## EgonOlsen (30. Aug 2007)

merlin2 hat gesagt.:
			
		

> Aber da bleibe ich doch lieber beim stärker mit Objekten arbeitenden J3D.


Niemand will dich davon abbringen, ich am allerwenigsten. Deswegen gibt es ja die Auswahl, damit sich jeder das raussuchen kann, was ihm besser liegt oder was besser für den geplanten Anwendungsfall geeignet ist.


----------



## Xams (31. Aug 2007)

Quaxli hat gesagt.:
			
		

> > JPCT (Von Quaxil, mit ein paar Verbesserungen von mir)
> 
> 
> 
> ...


   Immer doch, wenn du ihn mir bezahlst  :bae: 
Ich hab auch nur dein getGraphics.drawImage(buffer)
durch buffer.display(getGraphics()) ersetzt...

Schön das du dich mit Rembrand vergleichst... :bae:


----------



## merlin2 (31. Aug 2007)

Xams hat gesagt.:
			
		

> Schön das du dich mit Rembrand vergleichst... :bae:


Er weiß wenigstens, wie man ihn schreibt. :bae:
(*SCNR*)


----------



## Xams (4. Sep 2007)

Huch hab ich wohl das T vergessen...


----------



## Evil-Devil (4. Sep 2007)

Xams hat gesagt.:
			
		

> Oh Mann 301 Zeilen für nen dummen Würfel. Da bleib ich doch lieber bei jPCT...


LWJGL ist auch keine Engine, es ist ein Framwork das zur grafischen Darstellung OpenGl nutzt (zukünftig auch Direct3D).
Alles was ich da getan hab, müsste man in C/C++ und anderen Sprachen die eine OpenGL Anbindung haben ebenfalls schreiben, zusätzlich je nach Sprache und Bibliothek noch das Fenstermanagement. Allein das hat unter Windows schon gut 120 Zeilen. Nur um ein GDI Fenster erzeugen und schließen zu können.

Das Beispiel selbst könnte man noch um einige Zeilen kürzen, aber es soll für den Leser des Tutorials leicht verständlich sein und das ist es nicht, wenn mal alles verkryptet. Zumal es nun auch schon an die 2 Jahre alt ist...

Generell greift eine Engine nur auf die Funktionen von JOGL/LWJGL zu und kümmert sich entsprechend um die Darstellung. WIrklich anders läuft es bei jPCT auch nicht ab


----------



## Xams nA (8. Sep 2007)

Jo ich weiß, dennoch bin ich froh das jPCt mir das Leben etwas einfacher macht... 
Nochmal zu der Aussage von Quaxli, dass die Darstellung von nem Würfel nicht viel über die Engine aussagt.
Das stimmt schon, aber man sieht zumindest, welche unterschiedlichen Konzepte sie haben.
Wie z.B das jPCT weniger stark mit Objekten arbeitet. Das ist alles Geschmackssache ich bin jPCT prinzipiel zufrieden.


----------

