Created
March 18, 2016 07:28
-
-
Save Show-vars/06c1dc7e377d7250f35f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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