OpenGL GL30.glGenVertexArrays() returns null - java

I am having trouble populating a VAO with my vertex data. I am not sure what the problem is. Here is the error.
Exception in thread "main" java.lang.NullPointerException
at org.lwjgl.opengl.GL30.nglGenVertexArrays(GL30.java:3265)
at org.lwjgl.opengl.GL30.glGenVertexArrays(GL30.java:3294)
at javaapplication73.Loader.createVAO(Loader.java:35)
at javaapplication73.Loader.loadToVao(Loader.java:27)
at javaapplication73.HelloWorld.initial(HelloWorld.java:139)
at javaapplication73.HelloWorld.loop(HelloWorld.java:120)
at javaapplication73.HelloWorld.run(HelloWorld.java:32)
at javaapplication73.HelloWorld.main(HelloWorld.java:154)
Java Result: 1
And here is the loader class which is throwing the exception
public class Loader {
private List<Integer> vaos = new ArrayList<Integer>();
private List<Integer> vbos = new ArrayList<Integer>();
public RawModel loadToVao(float[] positions){
int vaoID = this.createVAO();
this.storeDataInAttributeList(0, positions);
this.unbindVAO();
return new RawModel(1, positions.length/3);
}
private int createVAO(){
int vaoID = GL30.glGenVertexArrays(1, vao);
vaos.add(vaoID);
GL30.glBindVertexArray(vaoID);
return vaoID;
}
public void storeDataInAttributeList(int attributeNumber, float[] data){
int vboID = GL15.glGenBuffers();
vbos.add(vboID);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboID);
FloatBuffer buffer =storeDataInFloatBuffer(data);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(attributeNumber, 3, GL11.GL_FLOAT, false, 0, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
public void unbindVAO(){
//unbind the array
GL30.glBindVertexArray(0);
}
private FloatBuffer storeDataInFloatBuffer(float[] data){
FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length);
buffer.put(data);
//need to flip between wright and read
buffer.flip();
return buffer;
}
public void cleanUp(){
for (Integer vao : this.vaos) {
GL30.glDeleteVertexArrays(vao);
}
for(Integer vbo : this.vbos){
GL15.glDeleteBuffers(vbo);
}
}
}
Here is the Main class
package javaapplication73;
public class HelloWorld {
// We need to strongly reference callback instances.
private GLFWErrorCallback errorCallback;
private GLFWKeyCallback keyCallback;
// The window handle
private long window;
private final int fpsCap = 120;
Loader loader = new Loader();
Renderer renderer = new Renderer();
private RawModel model;
public void run() {
System.out.println("Hello LWJGL " + Sys.getVersion() + "!");
try {
init();
loop();
// Release window and window callbacks
glfwDestroyWindow(window);
keyCallback.release();
} finally {
// Terminate GLFW and release the GLFWerrorfun
glfwTerminate();
errorCallback.release();
}
}
private void init() {
// Setup an error callback. The default implementation
// will print the error message in System.err.
glfwSetErrorCallback(errorCallback = errorCallbackPrint(System.err));
// Initialize GLFW. Most GLFW functions will not work before doing this.
if ( glfwInit() != GL11.GL_TRUE )
throw new IllegalStateException("Unable to initialize GLFW");
// Configure our window
glfwDefaultWindowHints(); // optional, the current window hints are already the default
glfwWindowHint(GLFW_VISIBLE, GL_FALSE); // the window will stay hidden after creation
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE); // the window will be resizable
int WIDTH = 1200;
int HEIGHT = 800;
// Create the window
window = glfwCreateWindow(WIDTH, HEIGHT, "Not so Still Life", NULL, NULL);
if ( window == 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.
glfwSetKeyCallback(window, keyCallback = new GLFWKeyCallback() {
#Override
public void invoke(long window, int key, int scancode, int action, int mods) {
if ( key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE )
glfwSetWindowShouldClose(window, GL_TRUE); // We will detect this in our rendering loop
cleanUp();
}
});
// Get the resolution of the primary monitor
ByteBuffer vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
// Center our window
glfwSetWindowPos(
window,
(GLFWvidmode.width(vidmode) - WIDTH) / 2,
(GLFWvidmode.height(vidmode) - HEIGHT) / 2
);
// Make the OpenGL context current
glfwMakeContextCurrent(window);
// Enable v-sync
glfwSwapInterval(1);
// Make the window visible
glfwShowWindow(window);
}
private void loop() {
// This line is critical for LWJGL's interoperation with GLFW's
// OpenGL context, or any context that is managed externally.
// LWJGL detects the context that is current in the current thread,
// creates the ContextCapabilities instance and makes the OpenGL
// bindings available for use.
GLContext.createFromCurrent();
// Set the clear color
glClearColor(.3243f,0,.83251234f,0);
// Run the rendering loop until the user has attempted to close
// the window or has pressed the ESCAPE key.
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, 800, 0, 600, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
while ( glfwWindowShouldClose(window) == GL_FALSE ) {
// Clear the screen and depth buffer
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
initial();
Render();
glfwSwapBuffers(window); // swap the color buffers
glfwPollEvents();
}
}
public void initial(){
System.out.println(glGetString(GL_VERSION));
//Pre game stuff
float[] verticies = {
-0.5f, 0.5f, 0f,
-0.5f, -0.5f, 0f,
0.5f, -0.5f, 0f,
0.5f, -0.5f, 0f,
0.5f, 0.5f, 0f,
-0.5f, 0.5f, 0f,
};
model = loader.loadToVao(verticies);
}
public void Render(){
renderer.prepare();
renderer.Render(model);
}
public void cleanUp(){
System.out.println("CleanUp");
this.loader.cleanUp();
}
public static void main(String[] args) {
System.setProperty("org.lwjgl.librarypath", "/Users/Bayjose/LWJGL/lwjgl/native");
new HelloWorld().run();
}
}
I am running Mac OSX Yosemite with Java 8, and I am useing LWJGL3 as a library for this project.

Remove arguments 1 and vao so
int vaoID = GL30.glGenVertexArrays();

Related

LWJGL3 - can't render triangle but can clear color

I've been trying to render a triangle on my screen for the past day but I can't figure out what I'm doing incorrectly. The only thing that works is displaying a window and rendering to it using clear color. Does anyone know what I'm doing incorrectly? All I'm expecting is to see a black triangle rendered on screen like I've done once in the past but currently I'm not able to do that.
Here's the code:
Main:
public class Main {
public static void main(String[] args){
System.out.println("Hello");
// Create Window
Window.createWindow();
long window = Window.getWindow();
// Create Renderer
Renderer renderer = new Renderer();
// Data
float[] positions = {
0.5f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f
};
// Create Model
Model triangle = Loader.dataToModel(positions);
// Render on window
while(!GLFW.glfwWindowShouldClose(window)){
GLFW.glfwPollEvents();
renderer.clear();
renderer.render(triangle);
GLFW.glfwSwapBuffers(window); // !##!##!## remember to add!!! !##!## Order important prob
}
System.out.println("TERMINATED");
Window.terminateWindow();
}
}
Window:
public class Window {
private static long window;
private static Callback debugCallback;
public static void createWindow(){
// Creates a window
// Init
if(!GLFW.glfwInit()){
throw new IllegalStateException("ERROR: could not GLFW.glfwInit()");
}
// Hints
// Hint opengl version
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR,3);
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR,2);
// Hint compatibility (profile, forward compat)
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_PROFILE,GLFW.GLFW_OPENGL_CORE_PROFILE);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_FORWARD_COMPAT,GLFW.GLFW_TRUE);
// Hint to hide initially
GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE,GLFW.GLFW_FALSE);
// Hint debug
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_DEBUG_CONTEXT, GLFW.GLFW_TRUE);
// Actually create window
window = GLFW.glfwCreateWindow(500, 500, "thinMatrix4", 0, 0);
if(window == 0){
throw new IllegalStateException("ERROR: during GLFW.glfwCreateWindow");
}
// Context and Capabilities
GLFW.glfwMakeContextCurrent(window); // create context for window
GL.createCapabilities(); // find all the opengl stuff to give capabilities
// Debugging enable
GL11.glEnable(org.lwjgl.opengl.KHRDebug.GL_DEBUG_OUTPUT_SYNCHRONOUS);
debugCallback = GLUtil.setupDebugMessageCallback();
// Position window
GLFWVidMode vidMode = GLFW.glfwGetVideoMode(GLFW.glfwGetPrimaryMonitor());
GLFW.glfwSetWindowPos(window,vidMode.width()/2,vidMode.height()/2);
// Window show
GLFW.glfwShowWindow(window);
}
public static void terminateWindow(){
// Termination
GLFW.glfwTerminate();
}
// GETTERS
public static long getWindow() {
return window;
}
}
Renderer:
public class Renderer {
public void render(Model model){
// Enable to allow model rendering
GL30.glBindVertexArray(model.getVAO());
GL20.glEnableVertexAttribArray(0);
// Render
GL11.glDrawArrays(GL11.GL_TRIANGLES,model.getVertexCount(),0);
// Clean up
GL20.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
}
public void clear(){
GL11.glClearColor(0f,0.8f,.6f,1f);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
}
}
Model:
public class Model {
private int vertexCount;
private int vao;
public Model(int vao, int count){
this.vao = vao;
this.vertexCount = count;
}
// GETTERS
public int getVertexCount(){
return this.vertexCount;
}
public int getVAO(){ return this.vao; }
}
public class Loader {
private static List<Integer> vaos = new ArrayList<Integer>();
private static List<Integer> vbos = new ArrayList<Integer>();
public static Model dataToModel(float[] data){
// Create VAO
int vao = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vao);
vaos.add(vao);
// Create Buffer (VBO) for actual data
int vbo = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER,vbo);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER,toFloatBuffer(data), GL15.GL_STATIC_DRAW); //!##!##!## What happens if data is not a float buffer
// vertex attribute pointer
GL30.glVertexAttribPointer(0,3, GL11.GL_FLOAT,false,0,0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER,0);
vbos.add(vbo);
// Create model
int count = data.length/3;
Model model = new Model(vao, count);
return model;
}
private static FloatBuffer toFloatBuffer(float[] data){
FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length);
buffer.put(data);
buffer.flip();
return buffer;
}
}
You used glDrawArrays incorrectly. The 2nd argument is the index of the 1st vertex to be rendered and the 3rd argument is the number of vertices:
GL11.glDrawArrays(GL11.GL_TRIANGLES,model.getVertexCount(),0);
GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, model.getVertexCount());

LWJGL Flickering Output When Attempting to Draw Triangle

I've been trying to get into OpenGL with LWJGL and I've run into an issue that I cannot find a solution to. When trying to draw a triangle with the code below, the window opens correctly and begins flashing a shape that isn't necessarily the intended triangle (sometimes it appears briefly, but often there are rectangles in one of the quadrants of the window).
Part of my hesitation is in how OpenGL, by my reading of various posts and docs online, has changed within recent memory to use a less functional and more an object-oriented approach (VBOs and GLSL?) with GL4. Am I correct in this understanding and what are the preferred resources for learning this newer OpenGL for LWJGL?
Thank you in advance!
import org.lwjgl.BufferUtils;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;
import org.lwjgl.system.*;
import java.nio.*;
import static org.lwjgl.glfw.Callbacks.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryStack.*;
import static org.lwjgl.system.MemoryUtil.*;
public class Main {
private long windowID;
private float[] tri = {0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f};
public static void main(String[] args) {
new Main().run();
}
public void run() { // Useful for making an instance class as opposed to a static main class?
init();
loop();
glfwFreeCallbacks(windowID);
glfwDestroyWindow(windowID);
glfwTerminate();
glfwSetErrorCallback(null).free();
}
public void init() { // Initializes all LWJGL components
GLFWErrorCallback.createPrint(System.err).set(); // Create error callback route for GL
if (!glfwInit()) { // Init GLFW
throw new IllegalStateException("Failed to initialize GLFW!");
} else {
System.out.println("GLFW successfully initialized!");
}
windowID = glfwCreateWindow(640, 480, "Creating Window", NULL, NULL);
if (windowID == NULL) { // Verify window creation
throw new IllegalStateException("Failed to create window!");
} else {
System.out.println("Successfully created window!");
}
glfwDefaultWindowHints(); // Set window Proporties
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
glfwSetKeyCallback(windowID, (window, key, scancode, action, mods) -> { // Key callback for closing the window
if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE)
glfwSetWindowShouldClose(window, true);
});
try (MemoryStack stack = stackPush()) { // Center the window
IntBuffer pWidth = stack.mallocInt(1);
IntBuffer pHeight = stack.mallocInt(1);
glfwGetWindowSize(windowID, pWidth, pHeight);
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos( // Center the window
windowID,
(vidmode.width() - pWidth.get(0)) / 2,
(vidmode.height() - pHeight.get(0)) / 2
);
}
glfwMakeContextCurrent(windowID); // Make the window current
glfwSwapInterval(0); // Sets the min num of pushed frames before buffers are swaped (Likely prevents horizontal tearing)
glfwShowWindow(windowID); // Unhides the window
}
private void loop() {
GL.createCapabilities();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // The color to clear the buffers with
while(!glfwWindowShouldClose(windowID)) { // If the window is allowed to live
glClear(GL_COLOR_BUFFER_BIT); // The OR is nessesary for some reason
FloatBuffer vBuff = BufferUtils.createFloatBuffer(6);
vBuff.put(tri);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, vBuff);
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableClientState(GL_VERTEX_ARRAY);
glfwSwapBuffers(windowID);
glfwPollEvents();
}
}
}
You missed vBuff.flip() after the buffer was crated and filled.
vBuff.put(tri) transfers the the data to the buffer, beginning at the current position (which is the start of the buffer in this case). The buffer position is incremented by the size of the data. So the new buffer position is at the end of the new data.
flip() sets the limit (length) of the buffer to the current position and then the position is set to zero.
Further, it is not necessary to create and fill the buffer continuously in the loop, it would be sufficient to do that once before the loop:
FloatBuffer vBuff = BufferUtils.createFloatBuffer(6);
vBuff.put(tri);
vBuff.flip();
while(!glfwWindowShouldClose(windowID)) {
glClear(GL_COLOR_BUFFER_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, vBuff);
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableClientState(GL_VERTEX_ARRAY);
glfwSwapBuffers(windowID);
glfwPollEvents();
}

