# LWJGL Dreidimensionaler Würfel



## florilu (3. Dez 2012)

Hallo,
Ich wollte mal fragen wie ich mit LWJGL in einer 3D-Umgebung einen 3D-Würfel reinsetzen kann? Der akuelle Code wäre nur eine Seite denke ich, spiele ja n wenig mit LWJGL rum, um zu lernen, aber wenn ich die Würfel habe will ich ein kleines Game draus machen. Meine bisherigen LWJGL-Erfahrungen sind ca. 4-5 Tage, aber dafür das ich schon 3D-Umgebungen gemacht habe lobe ich mich selbst ^^ Aber ich will ja eig in die 3D Programmierung rein.

So der Code:

```
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;

import java.util.Random;

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

public class Main {

    public static void main(String[] args) {
        // Initialization code Display
        try {
            Display.setDisplayMode(new DisplayMode(640, 480));
            Display.setTitle("Three Dee Demo");
            Display.create();
        } catch (LWJGLException e) {
            e.printStackTrace();
            Display.destroy();
            System.exit(1);
        }
        //

        // Initialization code OpenGL
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        // Create a new perspective with 30 degree angle (field of view), 640 / 480 aspect ratio, 0.001f zNear, 100 zFar
        // Note: 	+x is to the right
        //     		+y is to the top
        //			+z is to the camera
        gluPerspective((float) 30, 640f / 480f, 0.001f, 100);
        glMatrixMode(GL_MODELVIEW);
        //

        // To make sure the points closest to the camera are shown in front of the points that are farther away.
        glEnable(GL_DEPTH_TEST);

        // Initialization code random points
        Point[] points = new Point[0];
        Random random = new Random();
        // Iterate of every array index
        for (int i = 0; i < points.length; i++) {
            // Set the point at the array index to 
            // x = random between -50 and +50
            // y = random between -50 and +50
            // z = random between  0  and -200
            points[i] = new Point((random.nextFloat() - 0.5f/*0.5*/) * 100f/*100*/, (random.nextFloat() - 0.5f/*0.5*/) * 100f/*100*/, random.nextInt(200/*200*/) - 200/*200*/);
        }
        
        Cube[] cubes = new Cube[500];
        for(int i = 0; i <= cubes.length; i++){
        	cubes[i] = new Cube ((random.nextFloat() - 0.5f/*0.5*/) * 100f/*100*/, (random.nextFloat() - 0.5f/*0.5*/) * 100f/*100*/, random.nextInt(200/*200*/) - 200/*200*/);
        }
        // The speed in which the "camera" travels
        float speed = 0.0f;
        //

        while (!Display.isCloseRequested()) {
            // Render

            // Clear the screen of its filthy contents
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

            // Push the screen inwards at the amount of speed
            glTranslatef(0, 0, speed);

            // Begin drawing points
            glBegin(GL_POINTS);
            // Iterate of every point
            for (Point p : points) {
                // Draw the point at its coordinates
                glVertex3f(p.x, p.y, p.z);
            }
            for(Cube c: cubes){
            	glVertex3d(c.x, c.y, c.z);
            }
            // Stop drawing points
            glEnd();


            // If we're pressing the "up" key increase our speed
            if (Keyboard.isKeyDown(Keyboard.KEY_UP)) {
                speed += 0.01f;
            }
            if(Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)){
            	System.exit(0);
            	Display.destroy();
            }
            // If we're pressing the "down" key decrease our speed
            if (Keyboard.isKeyDown(Keyboard.KEY_DOWN)) {
                speed -= 0.01f;
            }
            // Iterate over keyboard input events
            while (Keyboard.next()) {
                // If we're pressing the "space-bar" key reset our speed to zero
                if (Keyboard.isKeyDown(Keyboard.KEY_SPACE)) {
                    speed = 0f;
                }
                // If we're pressing the "c" key reset our speed to zero and reset our position
                if (Keyboard.isKeyDown(Keyboard.KEY_C)) {
                    speed = 0;
                    glLoadIdentity();
                }
            }

            // Update the display
            Display.update();
            // Wait until the frame-rate is 60fps
            Display.sync(60);
        }

        // Dispose of the display
        Display.destroy();
        // Exit the JVM (for some reason this lingers on Macintosh)
        System.exit(0);
    }
    
    private static class Cube{
    	
    	float x, y, z;
    	
    	 public void draw(){
    		glBegin(GL_QUADS);
    		glVertex3f(x, y, z);
    		glVertex3f(x + 50, y, z);
    		glVertex3f(x + 50, y + 50, z);
    		glVertex3f(x, y + 50, z);
    		glEnd();
    	}
    	
    	public Cube(float x, float y, float z){
    		this.x = x;
    		this.y = y;
    		this.z = z;
    	}
    }

    private static class Point {

        float x, y, z;

        public Point(float x, float y, float z) {
            this.x = x;
            this.y = y;
            this.z = z;
        }
    }
}
```

