Skip to content

Instantly share code, notes, and snippets.

@Show-vars
Created March 18, 2016 07:28
Show Gist options
  • Save Show-vars/06c1dc7e377d7250f35f to your computer and use it in GitHub Desktop.
Save Show-vars/06c1dc7e377d7250f35f to your computer and use it in GitHub Desktop.
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.bunjlabs.lwjgltest;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import javax.imageio.ImageIO;
import org.lwjgl.*;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.opengl.GL11;
import org.lwjgl.system.MemoryUtil;
public class NewMain {
// We need to strongly reference callback instances.
private GLFWErrorCallback errorCallback;
private GLFWKeyCallback keyCallback;
int WIDTH = 800;
int HEIGHT = 600;
// The window handle
private long window;
public void run() {
System.out.println("Hello LWJGL " + Version.getVersion() + "!");
try {
init();
loop();
// Destroy window and window callbacks
GLFW.glfwDestroyWindow(window);
keyCallback.release();
} finally {
// Terminate GLFW and free the GLFWErrorCallback
GLFW.glfwTerminate();
errorCallback.release();
}
}
private void init() {
// Setup an error callback. The default implementation
// will print the error message in System.err.
GLFW.glfwSetErrorCallback(errorCallback = GLFWErrorCallback.createPrint(System.err));
// Initialize GLFW. Most GLFW functions will not work before doing this.
if (GLFW.glfwInit() != GLFW.GLFW_TRUE) {
throw new IllegalStateException("Unable to initialize GLFW");
}
// Configure our window
GLFW.glfwDefaultWindowHints(); // optional, the current window hints are already the default
GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, GLFW.GLFW_FALSE); // the window will stay hidden after creation
GLFW.glfwWindowHint(GLFW.GLFW_RESIZABLE, GLFW.GLFW_TRUE); // the window will be resizable
// Create the window
window = GLFW.glfwCreateWindow(WIDTH, HEIGHT, "Hello World!", MemoryUtil.NULL, MemoryUtil.NULL);
if (window == MemoryUtil.NULL) {
throw new RuntimeException("Failed to create the GLFW window");
}
// Setup a key callback. It will be called every time a key is pressed, repeated or released.
GLFW.glfwSetKeyCallback(window, keyCallback = new GLFWKeyCallback() {
@Override
public void invoke(long window, int key, int scancode, int action, int mods) {
if (key == GLFW.GLFW_KEY_ESCAPE && action == GLFW.GLFW_RELEASE) {
GLFW.glfwSetWindowShouldClose(window, GLFW.GLFW_TRUE); // We will detect this in our rendering loop
}
}
});
// Get the resolution of the primary monitor
GLFWVidMode vidmode = GLFW.glfwGetVideoMode(GLFW.glfwGetPrimaryMonitor());
// Center our window
GLFW.glfwSetWindowPos(
window,
(vidmode.width() - WIDTH) / 2,
(vidmode.height() - HEIGHT) / 2
);
// Make the OpenGL context current
GLFW.glfwMakeContextCurrent(window);
// Enable v-sync
GLFW.glfwSwapInterval(1);
// Make the window visible
GLFW.glfwShowWindow(window);
}
private void loop() {
GL.createCapabilities();
GL11.glViewport(0, 0, WIDTH, HEIGHT);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, WIDTH, 0, HEIGHT, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GL11.glEnable(GL11.GL_TEXTURE_2D);
int textId = newTexture("/texture.png");
while (GLFW.glfwWindowShouldClose(window) == GLFW.GLFW_FALSE) {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); // clear the framebuffer
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textId);
//GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glBegin(GL11.GL_QUADS);
{
GL11.glTexCoord2f(0, 0.2f);
GL11.glVertex2i(20, 40);
GL11.glTexCoord2f(0.2f, 0.2f);
GL11.glVertex2i(40, 40);
GL11.glTexCoord2f(0.2f, 0);
GL11.glVertex2i(40, 20);
GL11.glTexCoord2f(0, 0);
GL11.glVertex2i(20, 20);
}
GL11.glEnd();
GLFW.glfwSwapBuffers(window);
GLFW.glfwPollEvents();
}
}
private static final int BYTES_PER_PIXEL = 4;
public static int newTexture(final String path) {
int texture = 0;
try {
InputStream IS = NewMain.class.getResourceAsStream(path);
ByteArrayOutputStream BAOS = new ByteArrayOutputStream();
int read1 = IS.read();
while (read1 != -1) {
BAOS.write(read1);
read1 = IS.read();
}
byte[] textureBA = BAOS.toByteArray();
BAOS.close();
BufferedImage textureBI = ImageIO.read(new ByteArrayInputStream(textureBA));
texture = loadTexture(textureBI);
System.out.println("Texture load > Buffered image: " + textureBI.getWidth() + "x" + textureBI.getHeight() + " / Texture ID: " + texture);
} catch (IOException e) {
e.printStackTrace();
}
return texture;
}
private static int loadTexture(BufferedImage image) {
int[] pixels = new int[image.getWidth() * image.getHeight()];
image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());
ByteBuffer buffer = BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * BYTES_PER_PIXEL); //4 for RGBA, 3 for RGB
for (int y = 0; y < image.getHeight(); y++) {
for (int x = 0; x < image.getWidth(); x++) {
int pixel = pixels[y * image.getWidth() + x];
buffer.put((byte) ((pixel >> 16) & 0xFF)); // Red component
buffer.put((byte) ((pixel >> 8) & 0xFF)); // Green component
buffer.put((byte) (pixel & 0xFF)); // Blue component
buffer.put((byte) ((pixel >> 24) & 0xFF)); // Alpha component. Only for RGBA
}
}
buffer.flip(); //FOR THE LOVE OF GOD DO NOT FORGET THIS
// You now have a ByteBuffer filled with the color data of each pixel.
// Now just create a texture ID and bind it. Then you can newTexture it using
// whatever OpenGL method you want, for example:
int textureID = GL11.glGenTextures(); //Generate texture ID
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID); //Bind texture ID
//Setup wrap mode
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
//Setup texture scaling filtering
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
//Send texel data to OpenGL
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, image.getWidth(), image.getHeight(), 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
//Return the texture ID so we can bind it later again
return textureID;
}
public static void main(String[] args) {
new NewMain().run();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment