Every time I try to run my LWJGL application the JVM crashes. It seems to be related to adding multiple triangles to my VBO.
Here is my initialization code
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
};
vertexCount = vertices.length / 3;
FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(vertices.length);
verticesBuffer.put(vertices);
verticesBuffer.flip();
vboId = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, verticesBuffer, GL_STATIC_DRAW);
glVertexPointer(vertexCount, GL_FLOAT, 0, 0L);
glBindBuffer(GL_ARRAY_BUFFER, 0);
And this is my rendering code
glEnableClientState(GL_VERTEX_ARRAY);
glDrawArrays(GL_TRIANGLES, 0, vertexCount);
glDisableClientState(GL_VERTEX_ARRAY);
When I remove the last 9 values in the vertices array it works fine, but if I keep those, or add more, the JVM will crash.
The first argument to glVertexPointer is the number of coordinates per vertex, not the number of vertices. So change that line to this:
glVertexPointer(3, GL_FLOAT, 0, 0L);
Related
I am trying to draw a simple, red triangle on screen. Without using an VBO the code works as intended. When trying to draw it by using an VBO (with or without shader), it simply has no effect.
My code:
//Works
glBegin(GL_TRIANGLES);
glVertex3f(0f, 0f, 0.0f);
glVertex3f(0.5f, 0f, 0.0f);
glVertex3f(0.5f, 0.5f, 0.0f);
glEnd();
//Does not work
int vertexArrayID = glGenVertexArrays();
glBindVertexArray(vertexArrayID);
float[] g_vertex_buffer_data = new float[]{
0f, 0f, 0.0f,
0.5f, 00f, 0.0f,
0.5f, 0.5f, 0.0f,
};
int vertexbuffer = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, FloatBuffer.wrap(g_vertex_buffer_data), GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
false, // normalized?
0, // stride
0 // array buffer offset
);
glDrawArrays(GL_TRIANGLES, 0, 3); // 3 indices starting at 0 -> 1 triangle
glDisableVertexAttribArray(0);
glDeleteBuffers(vertexbuffer);
glDeleteVertexArrays(vertexArrayID);
System.out.println(glGetError());
glGetError() always returns 0.
I use a default, tutorial-copied shader to test my code (I link and bind the program before using above code):
#version 330 core
// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vertexPosition_modelspace;
void main(){
gl_Position.xyz = vertexPosition_modelspace;
gl_Position.w = 1.0;
}
#version 330 core
// Ouput data
out vec3 color;
void main()
{
// Output color = red
color = vec3(1,0,0);
}
I want to draw a rectangle in lwjgl. The code should draw a rectangle, but it doesn't. I am using OpenGL 4.4 (LWJGL doesn't support beyond that). I am mostly a beginner in 3d Graphics and such so any help would be greatly appreciated.
float[] vertices= {
0.5f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
-0.5f, 0.5f, 0.0f
};
float[] indices= {
0,1,2,
2,3,0
};
Shader vsh=new Shader("vertexShader.vsh",GL_VERTEX_SHADER);
Shader fsh=new Shader("fragmentShader.fsh",GL_FRAGMENT_SHADER);
sp=Shader.createProgram(vsh.shader,fsh.shader);
int VBO,EBO;
VAO=glGenVertexArrays();
VBO=glGenBuffers();
EBO=glGenBuffers();
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,indices,GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
glEnableVertexAttribArray(0);
glBindVertexArray(0);
glClearColor(1.0f,1.0f,1.0f,1.0f);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
void loop(){
while(!glfwWindowShouldClose(w.window)) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(sp);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6,GL_UNSIGNED_INT,0);
glBindVertexArray(0);
glfwSwapBuffers(w.window);
glfwPollEvents();
}
}
void run() {
init();
loop();
}
public static void main(String[] args) {
new Core().run();
}
It works when I remove the indices and use glDrawArrays instead of glDrawElements.
The type of the array of indices has to be int rather than float:
float[] indices =
int [] indices =
The type of the data in the element array buffer has to match the which is specified when glDrawElements is called.
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT,0);
The specified type must be one of GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, or GL_UNSIGNED_INT. The corresponding data types in java are byte, short respectively int.
Ive been playing around with open GL for a while now and i got to the point that i can draw 3d shapes, My shapes and vertices and indices are definitely right and my shape was getting messed up. I am now wanting to redo my drawing. I used to only use VBO with no VAO and just bind and draw them. This worked but im suspicious of this being my bug. So i started using VAO's and i dont see anything that is wrong with my code and i still cant get it to draw my white square(no shaders just like the wiki tutorials).
My code for initializing the window is here:
private void initWindow() {
//Makes sure window can work
if (!glfwInit()) {
throw new IllegalStateException("Failed to Initialize GLFW!");
}
//Create window object and set its hints
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
this.windowRef = glfwCreateWindow(width, height, name, NULL, NULL);
if (windowRef == 0) {
throw new IllegalStateException("Failed to create Window!");
}
GLFWVidMode videoMode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos(windowRef, (videoMode.width() - width) / 2, (videoMode.height() - height) / 2);
// Make the OpenGL context current
glfwMakeContextCurrent(windowRef);
// Enable v-sync
glfwSwapInterval(1);
//Make GL capabilites for window
GL.createCapabilities();
glfwShowWindow(windowRef);
}
my code for initializing my buffers and objects is here
public void loadGL() {
float[] vertex = {
0f, 0f, 0f, //0
0.5f, 0, 0, //1
0.5f, 0, 0.5f, //2
0f, 0f, 0.5f, //3
0f, 0.5f, 0f, //4
0.5f, 0.5f, 0, //5
0.5f, 0.5f, 0.5f,//6
0f, 0.5f, 0.5f//7
};
int[] index = {
0, 1, 2, //0
0, 2, 3, //1
0, 3, 4, //2
3, 7, 4,//3
0, 4, 1,//4
1, 5, 4,//5
1, 5, 2,//6
2, 6, 5,//7
2, 3, 6,//8
3, 7, 6,//9
4, 5, 7,//10
5, 6, 7//11
};
size = 12*3;
indicesBuff = BufferUtils.createIntBuffer(index.length);
vertBuff = BufferUtils.createFloatBuffer(vertex.length);
indicesBuff.put(index);
vertBuff.put(vertex);
indicesBuff.flip();
vertBuff.flip();
vao = glGenVertexArrays();
glBindVertexArray(vao);
vboID = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, vertBuff, GL_STATIC_DRAW);
GL20.glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
ibo = glGenBuffers();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesBuff, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
and finally my main loop is here, it is called after the window init:
private void mainLoop() {
loadGL();
glClearColor(0.5f, 0.5f, 0.5f, 1);
while (!glfwWindowShouldClose(windowRef)) {
//Render Stuff here
//TODO: later skip this block if nothing has changed
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear
the framebuffer
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, 0);
// glBegin(GL_QUADS);
// glVertex3f(-0.5f, -0.5f, 0);
// glVertex3f(-0.5f, 0.5f, 0);
// glVertex3f(0.5f, -0.5f, 0);
// glVertex3f(0.5f, 0.5f, 0);
// glEnd();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(0);
glBindVertexArray(0);
glfwSwapBuffers(windowRef);
glfwPollEvents();
}
}
btw drawing it with glBegin and so works but its not efficient for what i want to do.
The modern way of rendering in OpenGL, would be to use a Shader program.
If you don't use a shader program, than you have to define the array of vertex data using the deprected way by glVertexPointer and you have to enable the client-side capability for vertex coordinates by glEnableClientState( GL_VERTEX_ARRAY ):
vao = glGenVertexArrays();
glBindVertexArray(vao);
vboID = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, vertBuff, GL_STATIC_DRAW);
GL20.glVertexPointer(3, GL_FLOAT, 0, 0); // <--------------
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(vao);
glEnableClientState( GL_VERTEX_ARRAY ); // <--------------
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDisableClientState( GL_VERTEX_ARRAY ); // <---------------
glBindVertexArray(0);
Further note, that the state of the client-side capability (or vertex attribute array) and the reference to the index (element) buffer is stored in the Vertex Array Objects state vector.
So it is sufficient to enable the vertex coordinates, when the vertex array object is specified and to bid the index buffer when the vertex array object is bound. The enabling and disabling of the vertex coordinates and binding of the index buffer, when drawing the geometry, can be omitted:
vao = glGenVertexArrays();
glBindVertexArray(vao);
vboID = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, vertBuff, GL_STATIC_DRAW);
GL20.glVertexPointer(3, GL_FLOAT, 0, 0); // <--------------
glEnableClientState( GL_VERTEX_ARRAY ); // <--------------
glBindBuffer(GL_ARRAY_BUFFER, 0);
ibo = glGenBuffers();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesBuff, GL_STATIC_DRAW);
// skip glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
I am trying to get the vertices in a VBO to generate a fitting bounding box but the values returned from glMapBuffer are random.
Here is my code:
//Data (Quad):
FloatBuffer vertexData = FloatBuffer.wrap(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,
});
Storing vertices:
//Generating IDs
int vaoID = glGenVertexArrays();
glBindVertexArray(vaoID);
int vboID = glGenBuffers();
//Storing vertex data in attribute list
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, vertexData , GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
//Unbinding
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
Loading Vertices:
//Binding VAO and VBO
glBindVertexArray(vaoID);
glBindBuffer(GL_ARRAY_BUFFER, vboID);
ByteBuffer vertexBuffer = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
//Printing values
//vertices.flip(); //Do I have to flip it? No, right?
System.out.println("Capacity: " + vertices.capacity() + ", Limit: " + vertices.limit());
//Capacity: 48, Limit: 48, Position: 0
while(vertices.remaining() != 0) {
System.out.print("x: " + vertices.get());
System.out.print(", y: " + vertices.get());
System.out.println(", z: " + vertices.get());
}
//Unbinding
glUnmapBuffer(GL_ARRAY_BUFFER);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
The output are random values (mostly just zeros but sometimes random). GlGetError() returns 0 (no errors).
Is this a reasonable way to generate bounding boxes or just dumb? Why are the values random?
Unless this is in something you're not showing: glMapBuffer returns a ByteBuffer, so aren't you getting the 4 bytes that make up each float one at a time? So either try casting it to FloatBuffer with vertices.asFloatBuffer, or use getFloat() instead of get().
I've been trying to make this piece of code work for a while now and I still can't figure it out what I did wrong. (LWJGL - Java)
I have tried to check on the web for other people's code, but I can't find any major difference. I actually learned to use OpenGL with C++ so my mind might be stuck on it and that might be why I can't find my errors.
Here is the init (called once)
FloatBuffer vertices = BufferUtils.createFloatBuffer(4 * 5);
vertices.put(new float[]{
// pos // Color
0.5f, 0.5f, 0.5f, 0.0f, 0.5f,
0.5f, -0.5f, 0.5f, 0.0f, 0.75f,
-0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.5f, 1.0f
});
vertices.flip();
ByteBuffer indices = BufferUtils.createByteBuffer(2 * 3);
indices.put(new byte[]{
0, 1, 3,
1, 2, 3
});
indices.flip();
// VAO
VAO = GL30.glGenVertexArrays();
GL30.glBindVertexArray(VAO);
// VBO
VBO = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);
// EBO
EBO = glGenBuffers();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glEnableVertexAttribArray(0);
// v - position in layout (see shader)
// v - Nb of component per vertex (2 for 2D (x, y))
// v - Normalized ? (between 0 - 1)
// v - Offset between things (size of a line)
// v - Where to start ?
glVertexAttribPointer(0, 2, GL11.GL_FLOAT, false, 5 * Float.SIZE , 0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL11.GL_FLOAT, false, 5 * Float.SIZE , 2 * Float.SIZE);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
// Unbinds the VAO
GL30.glBindVertexArray(0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
And here is the render function :
shaderProgram.bind();
GL30.glBindVertexArray(VAO);
GL11.glDrawElements(GL11.GL_TRIANGLES, 6, GL11.GL_BYTE, 0);
GL30.glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
Shaders:
Vertex:
#version 330 core
layout(location = 0) in vec2 position;
layout(location = 1) in vec3 color;
out vec4 Color;
void main()
{
gl_Position = vec4(position, 0.0, 1.0);
Color = vec4(color, 1.0);
}
Framgent :
#version 330 core
in vec4 Color;
out vec4 color;
void main()
{
color = Color;
}
In the the official Java documentation, Float.SIZE is defined as:
The number of bits used to represent a float value.
Since glVertexAttribPointer() expects the stride and offset arguments in bytes, you will have to divide this by 8, and use (Float.SIZE / 8) instead.