# LWJGL Problem mit Erstellen eines Objekts und der Kamera



## florilu (6. Dez 2012)

Hi, ich bin gerade ein wenig verwirrt, da ich am versuchen bin einen Würfel (Ja bin immer noch bei meinen Würfeln, da ich vorhabe ein Spiel damit zu machen) an der Koordinate der Kamera zu erstellen wenn ich C drücke, um zu sehen ob es auch dort "generiert" wird wo ich will.

Also wenn ich C drücke sieht es so aus:






Aber eigentlich sollte ja nur einer erstellt werden, genau an der Position wo die Kamera ist, und nicht ne ganze Linie davon.
Hier der verantwortliche Code:

Main:

```
import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.glClear;
import static org.lwjgl.opengl.GL11.glLoadIdentity;
import static org.lwjgl.opengl.GL11.glPopMatrix;
import static org.lwjgl.opengl.GL11.glPushMatrix;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Random;

import javax.imageio.ImageIO;

import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;

public class Main
{
	private static List<Cube> shapes = new ArrayList<Cube>(1);
	
	public static float xcoords = Camera.x;
	public static float ycoords = Camera.y;
	public static float zcoords = Camera.z;
	
	public static void main(String[] args){
		
		initDisplay();
		
		gameLoop();
		cleanUp();
	}
	
	@SuppressWarnings({ "unused" })
	public static void gameLoop(){
		
		Camera cam = new Camera(70, (float)Display.getWidth()/(float)Display.getHeight(), 0.3f, 1000);
		
		float x = 0;
		
		while(!Display.isCloseRequested()){
			
			if(Keyboard.isKeyDown(Keyboard.KEY_W)){
				cam.move(0.01f, 1);
			}if(Keyboard.isKeyDown(Keyboard.KEY_S)){
				cam.move(-0.01f, 1);
			}if(Keyboard.isKeyDown(Keyboard.KEY_SPACE)){
				cam.moveUpDown(-0.01f);
			}if(Keyboard.isKeyDown(Keyboard.KEY_UP)){
				cam.rotateX(-0.01f);
			}if(Keyboard.isKeyDown(Keyboard.KEY_DOWN)){
				cam.rotateX(0.01f);
			}if(Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)){
				cam.moveUpDown(0.01f);
			}if(Keyboard.isKeyDown(Keyboard.KEY_A)){
				//cam.rotateY(-0.1f);
				cam.rotateY(-0.01f);
			}if(Keyboard.isKeyDown(Keyboard.KEY_D)){
				//cam.rotateY(0.1f);
				cam.rotateY(0.01f);
			}if(Keyboard.isKeyDown(Keyboard.KEY_C)){
				shapes.add(new Cube(xcoords, ycoords, zcoords));
			}if(Keyboard.isKeyDown(Keyboard.KEY_F1)){
				screenShot();
			}
			
			Display.setTitle("X:"+cam.getX()+" Y:"+cam.getY()+" Z:"+cam.getZ());
			
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
			glLoadIdentity();
			cam.setView();
			Random random = new Random();
			
			glPushMatrix();
			{
				for(final Cube c : shapes){
					c.draw();
				}
			}
			glPopMatrix();
			x += 0.01f;
			Display.update();
		}
	}
	
	public static void cleanUp(){
		Display.destroy();
	}
	
	public static void screenShot(){
		Calendar cal = Calendar.getInstance();
		SimpleDateFormat formater = new SimpleDateFormat();
		
		Date now = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("HH.mm.ss");
		String ausgabe = sdf.format(now);
		
		GL11.glReadBuffer(GL11.GL_FRONT);
		int width = Display.getDisplayMode().getWidth();
		int height = Display.getDisplayMode().getHeight();
		int bpp = 4;
		ByteBuffer buffer = BufferUtils.createByteBuffer(width * height * bpp);
		GL11.glReadPixels(0, 0, width, height, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
		
		String format = "png";
		File file = new File("images/"+ausgabe+"."+format);
		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		
		for(int x = 0; x < width; x++){
			for(int y = 0; y < height; y++){
				int i = (x + (width * y)) * bpp;
				int r = buffer.get(i) & 0xFF;
				int g = buffer.get(i + 1) & 0xFF;
				int b = buffer.get(i + 2) & 0xFF;
				image.setRGB(x, height - (y + 1), (0xFF << 24) | (r << 16) | (g << 8) | b);
			}
		}
		
		try{
			ImageIO.write(image, format, file);
			System.out.println("Screenshot erfolgreich erstellt!");
			System.out.println(formater.format(cal.getTime()));
		}catch(IOException e){
			e.printStackTrace();
			System.out.println("Fehler beim Erstellen des Bildes!");
		}
	}
	
	public static void initDisplay(){
		try{
			Display.setDisplayMode(new DisplayMode(800, 600));
			Display.create();
		}catch(LWJGLException e){
			e.printStackTrace();
			Display.destroy();
			System.exit(0);
		}
	}
}
```

Camera:

```
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.util.glu.GLU.*;

public class Camera
{
	static float x;
	static float y;
    static float z;
	private float rx;
	private float ry;
	private float rz;
	
	float speed = 0.01f;
	
	private float fov;
	private float aspect;
	private float near;
	private float far;
	
	public Camera(float fov, float aspect, float near, float far){
		x = 0;
		y = 0;
		z = 0;
		rx = 0;
		ry = 0;
		rz = 0;
		
		this.fov = fov;
		this.aspect = aspect;
		this.near = near;
		this.far = far;
		initProjection();
	}
	
	private void initProjection(){
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		gluPerspective(fov, aspect, near, far);
		glMatrixMode(GL_MODELVIEW);
		
		glEnable(GL_DEPTH_TEST);
	}
	
	public void setView(){
		glRotatef(rx, 1, 0, 0);
		glRotatef(ry, 0, 1, 0);
		glRotatef(rz, 0, 0, 1);
		glTranslatef(x, y, z);
	}
	
	public float getX(){
		return x;
	}
	
	public float getY(){
		return y;
	}
	
	public float getZ(){
		return z;
	}
	
	public void setX(float x){
		this.x = x;
	}
	
	public void setY(float y){
		this.y = y;
	}
	
	public void setZ(float z){
		this.z = z;
	}
	
	public float getRX(){
		return rx;
	}
	
	public float getRY(){
		return ry;
	}
	
	public float getRZ(){
		return rz;
	}
	
	public void setRX(float rx){
		this.rx = rx;
	}
	
	public void setRY(float ry){
		this.ry = ry;
	}
	
	public void setRZ(float rz){
		this.rz = rz;
	}
	
	public void move(float amt, float dir){
		z += amt * Math.sin(Math.toRadians(ry + 90 * dir)); 
		x += amt * Math.cos(Math.toRadians(ry + 90 * dir));
	}
	
	public void moveUpDown(float amt){
		y += amt;
	}
	
	public void rotateX(float amt){
		rx += amt;
	}
	
	public void rotateY(float amt){
		ry += amt;
	}
}
```

Cube:

```
import static org.lwjgl.opengl.GL11.GL_QUADS;
import static org.lwjgl.opengl.GL11.glBegin;
import static org.lwjgl.opengl.GL11.glColor3f;
import static org.lwjgl.opengl.GL11.glEnd;
import static org.lwjgl.opengl.GL11.glTranslatef;
import static org.lwjgl.opengl.GL11.glVertex3f;


public class Cube extends Main
{
	static float x;
	static float y;
	static float z;
	
	public Cube(float x, float y, float z){
		this.x = x;
		this.y = y;
		this.z = z;
		draw();
	}
	
	static float getX(){
		return x;
	}
	
	static float getY(){
		return y;
	}
	
	static float getZ(){
		return z;
	}
	
	static void draw(){
		glColor3f(1.0f, 0.5f, 0f);
		glTranslatef(0, 0,-10);
		glBegin(GL_QUADS);
		{
			//Front
			glColor3f(1f,0f,0f);
			glVertex3f(-1,-1,1);
			glVertex3f(1,-1,1);
			glVertex3f(1,1,1);
			glVertex3f(-1,1,1);
			
			//BackFace
			glColor3f(0f,1f,0f);
			glVertex3f(-1,-1,-1);
			glVertex3f(-1,1,-1);
			glVertex3f(1,1,-1);
			glVertex3f(1,-1,-1);
			
			//BottomFace
			glColor3f(0f,0f,1f);
			glVertex3f(-1,-1,-1);
			glVertex3f(-1,-1,1);
			glVertex3f(-1,1,1);
			glVertex3f(-1,1,-1);
			
			//TopFace
			glColor3f(1f,1f,0f);
			glVertex3f(1,-1,-1);
			glVertex3f(1,-1,1);
			glVertex3f(1,1,1);
			glVertex3f(1,1,-1);
			
			//LeftFace
			glColor3f(0f,1f,1f);
			glVertex3f(-1,-1,-1);
			glVertex3f(1,-1,-1);
			glVertex3f(1,-1,1);
			glVertex3f(-1,-1,1);
			
			//Right Face
			glColor3f(1f,0f,1f);
			glVertex3f(-1,1,-1);
			glVertex3f(1,1,-1);
			glVertex3f(1,1,1);
			glVertex3f(-1,1,1);
		}
		glEnd();
	}
}
```

Und das Problem mit der Kamera: 
Sie ist "Kopfüber" also wenn ich SPACE drücke dann get die Koordinate in den Minusbereich und wenn ich SHIFT drücke um runterzugehen, gehe ich hoch?

Hoffe ihr könnt mir helfen.

MfG:
Florilu


----------



## Spacerat (6. Dez 2012)

Man kann es sehen, du hast entweder NeHe keinen einzigen Blick gewürdigt oder es nur ganz grob überflogen . Wo bitte löscht du denn deinen Grafikpuffer vor dem (Neu)Zeichnen (okay... hab's doch noch gefunden*)? Im Gegensatz zu Java2D macht das LWJGL (sowie andere OpenGL-Bindings auch) nicht automatisch. Evtl. ist LWJGL fur sich ja auch nicht das richtige. Wer an die Programmierung von Java2D gewöhnt ist kommt evtl. mit Java3D besser zurecht.

* Aber kurz danach hast du eine for each Schleife, in welcher du anscheinend mehere Cubes zeichnest. Dieser Liste wird mit jedem Duruck auf C ein weiterer Würfel an der Kameraposition hinzugefügt. Wenn du nur diesen sehen willst, müsstest du die Liste vorher leeren. Eine andere Möglichkeit wäre, wenn du dem bereits existierendem Würfel schlicht die neuen Koordinaten übergibst.


----------



## florilu (6. Dez 2012)

Ich meinte es so, das ein neuer Würfel an meiner aktuellen Position generiert wird, aber die alten sollten auch bestehen bleiben.

Na ja habe in der Zeit eine FPS Kamera eingebaut, damit ich den ganzen Mist nicht per Pfeiltasten steuern muss.

MfG:
Florilu


----------



## TKausL (6. Dez 2012)

Hallo.

Bin selbst noch nicht so belesen in LWJGL aber ich glaube

```
glTranslatef(0, 0,-10);
```
verschiebt die Aktuelle Zeichenposition nur bei jedem Vorgang um weiter 10 (Pixel?) nach hinten, wobei du ja nichtmal die Koordinaten zum Zeichnen benutzt.
Da du das Keyboard.isKeyDown in deiner Main-Schleife hast würdest du bei 60 FPS und 1 Sekunde Taste halten genau 60 deiner Blöcke hinzufügen, welche eben genau so gezeichnet werden wie ich oben angedeutet habe (immer 10 (Pixel?) von der Kamera weg bewegt)

Push- und Pop die Matrix mal innerhalb der Draw-Methode der Boxen ganz am Anfang bzw. am Ende.
Wenns nicht funktioniert: Sagte ja, bin ein totaler noob in LWJGL/OpenGL :lol:

E: Und versuch die Tasten mal nicht mit isKeyDown sondern mit den Keyboard-Events abzufragen:

Keyboard (LWJGL API)
Wichtig hier die next() und alles was bei "See also" steht.


----------



## florilu (6. Dez 2012)

So, es hat sich was getan, undzwar am Anfang sieht es jetzt so aus (Wenn ich spawne):





Wenn ich P drücke und dann n wenig nach vorne Fliege:




Sprich:
Die Würfel erscheinen wenn ich P drücke, jetzt muss ich es nur noch irgendwie hinkriegen das der Würfel genau an der Position erscheint, wo ich gerade bin, dann muss ich noch ein Raster erstellen, was aber nicht die schwerste Aufgabe sein dürfte.


----------



## florilu (9. Dez 2012)

So, ich noch mal,

ich habe in letzter Zeit n wenig an meiner API gearbeitet und versucht eine noch bessere Kamera u machen, aber da ist jetzt 1 Problem, undzwar ein sehr verwirrendes.

Wenn wir es jetzt so betrachten:

  Z+ 
X+  X-
  Z-

Ich kann bei Z+ und X+ wenn ich SPACE drücke nach oben fliegen, und wenn ich SHIFT drücke nach unten, so weit so gut, aber wenn ich bei Z- oder bei X- bin dann fliege ich mit SPACE nach unten und mit SHIFT nach oben?

Kann mir da jemand bitte helfen?

Der Code:

```
public void moveUp(float distance){
    	position.y += distance * (float)Math.sin(Math.toRadians(yaw + 90));
    	position.y -= distance * (float)Math.cos(Math.toRadians(yaw + 90));
    }
    
    public void moveDown(float distance){
    	position.y += distance * (float)Math.sin(Math.toRadians(yaw - 90));
    	position.y -= distance * (float)Math.cos(Math.toRadians(yaw - 90));
    }
```

MfG:
Florilu

//Edit
Hat sich ganz schön schnell erledigt


----------

