OpenGL 4.3 Java Not Rendering in Window - java

I'm following the OpenGL 3D Game Tutorial series by ThinMatrix and everything seems to work fine except nothing appears in the window. I got to the 5th video.
My Loader Class
package org.voxsim;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
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 Models loadToVao(float[] pos, int[] ind) {
int vaoId = createVao();
bindIndBuffer(ind);
storeData(0,pos);
unbind();
return new Models(vaoId, ind.length);
}
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 storeData(int num, float[] data) {
int VboId = GL15.glGenBuffers();
vbos.add(VboId);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, VboId);
FloatBuffer buffer = storeInFloatBuffer(data);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(num,3,GL11.GL_FLOAT,false,0,0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
private void unbind() {
GL30.glBindVertexArray(0);
}
private void bindIndBuffer(int[] ind) {
int vboId = GL15.glGenBuffers();
vbos.add(vboId);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboId);
IntBuffer buffer = storeInIntBuffer(ind);
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
}
private IntBuffer storeInIntBuffer(int[] data) {
IntBuffer buffer = BufferUtils.createIntBuffer(data.length);
buffer.put(data);
buffer.flip();
return buffer;
}
private FloatBuffer storeInFloatBuffer(float[] data) {
FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length);
buffer.put(data);
buffer.flip();
return buffer;
}
}
My Render Class
package org.voxsim;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
public class Render {
public void render(Models model) {
GL11.glColor4f(0.5f, 0.9f, 0.2f, 1.0f);
GL30.glBindVertexArray(model.getVaoID());
GL20.glEnableVertexAttribArray(0);
GL11.glDrawElements(GL11.GL_TRIANGLES, model.getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
GL20.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
}
}
My Model Class
package org.voxsim;
public class Models {
private int vaoID;
private int vaoNum;
public Models(int vaoID, int vaoNum) {
this.vaoID = vaoID;
this.vaoNum = vaoNum;
}
public int getVaoID() {
return vaoID;
}
public int getVertexCount() {
return vaoNum;
}
}
My Main Class
package org.voxsim;
import static org.lwjgl.glfw.GLFW.glfwWindowShouldClose;
import static org.lwjgl.opengl.GL11.GL_FALSE;
import org.lwjgl.opengl.GL30;
import org.lwjgl.opengl.GLCapabilities;
import org.voxsim.game.Block;
import org.voxsim.shaders.Shader;
import org.voxsim.shaders.Static;
public class Game {
static public int width = 600;
static public int height = 400;
static public int vsync = 1;
static public String title = "VoxSim";
static private Loader loader = new Loader();
static private Render render = new Render();
private static void loop() {
Shader shader = new Static();
float[] v = {
-0.5f,0.5f,0,
-0.5f,-0.5f,0,
0.5f,-0.5f,0,
0.5f,0.5f,0
};
int[] ind = {
0,1,3,
3,1,2
};
Models model = loader.loadToVao(v, ind);
while (glfwWindowShouldClose(DisplayManager.windowID) == GL_FALSE) {
DisplayManager.updateDisplay();
shader.start();
render.render(model);
shader.stop();
}
shader.cleanUp();
}
public static void main(String[] args) {
DisplayManager.createDisplay();
DisplayManager.updateDisplay();
loop();
loader.cleanUp();
}
}
I followed the tutorial exactly but I don't know what's wrong. I am running an intel 4th gen i3 with intel hd graphics 4400 with 4GB of ram on windows 10 with
OpenGL Version 4.3,
OpenCL Version 1.2, and
Shader Model Version 5

Related

Error when calling GL30.glGenVertexArrays();

i am trying to learn usinf opengl and lwjgl with java and i have amde a program and am trying to render some mesh but the class handling the Vaos and Vbos is faulty.After doing some research , i have learnt that this may be cause because of the position of my calling the method relative to the MakecontextCurrent(); method but i got no luck there.
Warning
Alot of code ahead
The faulty class
package renderEngine;
import java.nio.FloatBuffer;
import java.util.*;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.*;
public class Loader {
private List<Integer>vaos = new ArrayList<Integer>();
private List<Integer>vbos = new ArrayList<Integer>();
public RawModel loadToVao(float[] positions) {
int vaoID = createVAO();
storeDataInAttributeList(0, positions);
unbind();
return new RawModel(vaoID,positions.length/3);
}
public void cleanup() {
for(int vao : vaos) {
GL30.glDeleteVertexArrays(vao);
}
for(int vbo : vbos) {
GL30.glDeleteVertexArrays(vbo);
}
}
public 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);
GL30.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
public void unbind() {
GL30.glBindVertexArray(0);
}
private FloatBuffer storeDataInFloatBuffer(float[] data) {
FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length);
buffer.put(data);
buffer.flip();
return buffer;
}
}
this is the class which handles the gameloop
package renderEngine;
import org.lwjgl.glfw.GLFW;
public class MainGameLoop implements Runnable{
public Loader loader;
public Thread gamethread;
public DisplayManager display;
public RawModel model;
Renderer renderer;
public static void main(String[] args) {
new MainGameLoop().start();
}
private void start() {
gamethread = new Thread(this , "game");
gamethread.start();
}
#Override
public void run() {
init();
while (!display.shouldClose()) {
update();
render();
}
loader.cleanup();
}
private void render() {
renderer.prepare();
renderer.renderModel(model);
display.render();
}
private void update() {
display.update();
}
private void init() {
float[] vertices = new float[] {
0.5f , 0.5f , 0.0f , -0.5f , 0.5f , 0.0f , -0.5f , -0.5f , 0.0f , 0.5f , -0.5f , 0.0f
};
loader = new Loader();
display = new DisplayManager(900, 500, "Our Game",GLFW.glfwGetPrimaryMonitor());
display.createDisplay();
model = loader.loadToVao(vertices);
renderer = new Renderer();
}
}
Class handling the window creating
package renderEngine;
import static org.lwjgl.glfw.GLFW.*;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.opengl.GL;
public class DisplayManager {
public int width , height;
public String title;
public long monitor = 0;
private long window;
public DisplayManager(int width , int height , String title , long monitor) {
this.width = width;
this.title = title;
this.height = height;
this.monitor = monitor;
}
public void createDisplay() {
if(glfwInit()) {
//handle initialization error
System.err.println("Error001:FailedInitialization");
}
//create window
window = glfwCreateWindow(width, height, title,monitor , 0);
if (window == 0) {
//handle window creation error
System.err.println("Error002:FailedDisplayCreation");
}
//create vidmode
GLFWVidMode vm = glfwGetVideoMode(glfwGetPrimaryMonitor());
int xpos = vm.width()/2-width/2, ypos = vm.height()/2-height/2;
//set position to center
glfwSetWindowPos(window, xpos, ypos);
glfwMakeContextCurrent(ypos);
GL.createCapabilities();
//show window
glfwShowWindow(window);
}
public void destroyWindow() {
glfwDestroyWindow(window);
glfwTerminate();
}
public void render() {
glfwSwapBuffers(window);
}
public void update() {
glfwPollEvents();
}
public boolean shouldClose() {
return glfwWindowShouldClose(window);
}
}
The renderer
package renderEngine;
import org.lwjgl.opengl.*;
public class Renderer {
public void prepare() {
GL11.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
GL11.glClear(GL15.GL_ARRAY_BUFFER);
}
public void renderModel(RawModel model) {
GL30.glBindVertexArray(model.getVaoID());
GL30.glEnableVertexAttribArray(0);
GL11.glDrawArrays(GL11.GL_TRIANGLES,0, model.getVertexCount());
GL20.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
}
}
the raw model
package renderEngine;
import org.lwjgl.opengl.*;
public class Renderer {
public void prepare() {
GL11.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
GL11.glClear(GL15.GL_ARRAY_BUFFER);
}
public void renderModel(RawModel model) {
GL30.glBindVertexArray(model.getVaoID());
GL30.glEnableVertexAttribArray(0);
GL11.glDrawArrays(GL11.GL_TRIANGLES,0, model.getVertexCount());
GL20.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
}
}
The error
FATAL ERROR in native method: Thread[game,5,main]: No context is current or a function that is not
available in the current context was called. The JVM will abort execution.
at org.lwjgl.opengl.GL30C.nglGenVertexArrays(Native Method)
at org.lwjgl.opengl.GL30C.glGenVertexArrays(GL30C.java:2420)
at org.lwjgl.opengl.GL30.glGenVertexArrays(GL30.java:2369)
at renderEngine.Loader.createVAO(Loader.java:28)
at renderEngine.Loader.loadToVao(Loader.java:13)
at renderEngine.MainGameLoop.init(MainGameLoop.java:47)
at renderEngine.MainGameLoop.run(MainGameLoop.java:21)
at java.lang.Thread.run(java.base#11.0.8/Thread.java:834)
Your error is juste a simple mistake in declaration order.
Reorder these line in your MainGameLoop class :
loader = new Loader();
display = new DisplayManager(900, 500, "Our Game",GLFW.glfwGetPrimaryMonitor());
display.createDisplay();
Like this :
display = new DisplayManager(900, 500, "Our Game",GLFW.glfwGetPrimaryMonitor());
display.createDisplay();
loader = new Loader();
Because in your Loader class you call OpenGL function (GL30.glGenVertexArrays();) but you cannot call OpenGL function if no context have been already setup.You setup an OpenGL context with GL.createCapabilities();, and this line is in your DisplayManager class.So the GL.createCapabilities(); is executed after the call to OpenGL function in your MainGameLoop class (in reality is never executed because the JVM will crash before).

Slick TextureLoader.getTexture cannot be resolved to a type

I think it is just the wrong implementation of the Libary, but i don' know how to resolve it.
funktion
It seems like the class Texture (org.newdawn.slick.opengl.Texture) doesn't work or...
Imports work...
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
I realy don't know, whats going on.
package Main.graphics;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL30.*;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.List;
import org.lwjgl.BufferUtils;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import Main.models.Model;
public class ModelLoader {
// nach Thin Matrix
private List<Integer> vaos = new ArrayList<Integer>();
private List<Integer> vbos = new ArrayList<Integer>();
private List<Integer> textures = new ArrayList<Integer>();
public Model loadToVAO(float[] positions, int[] indices) {
int vaoID = createVAO();
bindIndicesBuffer(indices);
storeDataInAttribList(0, positions);
unbindVAO();
return new Model(vaoID, indices.length);
}
public void destroyAll() {
for (int vao : vaos) {
glDeleteVertexArrays(vao);
}
for (int vbo : vbos) {
glDeleteBuffers(vbo);
}
for (int texture : textures) {
glDeleteTextures(texture);
}
}
public int loadTexture(String textureReference) {
Texture texture = null; // <--- light blue (seen as variable name?)
try {
texture = new TextureLoader.getTexture("PNG", new FileInputStream("res/" + textureReference + ".png"));
} catch (FileNotFoundException e) { // ^ TextureLoader.getTexture cannot be resolved to a type
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
int textureID = texture.getTextureID();
textures.add(textureID);
return textureID;
}
private int createVAO() {
int vaoID = glGenVertexArrays();
vaos.add(vaoID);
glBindVertexArray(vaoID);
return vaoID;
}
private void unbindVAO() {
glBindVertexArray(0);
}
private void bindIndicesBuffer(int[] indices) {
int vboID = glGenBuffers();
vbos.add(vboID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboID);
IntBuffer buffer = storeDataInIntBuffer(indices);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, buffer, GL_STATIC_DRAW);
}
private void storeDataInAttribList(int attribNumber, float[] data) {
int vboID = glGenBuffers();
vbos.add(vboID);
glBindBuffer(GL_ARRAY_BUFFER, vboID);
FloatBuffer buffer = storeDataInFloatBuffer(data);
glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW);
glVertexAttribPointer(attribNumber, 3, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
private IntBuffer storeDataInIntBuffer(int[] data) {
IntBuffer buffer = BufferUtils.createIntBuffer(data.length);
buffer.put(data);
buffer.flip();
return buffer;
}
private FloatBuffer storeDataInFloatBuffer(float[] data) {
FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length);
buffer.put(data);
buffer.flip();
return buffer;
}
}

JOGL failure; whatever I do is black screen. Shaders malfunctioning, glGetAttribLocation returns -1

I have a JOGL failure. I simply can't make it display anything. I've made Android OpenGL ES work, but I have 2 big problems here. First, nothing displays. Second, none of my variables exist for the shader compiler.
I am sorry that this is not a SSCEE. I just have this stinky bug and I can't reproduce it with shorter code.
import java.awt.Dimension;
import java.io.File;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import javax.swing.JFrame;
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.awt.GLCanvas;
import com.leonidnediak.labyrinth.annoyingGLstuff.ShaderStuff;
import com.leonidnediak.labyrinth.util.FileUtil;
public class Main implements GLEventListener {
public static File codeSource;
static {
try {
codeSource = new File(Main.class.getProtectionDomain().getCodeSource().getLocation().toURI());
} catch (URISyntaxException e) {
}
}
public static final Dimension size = new Dimension(400, 600);
public static int program;
public static int aColorLocation;
public static int aPositionLocation;
public static int uMatrixLocation;
public static void main(String[] args) {
GLProfile profile = GLProfile.get(GLProfile.GL2);
GLCapabilities cap = new GLCapabilities(profile);
GLCanvas canvas = new GLCanvas(cap);
canvas.addGLEventListener(new Main());
canvas.setSize(size);
JFrame frame = new JFrame();
frame.setSize(size);
frame.setResizable(false);
frame.add(canvas);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
#Override
public void display(GLAutoDrawable autoDrawable) {
GL2 gl = autoDrawable.getGL().getGL2();
gl.glClear(GL2.GL_COLOR_BUFFER_BIT);
gl.glEnableVertexAttribArray(aPositionLocation);
FloatBuffer vertexBuffer = ByteBuffer.allocateDirect(4*9).asFloatBuffer();
vertexBuffer.put(new float[] {-1, 1, 0, 0, -1, 0, 1, 1, 0});
vertexBuffer.position(0);
gl.glVertexAttribPointer(aPositionLocation, 3, GL2.GL_FLOAT, false, 12, vertexBuffer);
gl.glEnableVertexAttribArray(aColorLocation);
FloatBuffer colorBuffer = ByteBuffer.allocateDirect(4*9).asFloatBuffer();
colorBuffer.put(new float[] {1, 1, 1, 1, 1, 1, 1, 1, 1});
colorBuffer.position(0);
gl.glVertexAttribPointer(aPositionLocation, 3, GL2.GL_FLOAT, false, 12, colorBuffer);
gl.glDrawArrays(GL2.GL_TRIANGLES, 0, 3);
}
#Override
public void dispose(GLAutoDrawable autoDrawable) {
}
#Override
public void init(GLAutoDrawable autoDrawable) {
GL2 gl = autoDrawable.getGL().getGL2();
program = ShaderStuff.buildProgram(gl, FileUtil.fileContents(new File(codeSource, "vertexShader.glsl")), FileUtil.fileContents(new File(codeSource, "fragmentShader.glsl")));
int[] arr = new int[1];
gl.glGetProgramiv(program, GL2.GL_ACTIVE_ATTRIBUTES, arr, 0);
System.out.println(arr[0]);
aColorLocation = gl.glGetAttribLocation(program, "a_Color");
aPositionLocation = gl.glGetAttribLocation(program, "a_Position");
uMatrixLocation = gl.glGetUniformLocation(program, "u_Matrix");
System.out.println(program);
gl.glUniformMatrix4fv(uMatrixLocation, 1, false, new float[] {1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1}, 0);
}
#Override
public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4) {
}
}
sorry for indentation, stackoverflow forces me to indent a lot.
That's my Main class.
Here's my ShaderStuff:
import com.jogamp.opengl.GL2;
public class ShaderStuff {
public static int compileVertexShader(GL2 gl, String shaderCode) {
return compileShader(gl, GL2.GL_VERTEX_SHADER, shaderCode);
}
public static int compileFragmentShader(GL2 gl, String shaderCode) {
return compileShader(gl, GL2.GL_FRAGMENT_SHADER, shaderCode);
}
private static int compileShader(GL2 gl, int type, String shaderCode) {
final int shaderObjectId = gl.glCreateShader(type);
if (shaderObjectId == 0) {
return 0;
}
gl.glShaderSource(shaderObjectId, 1, new String[] {shaderCode}, null);
gl.glCompileShader(shaderObjectId);
final int[] compileStatus = new int[1];
gl.glGetShaderiv(shaderObjectId, GL2.GL_COMPILE_STATUS, compileStatus, 0);
if (compileStatus[0] == 0) {
//gl.glDeleteShader(shaderObjectId);
//return 0;
}
return shaderObjectId;
}
public static int linkProgram(GL2 gl, int vertexShaderId, int fragmentShaderId) {
final int programObjectId = gl.glCreateProgram();
if (programObjectId == 0) {
return 0;
}
gl.glAttachShader(programObjectId, vertexShaderId);
gl.glAttachShader(programObjectId, fragmentShaderId);
gl.glLinkProgram(programObjectId);
final int[] linkStatus = new int[1];
gl.glGetProgramiv(programObjectId, GL2.GL_LINK_STATUS, linkStatus, 0);
if (linkStatus[0] == 0) {
//gl.glDeleteProgram(programObjectId);
//return 0;
}
return programObjectId;
}
public static int buildProgram(GL2 gl, String vertexS, String fragS) {
int program;
int vertexShader = compileVertexShader(gl, vertexS);
int fragmentShader = compileVertexShader(gl, fragS);
program = linkProgram(gl, vertexShader, fragmentShader);
validateProgram(gl, program);
return program;
}
public static boolean validateProgram(GL2 gl, int programObjectId) {
gl.glValidateProgram(programObjectId);
final int[] validateStatus = new int[1];
gl.glGetProgramiv(programObjectId, GL2.GL_VALIDATE_STATUS, validateStatus, 0);
return validateStatus[0] != 0;
}
}
EDIT: the problem is in my GLSL but I can't find my failure.
Vertex Shader:
attribute vec4 a_Color;
attribute vec4 a_Position;
uniform mat4 u_Matrix;
varying vec4 v_Color;
void main()
{
v_Color = a_Color;
gl_Position = u_Matrix * a_Position;
gl_PointSize = 1.0;
}
Fragment Shader:
precision mediump float;
varying vec4 v_Color;
void main()
{
gl_FragColor = v_Color;
}
few observations/hints:
keeps locations hierarchical, like here, it's less error prone and keeps your code more readable:
public class Semantic { // or Location
public static class Attr {
public static int POSITION = 0;
public static int COLOR = 3;
}
}
don't allocate a new FloatBuffer every frame in the display(), initialize it in the init() and reuse it. You can use one utility of mine to dispose it, I'll tell you later.
Avoid reinventing the wheel, you could avoid your ShaderStuff class completely, use what jogl already provides us, here an example. it will automatically print out any compilation error.
which GLES versione are you targetting? Becuase in the shaders varying is deprecated, use in and out instead
same for gl_FragColor, use out vec4 FragColor;
We have others jogl users that is working in this direction, we could create a simple and clear hello triangle sample explicitely made for android, would that be interesting for you?

LWJGL OpenGL glGenVertexArrays() Error: This Function is not available

All, Having difficulty with glGenVertexArrays(). I get the following error:
Exception in thread "main" java.lang.IllegalStateException: This functionality is not available.
at org.lwjgl.system.Checks.checkFunctionality(Checks.java:57)
at org.lwjgl.opengl.GL30.getInstance(GL30.java:667)
at org.lwjgl.opengl.GL30.getInstance(GL30.java:662)
at org.lwjgl.opengl.GL30.nglGenVertexArrays(GL30.java:2789)
at org.lwjgl.opengl.GL30.glGenVertexArrays(GL30.java:2816)
at renderEngine.Loader.createVAO(Loader.java:26)
at renderEngine.Loader.loadToVAO(Loader.java:19)
at renderEngine.MainGameLoop.main(MainGameLoop.java:27)
Here is my Main Game Loop (I call GL.createCapabilities() from the createDisplay() method.)
package renderEngine;
import static org.lwjgl.glfw.GLFW.*;
public class MainGameLoop {
public static DisplayManager dm = new DisplayManager();
public static void main(String[] args) {
//Create Display
dm.createDisplay();
Loader loader = new Loader();
Renderer renderer = new Renderer();
float[] vertices = {
-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
};
RawModel model = loader.loadToVAO(vertices);
//Game Loop
while (glfwWindowShouldClose(dm.getWindowID()) != GLFW_TRUE) {
renderer.prepare();
renderer.render(model);
dm.updateDisplay();
}
//Destroy Display
dm.destroyWindow();
loader.cleanUp();
}
}
As referenced above, here is the Display Manager class:
package renderEngine;
import static org.lwjgl.glfw.GLFW.*;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.glfw.GLFWKeyCallback;
import org.lwjgl.opengl.GL;
public class DisplayManager {
private GLFWErrorCallback errorCallback;
private GLFWKeyCallback keyCallback;
private long windowID;
//Constructor
public DisplayManager(){
init();
}
private void init(){
if(glfwInit() != GLFW_TRUE){
throw new IllegalStateException("Unable to initiate GLFW");
}
}
public long createDisplay(){
windowID = glfwCreateWindow(640,480,"Hello World!", 0, 0);
if(windowID == 0){
glfwTerminate();
throw new RuntimeException("Failed to create the GLFW window");
}
GLFW.glfwSetWindowTitle(windowID, "GLFW Window");
setErrorCallback();
setKeyCallback();
glfwMakeContextCurrent(windowID);
GL.createCapabilities();
return windowID;
}
public long getWindowID(){
return this.windowID;
}
private void setErrorCallback(){
errorCallback = GLFWErrorCallback.createPrint(System.err);
glfwSetErrorCallback(errorCallback);
}
private void setKeyCallback(){
keyCallback = new GLFWKeyCallback(){
#Override
public void invoke(long window, int key, int scancode, int action, int mods) {
if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS){
glfwSetWindowShouldClose(window, GLFW_TRUE);
}
}
};
glfwSetKeyCallback(windowID, keyCallback);
}
public void updateDisplay(){
GLFW.glfwSwapInterval(1);
glfwSwapBuffers(windowID);
glfwPollEvents();
}
public void destroyWindow(){
glfwDestroyWindow(windowID);
keyCallback.release();
glfwTerminate();
errorCallback.release();
}
}
If would seem the above mentioned error is with the loader class:
package renderEngine;
import java.util.List;
import java.nio.FloatBuffer;
import java.util.ArrayList;
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 = createVAO();
storeDataInAttributeList(0,positions);
unbindVAO();
return new RawModel(vaoID,positions.length/3);
}
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); //0 un-binds currently bound VAO
}
public void cleanUp(){
for(int vao:vaos){
GL30.glDeleteVertexArrays(vao);
}
for(int vbo:vbos){
GL15.glDeleteBuffers(vbo);
}
}
private FloatBuffer storeDataInFloatBuffer(float[] data){
FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length);
buffer.put(data);
buffer.flip();
return buffer;
}
}
In Particular this line of code:
GL30.glBindVertexArray(vaoID);
As far as I can see this is the correct method to do it, and the GL capabilities/context have been set/called from the main thread (main game loops main method, utilising the display manager)
For completeness, here are the RawModel and Renderer Classes, do not suspect an issue these these:
package renderEngine;
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;
}
}
And here is the Renderer Class:
package renderEngine;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
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);
GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, model.getVertexCount());
GL20.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
}
}
Any assistance you can give me regarding my implementation of 'glGenVertexArrays' would be much appreciated.
I have now added the following
GLFW.glfwDefaultWindowHints();
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 3);
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 2);
However, am now getting the following error:
Exception in thread "main" java.lang.RuntimeException: Failed to create the GLFW window
at renderEngine.DisplayManager.createDisplay(DisplayManager.java:37)
at renderEngine.MainGameLoop.main(MainGameLoop.java:12)
The specific implementation of my createDisplay() is as follows:
public long createDisplay(){
GLFW.glfwDefaultWindowHints();
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 3);
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 2);
windowID = glfwCreateWindow(640,480,"Hello World!", 0, 0);
if(windowID == 0){
glfwTerminate();
throw new RuntimeException("Failed to create the GLFW window");
}
GLFW.glfwSetWindowTitle(windowID, "GLFW Window");
setErrorCallback();
setKeyCallback();
glfwMakeContextCurrent(windowID);
GL.createCapabilities();
return windowID;
}
UPDATE
If have removed the error callbacks, as thought they might be causing an issue. The resulting error is:
Exception in thread "main" java.lang.RuntimeException: Failed to create the GLFW window
at renderEngine.DisplayManager.createDisplay(DisplayManager.java:40)
at renderEngine.MainGameLoop.main(MainGameLoop.java:12)
It seems the RuntimeException is being thrown, and is displaying my custom error message if the glfw window cannot be created. Could this be todo with the order in which I run this? I have played around with the placement of the 'init' method with noluck. There has got to be something I am overlooking?... Thanks.
Updated code for the Display Manager:
package renderEngine;
import static org.lwjgl.glfw.GLFW.*;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.glfw.GLFWKeyCallback;
import org.lwjgl.opengl.GL;
public class DisplayManager {
private GLFWErrorCallback errorCallback;
private GLFWKeyCallback keyCallback;
private long windowID;
//Constructor
public DisplayManager(){
init();
}
private void init(){
if(glfwInit() != GLFW_TRUE){
throw new IllegalStateException("Unable to initiate GLFW");
}
}
public long createDisplay(){
GLFW.glfwDefaultWindowHints();
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 3);
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 2);
windowID = glfwCreateWindow(640,480,"Hello World!", 0, 0);
System.out.println(windowID);
if(windowID == 0){
glfwTerminate();
throw new RuntimeException("Failed to create the GLFW window");
}
glfwMakeContextCurrent(windowID);
GL.createCapabilities();
GLFW.glfwSetWindowTitle(windowID, "GLFW Window");
//setErrorCallback();
//setKeyCallback();
return windowID;
}
public long getWindowID(){
return this.windowID;
}
private void setErrorCallback(){
errorCallback = GLFWErrorCallback.createPrint(System.err);
glfwSetErrorCallback(errorCallback);
}
private void setKeyCallback(){
keyCallback = new GLFWKeyCallback(){
#Override
public void invoke(long window, int key, int scancode, int action, int mods) {
if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS){
glfwSetWindowShouldClose(window, GLFW_TRUE);
}
}
};
glfwSetKeyCallback(windowID, keyCallback);
}
public void updateDisplay(){
GLFW.glfwSwapInterval(1);
glfwSwapBuffers(windowID);
glfwPollEvents();
}
public void destroyWindow(){
glfwDestroyWindow(windowID);
keyCallback.release();
glfwTerminate();
errorCallback.release();
}
}
Many Thanks and Kind Regards,
Jake
The glGenVertexArrays function requires OpenGL 3.0 or higher. You have to explicitly tell GLFW this. Before calling glfwCreateWindow:
GLFW.glfwDefaultWindowHints();
GLFW.glfwWindowHint(GLFW.CONTEXT_VERSION_MAJOR, 3);
GLFW.glfwWindowHint(GLFW.CONTEXT_VERSION_MINOR, 0);
You can check that you have OpenGL 3.0 or higher by calling GL11.glGetString(GL11.GL_VERSION) or by looking at the GL.getCapabilities().OpenGL30 flag.

LWJGL3 shader, triangle not showing up

I'm new to OpenGL and LWJGL3 and I'm trying to render a triangle. However, it isn't showing up, only the white, empty window. I guess it's a pretty small piece that I somehow forgot or where I just made a mistake. I don't find it after searching for hours now though. Here's the code:
MainLoop:
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL30.*;
import static org.lwjgl.glfw.GLFW.*;
public class MainLoop {
private DisplayManager displayManager;
private Shader shader;
public MainLoop() {
displayManager = new DisplayManager();
displayManager.createDisplay();
shader = new Shader("src/shader.vert", "src/shader.frag");
}
private void start() {
float positions[] = {
-0.5f, 0.0f, 0.0f,
0.5f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f
};
int vao = glGenVertexArrays();
glBindVertexArray(vao);
int positionVbo = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, positionVbo);
glBufferData(GL_ARRAY_BUFFER, BufferUtils.createFloatBuffer(positions), GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
while(!displayManager.isCloseRequested()) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArray(vao);
render();
update();
displayManager.swapBuffers();
}
shader.cleanUp();
displayManager.destroyDisplay();
}
private void update() {
glfwPollEvents();
}
private void render() {
shader.bind();
//rendering stuff
glDrawArrays(GL_TRIANGLES, 0, 3);
shader.unbind();
}
public static void main(String[] args) {
new MainLoop().start();
}
}
Shader:
import static org.lwjgl.opengl.GL11.GL_FALSE;
import static org.lwjgl.opengl.GL20.*;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
public class Shader {
private int program;
public Shader(final String vertexShaderFilePath, final String fragmentShaderFilePath) {
int vertexShader = createShader(loadShaderSource(vertexShaderFilePath), GL_VERTEX_SHADER);
int fragmentShader = createShader(loadShaderSource(fragmentShaderFilePath), GL_FRAGMENT_SHADER);
program = glCreateProgram();
glAttachShader(vertexShader, program);
glAttachShader(fragmentShader, program);
glLinkProgram(program);
glValidateProgram(program); //just during development
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
}
private String loadShaderSource(final String shaderFilePath) {
String shaderSourceString = "";
try {
shaderSourceString = new String(Files.readAllBytes(Paths.get(shaderFilePath)));
} catch (IOException e) {
e.printStackTrace();
}
return shaderSourceString;
}
private int createShader(final String shaderSourceString, final int type) {
int shader = glCreateShader(type);
glShaderSource(shader, shaderSourceString);
glCompileShader(shader);
checkShaderCompileError(shader);
return shader;
}
private void checkShaderCompileError(int shader) {
if(glGetShaderi(shader, GL_COMPILE_STATUS) == GL_FALSE) {
System.err.println("Could not compile shader.");
System.err.println(glGetShaderInfoLog(program));
System.exit(-1);
}
}
public void bind() {
glUseProgram(program);
}
public void unbind() {
glUseProgram(0);
}
public void cleanUp() {
glDeleteProgram(program);
}
}
BufferUtils:
import java.nio.FloatBuffer;
public class BufferUtils {
public static FloatBuffer createFloatBuffer(float[] array) {
FloatBuffer buffer = org.lwjgl.BufferUtils.createFloatBuffer(array.length);
buffer.put(array);
buffer.flip();
return buffer;
}
}
shader.vert:
#version 410 core
layout (location = 0) in vec3 vertex_position;
void main(void)
{
gl_Position = vec4(vertex_position, 1.0);
}
shader.frag:
#version 410 core
out vec4 frag_color;
void main(void)
{
frag_color = vec4(1.0, 0.0, 1.0, 1.0);
}
EDIT: and here's the DisplayManager:
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.system.MemoryUtil.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GLContext.*;
import java.nio.ByteBuffer;
import org.lwjgl.glfw.GLFWvidmode;
public class DisplayManager {
private static final int WIDTH = 1280;
private static final int HEIGHT = 800;
private long window;
private Keyboard keyCallback;
public void createDisplay() {
// initialize GLFW
if(glfwInit() != GL_TRUE) {
System.err.println("GLFW failed to initialize.");
System.exit(-1);
}
// set window hints
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
glfwWindowHint(GLFW_SAMPLES, 4); //16 for production
// create window
window = glfwCreateWindow(WIDTH, HEIGHT, "OpenGL", NULL, NULL);
if(window == NULL) {
System.err.println("GLFW window failed to create.");
glfwTerminate();
System.exit(-1);
}
ByteBuffer videoMode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos(window, (GLFWvidmode.width(videoMode) - WIDTH) / 2, (GLFWvidmode.height(videoMode) - HEIGHT) / 2);
// set callback mechanisms
glfwSetKeyCallback(window, setKeyCallback(new Keyboard()));
// set context and show window
glfwMakeContextCurrent(window);
createFromCurrent();
glfwSwapInterval(1); // v-sync
glfwShowWindow(window);
// openGL functions
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glEnable(GL_DEPTH);
}
public void destroyDisplay() {
glfwDestroyWindow(window);
glfwTerminate();
}
public boolean isCloseRequested() {
if(glfwWindowShouldClose(window) == GL_TRUE) {
return true;
}
return false;
}
public void swapBuffers() {
glfwSwapBuffers(window);
}
public Keyboard getKeyCallback() {
return keyCallback;
}
public Keyboard setKeyCallback(Keyboard keyCallback) {
this.keyCallback = keyCallback;
return keyCallback;
}
}
Does anybody spot what's going wrong?
Thanks in advance!
I finally found the error, the order of parameters for the call glAttachShader(shader, program); were mixed up. You first have to pass the program and then the shader id like so: glAttachShader(program, shader);. Thank you for your answers though!

Categories

Resources