I'm having trouble getting a model rendered to the window using open gl and glfw (LWJGL)

I'm working on getting familiar with the LWJGL library for java and I've been following a few tutorials online and I can't seem to get a model rendered.
im using OpenGL 2.1(this seems to be very outdated but Im not really sure about how to update that, I know its tied in with the hardware you have, I'm using a MacBook Pro 2017 model if anyone is interested in my specs)
if someone could take a look at my code and tell me what im doing wrong I would really appreciate it! (all that is being rendered right now is a red window)
from the sources I've studied this code should result in a square made up of two triangles coloured in a gradient using a vertex and a fragment shader but instead nothing is being rendered.
public class Main {
private long window;
private int width = 1280, height = 720;
public void run() {
System.out.println("LWJGL " + Version.getVersion() + "!");
init();
loop();
glfwFreeCallbacks(window);
glfwDestroyWindow(window);
glfwTerminate();
glfwSetErrorCallback(null).free();
}
private void init() {
GLFWErrorCallback.createPrint(System.err).set();
if (!glfwInit()) throw new IllegalStateException("Unable to initialize GLFW");
glfwDefaultWindowHints();
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
window = glfwCreateWindow(width, height, "TESTING", NULL, NULL);
if (window == NULL) throw new RuntimeException("Failed to create the GLFW window");
glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> {
if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE) glfwSetWindowShouldClose(window, true); /
});
try (MemoryStack stack = stackPush()) {
IntBuffer pWidth = stack.mallocInt(1); // int*
IntBuffer pHeight = stack.mallocInt(1); // int*
glfwGetWindowSize(window, pWidth, pHeight);
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos(window, (vidmode.width() - pWidth.get(0)) / 2, (vidmode.height() - pHeight.get(0)) / 2);
}
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
glfwShowWindow(window);
}
private void loop() {
GL.createCapabilities();
GL11.glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
Renderer renderer = new Renderer();
Loader loader = new Loader();
StaticShader shader = new StaticShader();
float[] vertices = {
-0.5f, 0.5f, 0f,
-0.5f, -0.5f, 0f,
0.5f, -0.5f, 0f,
0.5f, 0.5f, 0f,
};
int[] indicies = {
0,1,3,
3,1,2
};
RawModel model = loader.loadToVAO(vertices, indicies);
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glfwSwapBuffers(window);
renderer.prepare();
shader.start();
renderer.render(model);
shader.stop();
glfwPollEvents();
}
loader.cleanUp();
shader.cleanUp();
}
public static void main(String[] args) {
new Main().run();
}
}
public class RawModel {
private int vaoID;
private int vertexCount;
public RawModel(int vaoID, int vertexCount) {
this.vaoID = vaoID;
this.vertexCount = vertexCount;
}
public int getVaoID() {
return vaoID;
}
public int getVertexCount() {
return vertexCount;
}
}
public class Renderer {
public void prepare() {
GL11.glClearColor(1, 0, 0, 1);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
}
public void render(RawModel model){
GL30.glBindVertexArray(model.getVaoID());
GL20.glEnableVertexAttribArray(0);
//System.out.println(model.getVertexCount());
GL11.glDrawElements(GL11.GL_TRIANGLES, model.getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
GL20.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
}
}
public class Loader {
private List<Integer> vaos = new ArrayList<Integer>();
private List<Integer> vbos = new ArrayList<Integer>();
public RawModel loadToVAO(float[] positions,int[] indicies) {
int vaoID = createVAO();
bindIndecesBuffer(indicies);
storeDataInAttributeList(0, positions);
unbindVAO();
return new RawModel(vaoID, indicies.length);
}
private void bindIndecesBuffer(int[] indices) {
int vboID = GL15.glGenBuffers();
vbos.add(vboID);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboID);
IntBuffer buffer = storeDatainIntBuffer(indices);
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
}
private IntBuffer storeDatainIntBuffer(int[] data) {
IntBuffer buffer = BufferUtils.createIntBuffer(data.length);
buffer.put(data);
buffer.flip();
return buffer;
}
public void cleanUp() {
for (int vao : vaos) {
GL30.glDeleteVertexArrays(vao);
}
for (int vbo : vbos) {
GL15.glDeleteBuffers(vbo);
}
}
private int createVAO() {
int vaoID = GL30.glGenVertexArrays();
vaos.add(vaoID);
GL30.glBindVertexArray(vaoID);
return vaoID;
}
private void storeDataInAttributeList(int attributeNumber, float[] data) {
int vboID = GL15.glGenBuffers();
vbos.add(vboID);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboID);
FloatBuffer buffer = storeDataInFloatBuffer(data);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(attributeNumber, 3, GL11.GL_FLOAT, false, 0, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
private void unbindVAO() {
GL30.glBindVertexArray(0);
}
private FloatBuffer storeDataInFloatBuffer(float[] data) {
FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length);
buffer.put(data);
buffer.flip();
return buffer;
}
}
public abstract class ShaderProgram {
private int programID;
private int vertexShaderID;
private int fragmentShaderID;
public ShaderProgram(String vertexFile,String fragmentFile){
vertexShaderID = loadShader(vertexFile,GL20.GL_VERTEX_SHADER);
fragmentShaderID = loadShader(fragmentFile,GL20.GL_FRAGMENT_SHADER);
programID = GL20.glCreateProgram();
GL20.glAttachShader(programID, vertexShaderID);
GL20.glAttachShader(programID, fragmentShaderID);
bindAttributes();
GL20.glLinkProgram(programID);
GL20.glValidateProgram(programID);
}
public void start(){
GL20.glUseProgram(programID);
}
public void stop(){
GL20.glUseProgram(0);
}
public void cleanUp(){
stop();
GL20.glDetachShader(programID, vertexShaderID);
GL20.glDetachShader(programID, fragmentShaderID);
GL20.glDeleteShader(vertexShaderID);
GL20.glDeleteShader(fragmentShaderID);
GL20.glDeleteProgram(programID);
}
protected abstract void bindAttributes();
protected void bindAttribute(int attribute, String variableName){
GL20.glBindAttribLocation(programID, attribute, variableName);
}
private static int loadShader(String file, int type){
StringBuilder shaderSource = new StringBuilder();
try{
BufferedReader reader = new BufferedReader(new FileReader(file));
String line;
while((line = reader.readLine())!=null){
shaderSource.append(line).append("//\n");
}
reader.close();
}catch(IOException e){
e.printStackTrace();
System.exit(-1);
}
int shaderID = GL20.glCreateShader(type);
GL20.glShaderSource(shaderID, shaderSource);
GL20.glCompileShader(shaderID);
if(GL20.glGetShaderi(shaderID, GL20.GL_COMPILE_STATUS )== GL11.GL_FALSE){
System.out.println(GL20.glGetShaderInfoLog(shaderID, 500));
System.err.println("Could not compile shader!");
System.exit(-1);
}
return shaderID;
}
}
public class StaticShader extends ShaderProgram {
private static final String VERTEX_FILE = "src/shaderEngine/vertexShader.txt";
private static final String FRAGMENT_FILE = "src/shaderEngine/fragmentShader.txt";
public StaticShader() {
super(VERTEX_FILE, FRAGMENT_FILE);
}
#Override
protected void bindAttributes() {
super.bindAttribute(0, "position");
}
}
//VERTEX SHADER
#version 120
attribute vec3 position;
varying vec3 colour;
void main(void){
gl_Position = vec4(position,1.0);
colour = vec3(position.x+0.5,0.0,position.y+0.5);
}
//FRAGMENT SHADER
#version 120
varying vec3 colour;
void main(void){
gl_FragColor = vec4(colour,1.0);
}
Your code uses Vertex Array Objects (VAOs) for rendering. As the GL30 syntax of lwjgl already suggests, this is an OpenGL 3.0 feature. Running this code with a GL 2.1 context will only work if your implementation happens to implement the GL_ARB_vertex_array_object OpenGL extension.
im using OpenGL 2.1(this seems to be very outdated but Im not really sure about how to update that, I know its tied in with the hardware you have, I'm using a MacBook Pro 2017 model if anyone is interested in my specs)
YOu are limited to OpenGL 2.1 because you are using a legacy GL context. If you want somewhat modern OpenGL on OSX, you have to request a GL 3.2 core profile context at context creation. Also be warned that the most recent GL version that Apple is going to support is GL 4.1, and Apple actually declared OpenGL as deprecated and might remove it completely from future versions of OSX.

No GLCapabilities instance has been set for the current thread

I've been trying OpenGL, following ThinMatrix's tutorials. Only thing I'm doing differently is he was using lwjgl 2 and i'm using 3. I thought it would be a good challenge, and it has definitely proven to be. It say's no glcapabilities have been set but I'm pretty sure I set them already!
Basically the full error I'm getting is
Exception in thread "main" java.lang.IllegalStateException: No GLCapabilities instance has been set for the current thread.
at org.lwjgl.opengl.GL.getCapabilities(GL.java:211)
at org.lwjgl.opengl.GL20.getInstance(GL20.java:378)
at org.lwjgl.opengl.GL20.glCreateShader(GL20.java:464)
at net.robharding.base.shaders.ShaderProgram.loadShader(ShaderProgram.java:67)
at net.robharding.base.shaders.ShaderProgram.<init>(ShaderProgram.java:17)
at net.robharding.base.shaders.StaticShader.<init>(StaticShader.java:9)
at net.robharding.base.engine.Display.init(Display.java:77)
at net.robharding.base.engine.Display.<init>(Display.java:31)
at net.robharding.base.MainComponent.main(MainComponent.java:8)
To me, this makes no sense because I Did do GL.CreateCapabilities();, and I can't find anything online about this error...
package net.robharding.base.engine;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;
import net.robharding.base.shaders.StaticShader;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.system.MemoryUtil.*;
public class Display {
private String title;
private int width, height;
#SuppressWarnings("unused")
private GLFWErrorCallback errorCallback;
#SuppressWarnings("unused")
private GLFWKeyCallback keyCallback;
private long windowID;
private Loader loader;
private Renderer renderer;
private StaticShader shader;
public Display(String title, int width, int height) {
this.title = title;
this.width = width;
this.height = height;
init();
}
private void keyPressed(int key, int scancode, int mods) {
}
private void keyReleased(int key, int scancode, int mods) {
if(key == GLFW_KEY_ESCAPE)
glfwSetWindowShouldClose(windowID, GLFW_TRUE);
}
private void init() {
// Setup an error callback. The default implementation
// will print the error message in System.err.
glfwSetErrorCallback(errorCallback = GLFWErrorCallback.createPrint(System.err));
if(glfwInit() != GLFW_TRUE)
throw new IllegalStateException("Unable to initialize GLFW");
glfwDefaultWindowHints();
glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
windowID = glfwCreateWindow(width, height, title, NULL, NULL);
if(windowID == NULL)
throw new RuntimeException("Failed to create the GLFW window");
glfwSetKeyCallback(windowID, keyCallback = new GLFWKeyCallback() {
#Override
public void invoke(long window, int key, int scancode, int action, int mods) {
if(action == GLFW_PRESS)
keyPressed(key, scancode, mods);
else if(action == GLFW_RELEASE)
keyReleased(key, scancode, mods);
}
});
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos(windowID, (vidmode.width() - width) / 2, (vidmode.height() - height) / 2);
glfwMakeContextCurrent(windowID);
glfwSwapInterval(1);
loader = new Loader();
renderer = new Renderer();
shader = new StaticShader();
glfwShowWindow(windowID);
}
public void run() {
GL.createCapabilities();
GL11.glViewport(0, 0, width, height);
float[] vertices = {
-0.5f, 0.5f, 0, // V1
-0.5f, -0.5f, 0, // V2
0.5f, -0.5f, 0, // V3
0.5f, 0.5f, 0 // V4
};
int[] indices = {
0, 1, 3,
3, 2, 1
};
RawModel model = loader.loadToVAO(vertices, indices);
while(glfwWindowShouldClose(windowID) == GLFW_FALSE) {
renderer.prepare();
shader.start();
renderer.render(model);
shader.stop();
glfwSwapBuffers(windowID);
glfwPollEvents();
}
shader.cleanUp();
loader.cleanUp();
}
}
Here is the method where it's tracing back to.
private static int loadShader(String file, int type) {
StringBuilder shaderSource = new StringBuilder();
try {
BufferedReader reader = new BufferedReader(new FileReader(file));
String line;
while((line = reader.readLine()) != null) {
shaderSource.append(line).append("\n");
}
reader.close();
} catch(IOException e) {
System.err.print("Count not read file!");
e.printStackTrace();
System.exit(-1);
}
int shaderID = GL20.glCreateShader(type);
GL20.glShaderSource(shaderID, shaderSource);
GL20.glCompileShader(shaderID);
if(GL20.glGetShaderi(shaderID, GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE) {
System.out.println(GL20.glGetShaderInfoLog(shaderID, 500));
System.err.println("Could not compile shader!");
System.exit(-1);
}
return shaderID;
}
Your code tries to use OpenGL before you have created the context.
The init method in which the shader is created is called in the constructor, but the context is created in the begin of the run method. To solve this, move the call of the init method to the run method after GL.createCapabilities();.
Please also note, that OpenGL contexts are always associated with exactly one thread. So all OpenGL commands have to be issued from this one thread.

Cannot Create VAO in LWJGL3

Whenever i try to populate a VAO, i get a null pointer exception
Error
Hello LWJGL 3.0.0a!
2.1 INTEL-10.0.86
Exception in thread "main" java.lang.NullPointerException
at org.lwjgl.opengl.GL30.nglGenVertexArrays(GL30.java:3265)
at org.lwjgl.opengl.GL30.glGenVertexArrays(GL30.java:3294)
at javaapplication73.Loader.createVAO(Loader.java:35)
at javaapplication73.Loader.loadToVao(Loader.java:27)
at javaapplication73.HelloWorld.initial(HelloWorld.java:139)
at javaapplication73.HelloWorld.loop(HelloWorld.java:120)
at javaapplication73.HelloWorld.run(HelloWorld.java:32)
at javaapplication73.HelloWorld.main(HelloWorld.java:154)
Java Result: 1
The code that throws this exception is the createVAO method in this Loader class.
package javaapplication73;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
public class Loader {
private List<Integer> vaos = new ArrayList<Integer>();
private List<Integer> vbos = new ArrayList<Integer>();
public RawModel loadToVao(float[] positions){
int vaoID = this.createVAO();
this.storeDataInAttributeList(0, positions);
this.unbindVAO();
return new RawModel(1, positions.length/3);
}
private int createVAO(){
int vaoID = GL30.glGenVertexArrays();
vaos.add(vaoID);
GL30.glBindVertexArray(vaoID);
return vaoID;
}
public void storeDataInAttributeList(int attributeNumber, float[] data){
int vboID = GL15.glGenBuffers();
vbos.add(vboID);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboID);
FloatBuffer buffer =storeDataInFloatBuffer(data);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(attributeNumber, 3, GL11.GL_FLOAT, false, 0, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
public void unbindVAO(){
//unbind the array
GL30.glBindVertexArray(0);
}
private FloatBuffer storeDataInFloatBuffer(float[] data){
FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length);
buffer.put(data);
//need to flip between wright and read
buffer.flip();
return buffer;
}
public void cleanUp(){
for (Integer vao : this.vaos) {
GL30.glDeleteVertexArrays(vao);
}
for(Integer vbo : this.vbos){
GL15.glDeleteBuffers(vbo);
}
}
}
I don't think that this class is really needed, but this is my main class
package javaapplication73;
import org.lwjgl.Sys;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;
import java.nio.ByteBuffer;
import static org.lwjgl.glfw.Callbacks.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryUtil.*;
public class HelloWorld {
// We need to strongly reference callback instances.
private GLFWErrorCallback errorCallback;
private GLFWKeyCallback keyCallback;
// The window handle
private long window;
private final int fpsCap = 120;
Loader loader = new Loader();
Renderer renderer = new Renderer();
private RawModel model;
public void run() {
System.out.println("Hello LWJGL " + Sys.getVersion() + "!");
try {
init();
loop();
// Release window and window callbacks
glfwDestroyWindow(window);
keyCallback.release();
} finally {
// Terminate GLFW and release the GLFWerrorfun
glfwTerminate();
errorCallback.release();
}
}
private void init() {
// Setup an error callback. The default implementation
// will print the error message in System.err.
glfwSetErrorCallback(errorCallback = errorCallbackPrint(System.err));
// Initialize GLFW. Most GLFW functions will not work before doing this.
if ( glfwInit() != GL11.GL_TRUE )
throw new IllegalStateException("Unable to initialize GLFW");
// Configure our window
glfwDefaultWindowHints(); // optional, the current window hints are already the default
glfwWindowHint(GLFW_VISIBLE, GL_FALSE); // the window will stay hidden after creation
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE); // the window will be resizable
int WIDTH = 1200;
int HEIGHT = 800;
// Create the window
window = glfwCreateWindow(WIDTH, HEIGHT, "Not so Still Life", NULL, NULL);
if ( window == 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.
glfwSetKeyCallback(window, keyCallback = new GLFWKeyCallback() {
#Override
public void invoke(long window, int key, int scancode, int action, int mods) {
if ( key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE )
glfwSetWindowShouldClose(window, GL_TRUE); // We will detect this in our rendering loop
cleanUp();
}
});
// Get the resolution of the primary monitor
ByteBuffer vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
// Center our window
glfwSetWindowPos(
window,
(GLFWvidmode.width(vidmode) - WIDTH) / 2,
(GLFWvidmode.height(vidmode) - HEIGHT) / 2
);
// Make the OpenGL context current
glfwMakeContextCurrent(window);
// Enable v-sync
glfwSwapInterval(1);
// Make the window visible
glfwShowWindow(window);
}
private void loop() {
// This line is critical for LWJGL's interoperation with GLFW's
// OpenGL context, or any context that is managed externally.
// LWJGL detects the context that is current in the current thread,
// creates the ContextCapabilities instance and makes the OpenGL
// bindings available for use.
GLContext.createFromCurrent();
// Set the clear color
glClearColor(.3243f,0,.83251234f,0);
// Run the rendering loop until the user has attempted to close
// the window or has pressed the ESCAPE key.
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, 800, 0, 600, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
while ( glfwWindowShouldClose(window) == GL_FALSE ) {
// Clear the screen and depth buffer
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
initial();
Render();
glfwSwapBuffers(window); // swap the color buffers
glfwPollEvents();
}
}
public void initial(){
System.out.println(glGetString(GL_VERSION));
//Pre game stuff
float[] verticies = {
-0.5f, 0.5f, 0f,
-0.5f, -0.5f, 0f,
0.5f, -0.5f, 0f,
0.5f, -0.5f, 0f,
0.5f, 0.5f, 0f,
-0.5f, 0.5f, 0f,
};
model = loader.loadToVao(verticies);
}
public void Render(){
renderer.prepare();
renderer.Render(model);
}
public void cleanUp(){
System.out.println("CleanUp");
this.loader.cleanUp();
}
public static void main(String[] args) {
System.setProperty("org.lwjgl.librarypath", "/Users/Bayjose/LWJGL/lwjgl/native");
new HelloWorld().run();
}
}
The computer that I am codeing this on is a Macbook Pro 2014 model, running osx Yosemite 10.10.1
Dont know if that has anything to do with the error or not

Categories

Resources