# LWJGL Gui erstellen



## TheCreeper202 (15. Mai 2012)

hallo leute
wie kann man mit lwjgl ein gui erstellen, denn minecraft nutzt das auch und ist einfach einen neuen guiscreen zu erstellen
tutorial, javadocs, buch, ...


----------



## tdc (15. Mai 2012)

Hi,
zuerst musst du auf deine 3d-Szene rendern, danach dann auf 2d "umschalten" (durch verschiedene Matrixoperationen) dann dein gui zeichnen und dann wieder zu 3d wechseln. Grob müsste das dann so aussehen:

```
public void drawOpenGL()
	{
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
		
		//3D
        
        glMatrixMode(GL_PROJECTION);
        glPushMatrix();
        glLoadIdentity();
        glOrtho(0,getWidth(),getHeight(),0,-1,1);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        //2D
        
        glMatrixMode(GL_PROJECTION);
        glPopMatrix();
        glMatrixMode(GL_MODELVIEW);
	}
```

Bei //3D renderst du ganz normal deine 3d-Szene und bei //2D deine Oberfläche. Dort kannst du dann ganz normal 2D-OpenGL-Formen reinzeichen, Texturen verwenden und daraus dein GUI aufbauen. Für Texte (z.B. auf Buttons) gibt es bei Slick UnicodeFont (auf TextureImpl.bindNone(); achten!).
Für größere GUIs gibt es dann afaik noch Nifty-Gui, für ein simples Menü sollte reines OpenGL aber reichen.


----------



## TheCreeper202 (15. Mai 2012)

ok, ich habs nicht ganz verstanden
1. ich habe lwjgl, lwjgl_util und jinput
2. die ganzen gl...() methoden sind doch in org.lwjgl.opengl.GL11
3. wie kann ich jetzt eine klasse names gui machen von der alle anderen klassen erben
aus minecraft (ganz einfach):

```
package net.minecraft.src;

public class GuiPrintHello extends GuiScreen { //GuiScreen extends Gui

    public void initGui() {
        controlList.clear();
        controlList.add(new GuiButton(0, 100, 100, 100, 20, "Print Hallo")); // id, x, y, breite, höhe, text
    }
    public void drawScreen(int i, int j, float f) {
        this.drawDefaultBackground();
        super.drawScreen(i, j, f);
    }
    public void actionPerformed(GuiButton guibutton) {
        if (guibutton.id == 0) {
            ModLoader.getMinecraftInstance().thePlayer.addChatMessage("Hello");
    }
}
```
alles mit den 3 bibliotheken
das macht einen 50% transperrenten schwarzen hintergrund mit einem button mit der aufschrift "Print Hello" wenn man drauf klickt wird im chat Hello ausgegeben