So das währ mein Code.
Und die Fehlermeldung:

```
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 500
	at Main.main(Main.java:54)
```

Ich weiß leider nicht wie ich das genau machen soll, vllt. hat ja jemand ne Idee wie ich einen Würfel machen kann, den ich dann hinterher generieren kann + Collisionbox.

Wie macht man es richtig?

Kann auch n komplett neuer Code sein, Hauptsache die Würfel lassen sich generieren.

Oder ihr schlägt mir ein paar Tuts vor 

MfG:
Florilu


----------



## Tomate_Salat (3. Dez 2012)

[c]for(int i = 0; i <= cubes.length; i++){[/c]
ändere das mal in:
[c] for(int i = 0; i < cubes.length; i++){[/c]
;-)


----------



## florilu (3. Dez 2012)

Ok das läuft, aber wie kriege ich jetzt Würfel hin? Habe leider nur Pünktchen, oder ich leg mir ne FPS Kamera zu.


----------



## Spacerat (3. Dez 2012)

Also du hast 8 Points, die entsprechend plaziert sind.
dann verbindest du

OBEN:
1, 2, 3, 4
UNTEN:
5, 6, 7, 8
VORNE:
1, 2, 5, 6
HINTEN:
3, 4, 7, 8
LINKS:
1, 4, 5, 8
RECHTS:
2, 3, 6, 7

Das bedeutet, du musst 6 Quads zeichnen. Das geht im übrigen auch innerhalb eines einzigen "glBegin(GL.QUADS)" und "glEnd()". Wichtig ist nur, dass die Anzahl der gezeichneten Vertices durch 4 teilbar ist.
[EDIT]An die Semi-Profis da draussen... ich weiss, ich hab CW bzw. CCW nicht beachtet, BackfaceCulling sollte also abgeschaltet werden.[/EDIT]


----------



## florilu (3. Dez 2012)

Ok, und wie bring ich jetzt das draw in meinem Code ein das er es auch in der Form macht?
In 2D ist es ja einfach, aber der Code zum zeichnen + die generierung der Objekte. Weiß leider nicht so ganz wie ich das machen soll.


----------



## Spacerat (3. Dez 2012)

Okay, dann gibt's auch noch die Punktplatzierungen...

a entspricht der Kantenlänge


```
1. 0.0, 0.0, 0.0
2.   a, 0.0, 0.0
3.   a, 0.0,   a
4. 0.0, 0.0,   a
5. 0.0,   a, 0.0
6.   a,   a, 0.0
7.   a,   a,   a
8. 0.0,   a,   a
```


----------



## florilu (3. Dez 2012)

Ok, na ja dennoch würde ich es gerne irgendwie reinzeichnen, nur weiß ich nicht wie  das ist ja mein größtes Problem. In 2D habe ich z.B. eine steuerbares Quadrat und mein Code dafür sieht so aus:

Main.java:

```
import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.GL_MODELVIEW;
import static org.lwjgl.opengl.GL11.GL_PROJECTION;
import static org.lwjgl.opengl.GL11.glClear;
import static org.lwjgl.opengl.GL11.glLoadIdentity;
import static org.lwjgl.opengl.GL11.glMatrixMode;
import static org.lwjgl.opengl.GL11.glOrtho;

import java.awt.Graphics;
import java.util.ArrayList;
import java.util.List;

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

public class Main 
{
	private static List<Player> shapes = new ArrayList<Player>(1);
	
	private static float xcoords = Player.x;
	private static float ycoords = Player.y;
	private static String playercoords = "X: "+xcoords+" Y: "+ycoords;
	
	long fps = 0;
	
	public void paintComponent(Graphics g){
		g.drawString(playercoords, 15, 15);
		g.drawString("FPS: "+Long.toString(fps), 20, 10);
	}
	
	public static void main(String[] args){
		
		try{
			Display.setDisplayMode(new DisplayMode(640, 480));
			Display.setTitle("Game!");
			Display.create();
		}catch(LWJGLException e){
			e.printStackTrace();
			Display.destroy();
			System.exit(1);
		}
		
		shapes.add(new Player(15, 15));
		
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		glOrtho(0, 640, 480, 0, 1, -1);
		glMatrixMode(GL_MODELVIEW);
		
		while(!Display.isCloseRequested()){
			glClear(GL_COLOR_BUFFER_BIT);
			
			if(Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)){
				Display.destroy();
				System.exit(0);
			}
			
			for(final Player player : shapes){
				if(Keyboard.isKeyDown(Keyboard.KEY_W)){
					player.y += -1;
				}if(Keyboard.isKeyDown(Keyboard.KEY_S)){
					player.y += 1;
				}if(Keyboard.isKeyDown(Keyboard.KEY_A)){
					player.x += -1;
				}if(Keyboard.isKeyDown(Keyboard.KEY_D)){
					player.x += 1;
				}if(Keyboard.isKeyDown(Keyboard.KEY_UP)){
					player.y += -1;
				}if(Keyboard.isKeyDown(Keyboard.KEY_DOWN)){
					player.y += 1;
				}if(Keyboard.isKeyDown(Keyboard.KEY_LEFT)){
					player.x += -1;
				}if(Keyboard.isKeyDown(Keyboard.KEY_RIGHT)){
					player.x += 1;
				}
				player.draw();
			}
			System.out.println(Player.x);
			Display.update();
			Display.sync(60);
		}
	}
}
```

Und Player.java:

```
import static org.lwjgl.opengl.GL11.*;

public class Player extends Main
{
	public static int x;
	public static int y;
	
	void update(int dx, int dy){
		x += dx;
		y += dy;
	}
	
	Player(int x, int y){
		this.x = x;
		this.y = y;
	}
	
	void draw(){
		glBegin(GL_QUADS);
		glVertex2f(x, y);
		glVertex2f(x + 50, y);
		glVertex2f(x + 50, y + 50);
		glVertex2f(x, y + 50);
		glEnd();
	}
}
```

Wie ich das platzieren kann weiß ich ja, das habe ich ja schon mit den Pünktchen angestellt. Mit dem Würfel dürfte das anders sein, nur mit der Z-Koordinate.

Also das drawing, muss ich noch n wenig mit rumspielen  Aber es währ ja für mich schon n Erfolg wenn ich 2 Flächen hätte die in einem 3D-Raum generiert werden. 

So dann noch mal zur frage, wie kriege ich das draw jetzt in den 3D raum rein, damit er weiß welche Form das Objekt hat bzw. es in dieser Form generiert in 2D währ es der Code:


```
shapes.add(new Player(15, 15));
```
und

```
player.draw();
```

MfG:
Florilu


----------



## Spacerat (3. Dez 2012)

Fang am besten mal klein an... z.B. hier. Bei einigen Tuts sind auch LWJGL-Quellen vorhanden (unten auf den Seiten zum download). Zum Einstieg genügt das zwar, aber anschliessend sollte man das alles schnell wieder vergessen, weil nicht UpToDate.


----------



## florilu (3. Dez 2012)

Das ist ja nicht mein Problem, nur mein Problem ist, das ich nicht weiß wie ich es dareinzeichnen soll, denn ich würde gerne die Methode dazu wissen, das was du mir gesendet hast, ist meiner Meinung nach "solala" aber dort wird ja nicht das Thema LWJGL behandelt, sondern eher OpenGL, aber meines Wissens nach "erleichtert" LWJGL das Handling von OpenGL obwohl es in der wesentlichen Programmierung nicht die größten Unterschiede macht. Aber ich habe auch in den Tutorials nicht das gefunden (Beim überfliegen) was ich gesucht habe.
Habe mal das Bewegen in einer 3Dimensionalen Welt runtergeladen (Quelltext für Java), und da sind mehrere Sachen enthalten die mir in LWJGL nur bedingt weiterhelfen werden besonders in dem Bereich wo ich Probleme habe, also 2D habe ich ja schon durch + CollisionBox und Entities usw. jetzt will ich bei 3D beginnen und Punkte habe ich ja schon, jetzt will ich in dem Bereich einen Würfel erscheinen lassen, dann für ne Welt generieren. Da bin ich ja schon weit genug für, aber ich habe noch keine Tuts dazu gefunden, oder ich muss mich durch die Docs quälen, die sagen mir leider auch nicht wie ich das aufbauen muss.

Hoffe verstehst mich darin ein wenig 

MfG:
Florilu


----------



## Spacerat (3. Dez 2012)

florilu hat gesagt.:


> Das ist ja nicht mein Problem, nur mein Problem ist, das ich nicht weiß wie ich es dareinzeichnen soll, denn ich würde gerne die Methode dazu wissen, das was du mir gesendet hast, ist meiner Meinung nach "solala" aber dort wird ja nicht das Thema LWJGL behandelt, sondern eher OpenGL, aber meines Wissens nach "erleichtert" LWJGL das Handling von OpenGL obwohl es in der wesentlichen Programmierung nicht die größten Unterschiede macht. Aber ich habe auch in den Tutorials nicht das gefunden (Beim überfliegen) was ich gesucht habe.
> Habe mal das Bewegen in einer 3Dimensionalen Welt runtergeladen (Quelltext für Java), und da sind mehrere Sachen enthalten die mir in LWJGL nur bedingt weiterhelfen werden besonders in dem Bereich wo ich Probleme habe, also 2D habe ich ja schon durch + CollisionBox und Entities usw. jetzt will ich bei 3D beginnen und Punkte habe ich ja schon, jetzt will ich in dem Bereich einen Würfel erscheinen lassen, dann für ne Welt generieren. Da bin ich ja schon weit genug für, aber ich habe noch keine Tuts dazu gefunden, oder ich muss mich durch die Docs quälen, die sagen mir leider auch nicht wie ich das aufbauen muss.
> 
> Hoffe verstehst mich darin ein wenig
> ...


Tja... du musst 'ne Kleinigkeit verstehen... LWJGL ist ein sog. Java-Binding. Ein solches projeziert native API-Methoden in Java, im Falle von LWJGL betrifft das OpenGL, OpenAL und OpenCL. Die projezierten Methoden sind entweder zu den nativen identisch oder soweit angepasst, dass sie mit Javamitteln funktionieren. Erleichtern tun sie die Arbeit jedoch keineswegs.
Das bedeutet für dich, dass du dich durchaus auch mit OpenGL in anderen Sprachen (z.B. C/C++) befassen kannst, um dahinter zu kommen, wie das Ein oder Andere (letztendlich auch in LWJGL) funktioniert. In NeHes Lesson 5 z.B. wird ein Würfel gezeichnet und rotiert. Wenn man sich den Quelltext dazu ansieht, erkennt man, dass der Würfel (in Grösse und Aussehen) statisch ist und nur entsprechende Matrix-Manipulation gedreht wird. Ebenso müsste er auch bewegt werden. Mit anderen Worten... Ja, es kann nicht schaden, sich da durch zu quälen.


----------



## Landei (3. Dez 2012)

[OT]
Ein Würfel ist immer 3D. In 2D nenn sich das "Quadrat", in 1D "Linie" und in 0D "Punkt". In höheren Dimensionen handelt es sich um einen "Hyperwürfel".
[/OT]


----------



## florilu (3. Dez 2012)

> Ein Würfel ist immer 3D. In 2D nenn sich das "Quadrat", in 1D "Linie" und in 0D "Punkt". In höheren Dimensionen handelt es sich um einen "Hyperwürfel".


Habe ich je was anderes behauptet? Wenn ja, dann sry 

@Spacerat
Ich habe mal n wenig rumgestöbert und bin auf ein simples Spiel gestoßen, was meine "Wünsche" erfüllt, ich werde da mal im Code rumstöbern und schauen wie die Systematik ist, und werd mir am Ende was selbst zusammenbasteln.

MfG:
Florilu


----------



## Spacerat (3. Dez 2012)

[OT]





Landei hat gesagt.:


> Ein Würfel ist immer 3D. In 2D nenn sich das "Quadrat", in 1D "Linie" und in 0D "Punkt". In höheren Dimensionen handelt es sich um einen "Hyperwürfel".


:lol: Wieso fällt einem für höhere (evtl. unbekannte) Gefilde nichts mehr ausser schon Dagewesenes ein? Der Würfel war bei der Entdeckung der 3. Dimension ja auch kein Hyperquadrat. Wie wär's mit Polygramm?[/OT]
@TO: Was anderes Behauptet hast du nicht wirklich. Der Titel dieses Threads, lässt aber anmuten, als gäbe es auch andere (ausser dreidimensionale) Würfel.


----------



## florilu (5. Dez 2012)

Man kann den ja auch in 2D zeichnen  z.B. so http://www.planet-schule.de/warum_chemie/feuerloeschen/themenseiten/t10/images_content/wuerfel1.gif Ist für mich vom aussehen her ein Würfel.


Davon abgesehen habe ihn schon seit 2 Tagen fertig


----------



## Landei (6. Dez 2012)

Das zeigt die Parallelprojektion eines Würfels.

Und das ist keine Pfeife:


----------



## Evil-Devil (9. Dez 2012)

Ein Würfel in LWJGL....


```
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);
	
	// Der Würfel aller Würfel ^__^'
	GL11.glBegin(GL11.GL_QUADS);

		// Front Side
		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.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.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.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.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.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();
}
```


----------

