# Erster Versuch mit JPCT



## Quaxli (6. Jul 2007)

Angeregt durch das JPCT-Tutorial habe ich mir das Ganze runter geladen und einen erste Schritt versucht. Aber obwohl die Beispiele bei mir problemlos laufen, ist es mit meinem eigenen Versuch leider nicht weit her.

Ich habe das Beispiel von der JPCT-Seite etwas angepaßt, um den getGraphics()-Aufruf zu vermeiden. Das Problem ist, daß in meinem Fenster nix zu sehen ist und das Ganze flackert wie die S...

Evtl. hat jemand von Euch Zeit, mal kurz auf meinen Code zu schauen. Ich hoffe es ist nur ein Kleinigkeit, die fehlt. Ich wollte nur als ersten Versuch eine Box mal in eine ansonsten leere Welt stellen. Hier ist der Code:


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

import java.io.*;
import java.net.URL;
import java.awt.*;
import java.awt.image.BufferStrategy;

import javax.swing.JFrame;


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(){
	  Config.maxPolysVisible = 10000;
	  
	  world  = new World();
    Config.fadeoutLight=false;
    world.getLights().setOverbrightLighting(Lights.OVERBRIGHT_LIGHTING_DISABLED);
	  world.getLights().setRGBScale(Lights.RGB_SCALE_2X);
	  world.setAmbientLight(25,30,30);
	  
    world.addLight(new SimpleVector(0, -150, 0), 25, 22, 19);
    world.addLight(new SimpleVector(-1000, -150, 1000), 22, 5, 4);
    world.addLight(new SimpleVector(1000, -150, -1000), 4, 2, 22);
    
    
    world.setFogging(World.FOGGING_ENABLED);
    world.setFogParameters(1200f,0f,0f,0f);
    
	  Config.farPlane = 1200;
	  Config.tuneForOutdoor();
    
	  texman = TextureManager.getInstance();
    Texture spot=new Texture(getClass().getClassLoader().getResourceAsStream("textures/spot.jpg"),false);
    TextureManager.getInstance().addTexture("car", spot);
    
	  box = Primitives.getBox(8f,0.25f);
	  box.translate(5f, 5f, 5f);
	  box.setTexture("car");
	  box.build();
	  world.addObject(box);
	  
    camera= world.getCamera();
    camera.setPosition(0,-2500,-1500);
    camera.lookAt(box.getTransformedCenter());

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

    loop();    
	  
	}
	
	private void loop(){
		
		World.setDefaultThread(Thread.currentThread());
		buffer = new FrameBuffer(800,600,FrameBuffer.SAMPLINGMODE_NORMAL);
		buffer.enableRenderer(IRenderer.RENDERER_SOFTWARE);
		buffer.setBoundingBoxMode(FrameBuffer.BOUNDINGBOX_NOT_USED);
		buffer.optimizeBufferAccess();
	
		
		while(running){
	    
			buffer.clear();
	    world.renderScene(buffer);		
	    world.draw(buffer);
	    buffer.update();
	    
			repaint();
			Thread.yield();
			
			try {
				Thread.sleep(20);
			} catch (InterruptedException e) {
				System.out.println(e);
			}
			
		}
	}

	public void paint(Graphics g) {
		super.paint(g);
    g.drawImage(buffer.getOutputBuffer(), 0, 0, this);
	}
	

	
	
}
```


----------



## Quaxli (6. Jul 2007)

Jaaa! Kaum macht man 2 Stunden rum....
Alles ist mir noch nicht klar, aber immerhin sieht man was. Der Bösewicht war der repaint-Aufruf.  :? 
Leider habe ich es nicht hinbekommen, ohne getGraphics() aufzurufen.  :bahnhof: 
Falls jemand einen besseren Vorschlag hatte, bitte posten. Ansonsten für die, die es interessiert, hier mal der Code (etwas modifiziert und kommentiert):


```
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
	  
	  //Textur abholen - liegen bei mir im Verzeichnis der Class-Dateien im Unterordner "textures"
	  texman = TextureManager.getInstance();
    Texture spot=new Texture(getClass().getClassLoader().getResourceAsStream("textures/spot.jpg"),false);
    TextureManager.getInstance().addTexture("car", spot);
    
    //Box erzeugen
	  box = Primitives.getBox(8f,1f);
	  box.setTexture("car");  //den Texture-Quatsch könnte man Anfang weglassen - sieht aber langweilig aus

	  //	Textur als Umgebungs-Map. Noch keine so rechte Ahnung was gemeint ist, sieht aber gut aus ;9
	  box.setEnvmapped(Object3D.ENVMAP_ENABLED); 
	  box.build(); //Box initializieren - kann weggelassen werden, wenn world.builtAllObjects() aufgerufen wird
	  
	  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); //alles was notwendig ist, um das Zeichnen zu beginnen	
	    world.draw(buffer); //zeichne in den Buffer
	    buffer.update(); //gewährleistet, daß alle Änderungen übernommen werden. Update des Output-Buffers
	    
	    //Jetzt wird gezeichnet - ohne getGraphics hab' ich es nicht gebacken bekommen :(
	    //mit repaint hat das Ganze nicht funktioniert :(
	    getGraphics().drawImage(buffer.getOutputBuffer(), 0, 0, this); 
			Thread.yield();
			
			try {
				Thread.sleep(20);
			} catch (InterruptedException e) {
				System.out.println(e);
			}
			
		}
	}
	
}
```


----------



## EgonOlsen (6. Jul 2007)

Du rufst niemals FrameBuffer.display(...) auf. Das führt dazu, dass jPCT das alles für einen gewaltigen Frame hält und das ist im Hinblick auf einige Internas keine so gute Idee. Du solltest den drawImage()-Aufruf besser ersetzen durch z.B. buffer.display(getGraphics());
Ich werde aber dieses Verhalten für die nächste Version anpassen, so dass ein Aufruf von update() ebenfalls reicht, um einen vollständigen Frame zu markieren.


----------



## Quaxli (6. Jul 2007)

O.k., werde ich besser. 
(Schöner wäre es aber, wenn man auf getGraphics() verzichten könnte.)
Danke für den Tipp.


----------



## EgonOlsen (6. Jul 2007)

Das Flackern kommt schlicht und einfach vom Standardverhalten von paint() bzw. update(). Das musst du überschreiben,  wenn du direkt in den Frame malen willst. Also z.B. so:


```
public void update(Graphics g) {
       paint(g);   
   }

   public void paint(Graphics g) {
       if (buffer!=null) {
           buffer.display(g);
       }
   }
```

Aber damit zeigst du dann nicht zwingend jedes Bild an, bzw. manches vielleicht ein paar mal. Man kann nicht oft genug betonen, dass repaint() weder update() noch paint() direkt aufruft. Es äußert nur den Wunsch nach Neuzeichnen...wann das passiert, steht in den Sternen des AWT-Event-Dispatcher-Threads. Für Spiele, die direkt in einen Frame zeichnen, finde ich das nicht unbedingt sinnvoll.


----------



## Xams (8. Jul 2007)

Füg mal in deinen Code
box.setSpecularLighting(true);
ein. 
Das hat zwar nichts mit deinem Problem zu tun, ist aber dennoch intressant.


----------