ach ja und in minecraft gibt es die terrain.png da sind alle blocktexturen im format 16x16px wenn man [c]new Block(150, 6);[/c] zählt der ab:
0:  x=0, y=0
1:  x=16, y=0
...
11: x=0, y=16
...
wie geht das ([c]Image img = TextureLoader.getImage("/hallo.png", 5); // bild in jar, zahl zum abzählen[/c])


----------



## tdc (15. Mai 2012)

> 1. ich habe lwjgl, lwjgl_util und jinput


Wenn du es dir schwer machen willst, okay, ansonsten binde noch slick ein, damit kann man viel leichter Text darstellen lassen.



> 2. die ganzen gl...() methoden sind doch in org.lwjgl.opengl.GL11


Jaaaaaa....?



> 3. wie kann ich jetzt eine klasse names gui machen von der alle anderen klassen erben
> aus minecraft


Solange du das Prinzip nicht verstanden hast erstmal gar nicht. Das Problem ist, du musst den Text bei jedem Renderdurchgang rendern, du kannst also nicht einmal Text hinzufügen (".addChatMessage("Hello");"), sondern musst ihn, solange er angezeigt wird zeichnen lassen.

Ansonsten solltest du dich vielleicht nochmal mit den Grundlagen von OpenGL beschäftigen, mit Aussagen wie "2. die ganzen gl...() methoden sind doch in org.lwjgl.opengl.GL11" und einem Verweis auf nichtssagenden Minecraft-Quellcode machst du auf mich nicht gerade den Eindruck, als wüsstest du, was du tust/willst.

------------------------



> ach ja und in minecraft gibt es die terrain.png da sind alle blocktexturen im format 16x16px wenn man [c]new Block(150, 6);[/c] zählt der ab:
> 0:  x=0, y=0
> 1:  x=16, y=0
> ...
> ...


Ich habe keine Ahnung, was in Minecraft wann/wie/wo gemacht wird und es ist mir auch egal. Orientiere dich nicht an dem Quellcode, sondern mache etwas eigenes, was du auch verstehst. Fange z.B. mal mit einem rotierenden Block an und arbeite dich dann Schritt für Schritt vorwärts.

Was willst du überhaupt erreichen? Willst du den Quellcode einfach nur verstehen? Willst du einen "Mod" für Minecraft schreiben?


----------



## TheCreeper202 (17. Mai 2012)

1. modden mach ich zur zeit und mein mod kommt im juni raus
2. DeBukkIt auf YouTube GuiScreen erstellen Tutorial
3. ich möchte ein Programm/Spiel (naja eher eine libary) wo man so einfach ein gui erstellen kann natürlich mit eigener grafik
4. Wo kann ich was über opengl erfahren


----------



## Spacerat (17. Mai 2012)

Was bitte verstehst man in LWJGL unter einer GUI? Sollen Texte, Knöpfe und Fenster in 3D dargestellt werden oder genügen Texturen? Sollen einzelne GUI-Elemente voneinander getrennt (wegen Picking) sein oder dürfen sie alle zusammen liegen? Theoretisch liessen sich ja irgendwelche GUI-Elemente (AWT, Swing, usw.) mit meinem DirectBufferedImage ganz einfach in eine Textur schreiben, nur müsste dort noch an einem Event-System gearbeitet werden. Man könnte sich dies bezüglich aber auch mal Marcos SWOGL ansehen.
Alles Möglichkeiten. Aber leider denke ich, das Minecraft bereits ein eigenes GUI-System hat, welches du benutzen müsstest. Da könnten aber spezielle Mincraft-Entwickler-Foren viel hilfreicher sein.


----------



## Evil-Devil (18. Mai 2012)

TheCreeper202 hat gesagt.:


> 1. modden mach ich zur zeit und mein mod kommt im juni raus
> 2. DeBukkIt auf YouTube GuiScreen erstellen Tutorial
> 3. ich möchte ein Programm/Spiel (naja eher eine libary) wo man so einfach ein gui erstellen kann natürlich mit eigener grafik
> 4. Wo kann ich was über opengl erfahren



1) recht krasser Zeitplan, wenn man bedenkt das du nicht weißt wo du anfangen sollst
3) SLICK wäre hier eine Möglichkeit, aber Minecraft hat doch sicher eigene GUI Zeichenroutinen?
4) Let me google that for you

Für Texturen benötigst du ein Grafikprogramm. Gimp oder Photoshop werden bei den meisten die erste Wahl sein.


----------



## TheCreeper202 (10. Jun 2012)

ok ich hab mich was mit lwjgl und opengl und nehe's tutorials und wollte jetzt ein viereck zeichnen mit den koordinaten x: 0, y: 0, width: 10, height: 10
hier mein code der klasse Gui:

```
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package de.creeperfans.opengl;

import org.lwjgl.opengl.GL11;
import org.lwjgl.util.vector.Vector2f;

/**
 *
 * @author Roman
 */
public class Gui {
    
    public void drawRect(int x, int y, int width, int height, int color) {
        GL11.glLoadIdentity();
        GL11.glTranslatef(0.0f, 0.0f, 0.0f);
        setHexColor(color);
        Vector2f point1 = new Vector2f(x, y);
        Vector2f point2 = new Vector2f(x + width, y);
        Vector2f point3 = new Vector2f(x + width, y + height);
        Vector2f point4 = new Vector2f(x, y + height);
        GL11.glBegin(GL11.GL_QUADS);
        {
            GL11.glVertex2f(point1.x, point1.y);
            GL11.glVertex2f(point2.x, point2.y);
            GL11.glVertex2f(point3.x, point3.y);
            GL11.glVertex2f(point4.x, point4.y);
        }
        GL11.glEnd();
    }
    
    public void setHexColor(int color) {
        float r = (float)(color >> 24 & 0xff) / 255F;
        float g = (float)(color >> 16 & 0xff) / 255F;
        float b = (float)(color >> 8 & 0xff) / 255F;
        float a = (float)(color & 0xff) / 255F;
        GL11.glColor4f(r, g, b, a);
    }
    
}
```
und hier meine main-class:

```
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package de.creeperfans.opengl;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import org.newdawn.slick.util.ResourceLoader;

/**
 *
 * @author Roman
 */
public class Main implements Runnable {
    
    public DisplayMode displayMode;
    public static Main game;
    public int width;
    public int height;
    public File[] folders;
    
    public Main() {
        displayMode = new DisplayMode(800, 600);
        game = this;
        width = displayMode.getWidth();
        height = displayMode.getHeight();
        folders = new File[] {
            new File("screenshots/")
        };
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Thread main = new Thread(new Main(), "game");
        main.start();
    }

    @Override
    public void run() {
        createDisplay();
        createControllers();
        createUsedFolders();
        init();
        runGameLoop();
        stop();
    }
    
    public void createDisplay() {
        try {
            Display.setDisplayMode(displayMode);
            Display.create();
        } catch (LWJGLException ex) {
            Logger.getLogger(NewClass.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public void createControllers() {
        try {
            Keyboard.create();
            Mouse.create();
        } catch (LWJGLException ex) {
            Logger.getLogger(NewClass.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public void createUsedFolders() {
        System.out.println("Creating Folders...");
        for (File folder : folders) {
            String EXISTS = "already exists";
            String TRUE = "created";
            String FALSE = "cannot create";
            String print = folder.mkdir() ? TRUE : folder.exists() ? EXISTS : FALSE;
            System.out.println(folder.getName() + ": " + print);
        }
    }
    
    public void init() {
        GL11.glEnable(GL11.GL_DEPTH_TEST);
        GL11.glShadeModel(GL11.GL_SMOOTH);
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        DisplayMode dm = Display.getDisplayMode();
        int w = dm.getWidth();
        int h = dm.getHeight();
        GLU.gluPerspective(45.0f, (float) w / (float) h, 0.1f, 100.0f);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        GL11.glEnable(GL11.GL_TEXTURE_2D);
    }
    
    public void runGameLoop() {
        while (!Display.isCloseRequested() && !Keyboard.isKeyDown(Keyboard.KEY_ESCAPE))
        {
            draw();
            updateControllers();
            Display.update();
        }
    }
    
    RenderEngine renderEngine = new RenderEngine();
    Gui gui = new Gui();
    
    public void draw() {
        gui.drawRect(0, 0, 10, 10, 0xffffff);
    }
    
    public void stop() {
        Keyboard.destroy();
        Mouse.destroy();
        Display.destroy();
    }
    
    public void updateControllers() {
        while (Keyboard.next()) {
            if (Keyboard.getEventKeyState()) {
                if (Keyboard.getEventKey() == Keyboard.KEY_ESCAPE) {
                    stop();
                }
                if (Keyboard.getEventKey() == Keyboard.KEY_F2) {
                    screenshot();
                }
            }
        }
    }
    
    public void screenshot() {
        GL11.glReadBuffer(GL11.GL_FRONT);
        int bpp = 4; // Assuming a 32-bit display with a byte each for red, green, blue, and alpha.
        ByteBuffer buffer = BufferUtils.createByteBuffer(width * height * bpp);
        GL11.glReadPixels(0, 0, width, height, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer );
        File file = new File("screenshots/screenshot_" + getDate() + ".png");
        String format = "PNG";
        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);
        } catch (IOException e) { e.printStackTrace(); }
        System.out.println("Screenshot token!");
    }
    
    public static String getDate(String dateformat) {
        String DATE_FORMAT = dateformat;
        Calendar c = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
        return sdf.format(c.getTime());
    }
    
    public static String getDate() {
        return getDate("yyyyMMdd_HHmmss_SSS");
    }
    
}
```
doch es wird nichts gezeichnet es kommt einfach ein blackscreen mehr nicht
weiß jemand vlt wies richtig ist???
danke im vorraus!
TheCreeper202


----------

