Nein, brauchst du nicht.ich brauche irgendeine gui lib für lwjgl2
Texture texture = null;
try {
texture = TextureLoader.getTexture("PNG",
new FileInputStream("res/" + fileName + ".png"));
GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR_MIPMAP_LINEAR);
GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL14.GL_TEXTURE_LOD_BIAS, -0.4f);
} catch (Exception e) {
e.printStackTrace();
System.err.println("Tried to load texture " + fileName + ".png , didn't work");
System.exit(-1);
}
der grund weshalb ich lwjgl 2 benutze ist also es ist einfach einfacher für michDu möchtest LWJGL 3 verwenden. LWJGL 2 ist schon viele viele Jahre deprecated und wird nicht mehr maintained und beginnt langsam, zu verfallen und Probleme (gerade mit Mac OS) zu machen: http://forum.lwjgl.org/index.php?topic=6951.msg36546#msg36546
Minecraft (als populärster Client von LWJGL) ist auch schon lange auf LWJGL 3 umgestiegen.
Nein, ist es nicht. LWJGL 2 ist nicht einfacher als LWJGL 3. Du musst halt dir einfach nur mal ein Beispiel mit GLFW angucken.es ist einfach einfacher für mich
GLFWErrorCallback errorCallback;
GLFWKeyCallback keyCallback;
GLFWFramebufferSizeCallback fsCallback;
Callback debugProc;
glfwSetErrorCallback(errorCallback = GLFWErrorCallback.createPrint(System.err));
if (!glfwInit())
throw new IllegalStateException("Unable to initialize GLFW");
glfwDefaultWindowHints();
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
window = glfwCreateWindow(width, height, "Hello World!", NULL, NULL);
if (window == NULL)
throw new RuntimeException("Failed to create the GLFW window");
glfwSetKeyCallback(window, keyCallback = new GLFWKeyCallback() {
public void invoke(long window, int key, int scancode, int action, int mods) {
if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE)
glfwSetWindowShouldClose(window, true);
}
});
glfwSetFramebufferSizeCallback(window, fsCallback = new GLFWFramebufferSizeCallback() {
public void invoke(long window, int w, int h) {
if (w > 0 && h > 0) {
width = w;
height = h;
}
}
});
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos(window, (vidmode.width() - width) / 2, (vidmode.height() - height) / 2);
try (MemoryStack frame = MemoryStack.stackPush()) {
IntBuffer framebufferSize = frame.mallocInt(2);
nglfwGetFramebufferSize(window, memAddress(framebufferSize), memAddress(framebufferSize) + 4);
width = framebufferSize.get(0);
height = framebufferSize.get(1);
}
glfwShowWindow(window);
}
//renderloop
glfwMakeContextCurrent(window);
//render stuff here
if (!destroyed) {
glfwSwapBuffers(window);
}
public static void createDisplay(){
/*ContextAttribs attribs = new ContextAttribs(1,3)
.withForwardCompatible(true)
.withProfileCore(true);*/
try {
Display.setDisplayMode(new DisplayMode(WIDTH,HEIGHT));
Display.create();
Display.setTitle("title");
} catch (LWJGLException e) {
e.printStackTrace();
}
GL11.glViewport(0,0, WIDTH, HEIGHT);
}
//render loop
Display.sync(FPS_CAP);
Display.update();
//-------------------
public static void closeDisplay(){
Display.destroy();
}
//main noch bevor irgendwas
DisplayManager.createDisplay();
nicht zu vergessen key input welcher in glfw mit callbacks funktoniertNein, ist es nicht. LWJGL 2 ist nicht einfacher als LWJGL 3. Du musst halt dir einfach nur mal ein Beispiel mit GLFW angucken.
Such dir irgendeine Demo hier aus: https://github.com/LWJGL/lwjgl3-demos/tree/master/src/org/lwjgl/demo/opengl
Schwachsinn. Der LWJGL 2 Code, den du zeigst, ist äquivalent zu dem LWJGL 3 / GLFW Code hier:man brauch ja auch mehr glfw code als lwjgl2
glfwInit();
long window = glfwCreateWindow(WIDTH, HEIGHT, "Hello World!", glfwGetPrimaryMonitor(), NULL);
glfwMakeContextCurrent(window);
glfwShowWindow(window);
GL.createCapabilities();
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// render..
glfwSwapBuffers(window);
glfwPollEvents();
}
Schwachsinn. Der LWJGL 2 Code, den du zeigst, ist äquivalent zu dem LWJGL 3 / GLFW Code hier:
Jetzt hör auf, rumzuheulen, und nutze einfach LWJGL 3 bzw. GLFW. Ist auf kurze und lange Sicht die wesentlich bessere Alternative!Java:glfwInit(); long window = glfwCreateWindow(WIDTH, HEIGHT, "Hello World!", glfwGetPrimaryMonitor(), NULL); glfwMakeContextCurrent(window); glfwShowWindow(window); GL.createCapabilities(); while (!glfwWindowShouldClose(window)) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // render.. glfwSwapBuffers(window); glfwPollEvents(); }
EDIT: Außerdem ist das Window Setup und die äußere Event-Loop Schleife eine einmalige Sache, für die man ein einziges Mal vielleicht 10 Minuten Recherche und Coding investieren muss. Und dann ist man damit durch...
Streng genommen, ist es vollkommen egal, ob das Window Setup nun 10 oder 50 Zeilen kostet... Who cares? Das ist nicht der Aufwandstreiber in einem Projekt. Und wenn du das ein einziges Mal hast, dann kannst du genauso wie in LWJGL 2 in LWJGL 3 einfach statische OpenGL Methoden aufrufen. Da ändert sich gar nichts.
Wer nicht will, findet Gründe. Wer will, findet Wege: https://github.com/JOML-CI/JOMLnicht zu vergessen keine Vector und matrix klassen welche ich benötige
Ich sag mal: jaok aber in joml durch wurde jetzt translate scale und rotate ersetzt
public static Matrix4f createTransformationMatrix(Vector2f translation, Vector2f scale) {
Matrix4f matrix = new Matrix4f();
matrix.identity();
Matrix4f.translate(translation, matrix, matrix);
Matrix4f.scale(new Vector3f(scale.x, scale.y, 1f), matrix, matrix);
return matrix;
}
public static Matrix4f createTransformationMatrix(Vector2f translation, Vector2f scale) {
return new Matrix4f()
.translate(translation.x, translation.y, 0)
.scale(scale.x, scale.y, 1);
}
Die API von JOML gegenüber der von lwjgl_util.jar von LWJGL 2 ist sehr viel mehr "fluent" und benötigt keine ekeligen statischen Methoden mit manuellem Parameterhinundhergereiche mehr.Java:public static Matrix4f createTransformationMatrix(Vector2f translation, Vector2f scale) { return new Matrix4f() .translate(translation.x, translation.y, 0) .scale(scale.x, scale.y, 1); }
public static Matrix4f createTransformationMatrix(Vector3f translation, float rx, float ry,
float rz, float scale) {
return new Matrix4f()
.translate(translation)
.rotate((float) Math.toRadians(rx), new Vector3f(1,0,0))
.rotate((float) Math.toRadians(ry), new Vector3f(0,1,0))
.rotate((float) Math.toRadians(rz), new Vector3f(0,0,1))
.scale(new Vector3f(scale,scale,scale));
}
public static Matrix4f createTransformationMatrix(
Vector3f translation,
float rx, float ry, float rz,
float scale) {
return new Matrix4f()
.translate(translation)
.rotateX((float) Math.toRadians(rx))
.rotateY((float) Math.toRadians(ry))
.rotateZ((float) Math.toRadians(rz))
.scale(scale);
}
`rotate((float) Math.toRadians(rx), new Vector3f(1,0,0))` _kann_ man so machen, es gibt aber performantere Methoden, wenn es sich um eine der drei Basisachsen handelt.Java:public static Matrix4f createTransformationMatrix( Vector3f translation, float rx, float ry, float rz, float scale) { return new Matrix4f() .translate(translation) .rotateX((float) Math.toRadians(rx)) .rotateY((float) Math.toRadians(ry)) .rotateZ((float) Math.toRadians(rz)) .scale(scale); }
Bitte benutze einfach eine IDE und explore mal ein bisschen die API/Klassen. Dort wirst du die benötigten Methoden finden. Sie heißen jetzt nur _exakt_ genauso wie die nativen OpenGL Funktionen (also mit Typsuffix).Java:GL20.glUniformMatrix4 //und GL20.glGetShader
gibt es nicht mehr
STBImage: https://github.com/nothings/stboh und was ist mit texturen laden
ok ich les mir das mal durchSTBImage: https://github.com/nothings/stb
Gibt es auch viele Beispiele in dem GitHub Demo Repo und in dem LWJGL/lwjgl3 GitHub Repo.
private void createProjectionMatrix(){
float aspectRatio = (float) Display.getWidth() / (float) Display.getHeight();
float y_scale = (float) ((1f / Math.tan(Math.toRadians(FOV / 2f))) * aspectRatio);
float x_scale = y_scale / aspectRatio;
float frustum_length = FAR_PLANE - NEAR_PLANE;
projectionMatrix = new Matrix4f();
projectionMatrix.m00 = x_scale;
projectionMatrix.m11 = y_scale;
projectionMatrix.m22 = -((FAR_PLANE + NEAR_PLANE) / frustum_length);
projectionMatrix.m23 = -1;
projectionMatrix.m32 = -((2 * NEAR_PLANE * FAR_PLANE) / frustum_length);
projectionMatrix.m33 = 0;
}
aber ich glaube die m00 sachen sind jetzt einfach _m00jetzt fehlt halt noch display zeug und input aber das bekomm ich schon hin bin aber auf ein anderes problem gestoßen nämlich das hier:
funktoniert nicht mehrJava:private void createProjectionMatrix(){ float aspectRatio = (float) Display.getWidth() / (float) Display.getHeight(); float y_scale = (float) ((1f / Math.tan(Math.toRadians(FOV / 2f))) * aspectRatio); float x_scale = y_scale / aspectRatio; float frustum_length = FAR_PLANE - NEAR_PLANE; projectionMatrix = new Matrix4f(); projectionMatrix.m00 = x_scale; projectionMatrix.m11 = y_scale; projectionMatrix.m22 = -((FAR_PLANE + NEAR_PLANE) / frustum_length); projectionMatrix.m23 = -1; projectionMatrix.m32 = -((2 * NEAR_PLANE * FAR_PLANE) / frustum_length); projectionMatrix.m33 = 0; }
private void createProjectionMatrix() {
float aspectRatio = (float) Display.getWidth() / (float) Display.getHeight();
projectionMatrix = new Matrix4f().perspective((float) Math.toRadians(FOV), aspectRatio, NEAR_PLANE, FAR_PLANE);
}
//-------------------ioutil klasse
package toolbox;
import org.lwjgl.*;
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.file.*;
import static org.lwjgl.BufferUtils.*;
public final class IOUtil {
private IOUtil() {
}
private static ByteBuffer resizeBuffer(ByteBuffer buffer, int newCapacity) {
ByteBuffer newBuffer = BufferUtils.createByteBuffer(newCapacity);
buffer.flip();
newBuffer.put(buffer);
return newBuffer;
}
public static ByteBuffer ioResourceToByteBuffer(String resource, int bufferSize) throws IOException {
ByteBuffer buffer;
Path path = Paths.get(resource);
if (Files.isReadable(path)) {
try (SeekableByteChannel fc = Files.newByteChannel(path)) {
buffer = BufferUtils.createByteBuffer((int)fc.size() + 1);
while (fc.read(buffer) != -1) {
;
}
}
} else {
try (
InputStream source = IOUtil.class.getClassLoader().getResourceAsStream(resource);
ReadableByteChannel rbc = Channels.newChannel(source)
) {
buffer = createByteBuffer(bufferSize);
while (true) {
int bytes = rbc.read(buffer);
if (bytes == -1) {
break;
}
if (buffer.remaining() == 0) {
buffer = resizeBuffer(buffer, buffer.capacity() * 3 / 2); // 50%
}
}
}
}
buffer.flip();
return buffer;
}
}
//------------------------------------------------image klasse
package textures;
import static toolbox.IOUtil.*;
import static java.lang.Math.*;
import static org.lwjgl.opengl.GL12.*;
import static org.lwjgl.opengl.GL30.*;
import static org.lwjgl.stb.STBImage.*;
import static org.lwjgl.stb.STBImageResize.*;
import static org.lwjgl.system.MemoryStack.*;
import static org.lwjgl.system.MemoryUtil.*;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL14;
import org.lwjgl.system.MemoryStack;
public class Image {
private static ByteBuffer image;
private static int wi;
private static int he;
private static int compo;
private int scale;
private static void Image(String imagePath) {
ByteBuffer imageBuffer;
try {
imageBuffer = ioResourceToByteBuffer(imagePath, 8 * 256);
} catch (IOException e) {
throw new RuntimeException(e);
}
try (MemoryStack stack = stackPush()) {
IntBuffer w = stack.mallocInt(1);
IntBuffer h = stack.mallocInt(1);
IntBuffer comp = stack.mallocInt(1);
// Use info to read image metadata without decoding the entire image.
// We don't need this for this demo, just testing the API.
if (!stbi_info_from_memory(imageBuffer, w, h, comp)) {
throw new RuntimeException("Failed to read image information: " + stbi_failure_reason());
} else {
System.out.println("OK with reason: " + stbi_failure_reason());
}
System.out.println("Image width: " + w.get(0));
System.out.println("Image height: " + h.get(0));
System.out.println("Image components: " + comp.get(0));
System.out.println("Image HDR: " + stbi_is_hdr_from_memory(imageBuffer));
// Decode the image
image = stbi_load_from_memory(imageBuffer, w, h, comp, 0);
if (image == null) {
throw new RuntimeException("Failed to load image: " + stbi_failure_reason());
}
wi = w.get(0);
he = h.get(0);
compo = comp.get(0);
}
}
private void setScale(int scale) {
this.scale = max(-9, scale);
}
private static void premultiplyAlpha() {
int stride = wi * 4;
for (int y = 0; y < he; y++) {
for (int x = 0; x < wi; x++) {
int i = y * stride + x * 4;
float alpha = (image.get(i + 3) & 0xFF) / 255.0f;
image.put(i + 0, (byte)round(((image.get(i + 0) & 0xFF) * alpha)));
image.put(i + 1, (byte)round(((image.get(i + 1) & 0xFF) * alpha)));
image.put(i + 2, (byte)round(((image.get(i + 2) & 0xFF) * alpha)));
}
}
}
public static int createTexture(String path) {
Image(path);
int texID = glGenTextures();
glBindTexture(GL_TEXTURE_2D, texID);
glGenerateMipmap(GL11.GL_TEXTURE_2D);
glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf(GL11.GL_TEXTURE_2D, GL14.GL_TEXTURE_LOD_BIAS, -0.4f);
int format;
if (compo == 3) {
if ((wi & 3) != 0) {
glPixelStorei(GL_UNPACK_ALIGNMENT, 2 - (wi & 1));
}
format = GL_RGB;
} else {
premultiplyAlpha();
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
format = GL_RGBA;
}
glTexImage2D(GL_TEXTURE_2D, 0, format, wi, he, 0, format, GL_UNSIGNED_BYTE, image);
ByteBuffer input_pixels = image;
int input_w = wi;
int input_h = he;
int mipmapLevel = 0;
while (1 < input_w || 1 < input_h) {
int output_w = Math.max(1, input_w >> 1);
int output_h = Math.max(1, input_h >> 1);
ByteBuffer output_pixels = memAlloc(output_w * output_h * compo);
stbir_resize_uint8_generic(
input_pixels, input_w, input_h, input_w * compo,
output_pixels, output_w, output_h, output_w * compo,
compo, compo == 4 ? 3 : STBIR_ALPHA_CHANNEL_NONE, STBIR_FLAG_ALPHA_PREMULTIPLIED,
STBIR_EDGE_CLAMP,
STBIR_FILTER_MITCHELL,
STBIR_COLORSPACE_SRGB
);
if (mipmapLevel == 0) {
stbi_image_free(image);
} else {
memFree(input_pixels);
}
glTexImage2D(GL_TEXTURE_2D, ++mipmapLevel, format, output_w, output_h, 0, format, GL_UNSIGNED_BYTE, output_pixels);
input_pixels = output_pixels;
input_w = output_w;
input_h = output_h;
}
if (mipmapLevel == 0) {
stbi_image_free(image);
} else {
memFree(input_pixels);
}
return texID;
}
}
//---------------------------------------ruft image.create texture auf-----
public int loadTexture(String fileName) {
return Image.createTexture(fileName + ".png");
}
//-----------------------------load texture wird von hier aufgerufen-----
TerrainTexture backgroundTexture = new TerrainTexture(loader.loadTexture("grassy"));
Exception in thread "main" java.lang.NullPointerException: "in" is null!
at java.nio.channels.Channels.checkNotNull(Channels.java:67)
at java.nio.channels.Channels.newChannel(Channels.java:347)
at toolbox.IOUtil.ioResourceToByteBuffer(IOUtil.java:39)
at textures.Image.Image(Image.java:34)
at textures.Image.createTexture(Image.java:88)
at renderEngine.Loader.loadTexture(Loader.java:51)
at main.Main.main(Main.java:37)