Hot questions for Using Lightweight Java Game Library in buffer

Question:

I can't get my depth to render correctly. No errors are thrown, the glCheckFramebufferStatus says it is complete as well.

Below is the code, the screen always shows up white. The depth values are not 1, but very very close:

EDIT:

So I tried linearizing the depth inside of my depth fragment shader and then drawing that directly to the screen to make sure the values were correct. They are correct. However, even if I send that linearized depth to my full screen quad shader (the 2nd one below), the screen is still all white.

public void initFramebuffers() {
    glBindFramebuffer(GL_FRAMEBUFFER, depthShader.fbo);
    depthShader.initTexture(width, height, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthShader.tex, 0);
    glDrawBuffer(GL_NONE);
    glReadBuffer(GL_NONE);
}

public void initTexture(int width, int height, int format, int internalFormat) {
    tex = glGenTextures();
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, GL_FLOAT, (ByteBuffer)null);
}

Depth Shader:

#version 400

in vec3 pos;
in float radius;

uniform mat4 mView;
uniform mat4 projection;
uniform vec2 screenSize;
uniform vec3 lightPos;

out float depth;

float linearizeDepth(float depth) {
    float n = 0.01;
    float f = 100;
    return (2.0 * n) / (f + n - depth * (f - n));
}    

void main() {
    //calculate normal
    vec3 normal;
    normal.xy = gl_PointCoord * 2.0 - 1.0;
    float r2 = dot(normal.xy, normal.xy);

    if (r2 > 1.0) {
        discard;
    }

    normal.z = sqrt(1.0 - r2);

    //calculate depth
    vec4 pixelPos = vec4(pos + normal * radius, 1.0);
    vec4 clipSpacePos = projection * pixelPos;

    depth = clipSpacePos.z / clipSpacePos.w * 0.5f + 0.5f;
    depth = linearizeDepth(depth);
}

Shader that reads in the depth. The values in linearizeDepth are my near and far distances:

#version 400

in vec2 coord;

uniform sampler2D depthMap;
uniform vec2 screenSize;
uniform mat4 projection;

out vec4 color;

float linearizeDepth(float depth) {
    float n = 0.01;
    float f = 100;
    return (2.0 * n) / (f + n - depth * (f - n));
}    

void main() {
    float curDepth = texture2D(depthMap, coord).x;
    //float d = linearizeDepth(curDepth);

    color = vec4(d, d, d, 1.0f);
}

Code for drawing everything:

//--------------------Particle Depth-----------------------
{
    glUseProgram(depthShader.program);
    glBindFramebuffer(GL_FRAMEBUFFER, depthShader.fbo);

    depthShader.particleDepthVAO(points);

    //Sets uniforms
    RenderUtility.addMatrix(depthShader, mView, "mView");
    RenderUtility.addMatrix(depthShader, projection, "projection");
    RenderUtility.addVector2(depthShader, screenSize, "screenSize");
    RenderUtility.addVector3(depthShader, lightPosition, "lightPos");

    glDisable(GL_BLEND);
    glEnable(GL_DEPTH_TEST);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glBindVertexArray(depthShader.vao);

    glDrawArrays(GL_POINTS, 0, points.size());  
}

    //Draw full screen
{
    glUseProgram(blurShader.program);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    blurShader.blurDepthVAO();

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, depthShader.tex);
    glUniform1i(blurShader.depthMap, 0);

    //Sets uniforms 
    RenderUtility.addMatrix(blurShader, mView, "mView");
    RenderUtility.addMatrix(blurShader, projection, "projection");
    RenderUtility.addVector2(blurShader, screenSize, "screenSize");

    //glEnable(GL_DEPTH_TEST);

    glBindVertexArray(blurShader.vao);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    glViewport(0, 0, width, height);
}

Answer:

The problem ended up being that my vertex shader's out variable name didn't match the fragment shader's in variable name (doh). The code posted above is 100% correct in case anyone sees this in the future.

Question:

I am attempting to use the glMapData() and glBufferSubData() methods to modify an existing VBO.

My current code is the following:

public void updateBufferData(int vaoID, int vboID, long index, int value){
    GL30.glBindVertexArray(vaoID); //bind VAO
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboID); //bind VBO
    IntBuffer buffer = storeDataInIntBuffer(new int[]{value}); //I'm not sure if I should do it like this?
    GL15.glBufferSubData(vboID, index, buffer); //set data
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); //unbind VBO
    GL30.glBindVertexArray(0); //unbind VAO
}

However when I call this method, it doesn't seem to have any effect on the VBO. The rendered object is still the same.

I'm pretty sure that the VBO/VAO aren't bound to anything else when the updateBufferData() method is called.


Answer:

Okay, two things here:

First off, you don't need to bind a VAO to update an VBO. Once you've specified that said VBO is the source for the glVertexAttribArrayPointer (you do this when you create the VAO) you don't need to bind them together anymore. For drawing you bind the VAO, for VBO modifications you bind the VBO. Think of it this way: the same VBO may have been bind to several VAOs, so there's no sense in binding a specific VAO to update it.

Now on to the actual answer, you're doing the glBufferSubData call wrong. It should be using GL15.GL_ARRAY_BUFFER as the first parameter, not the VBO ID, since that has already been bind to the GL15.GL_ARRAY_BUFFER binding point.

Question:

According to lwjgl javadooc, there is a function :

public static void glGenBuffers(int n, ByteBuffer buffer)

But i dont exactly understand how this works. Do i create an ByteBuffer :

ByteBuffer buffer = ByteBuffer.allocate("how much???")
glGenBuffers(4, buffer);

And especially do i have to fill the Buffer with glBufferSubData OR is it better to create 4 buffers and bind and fill them?

My thought was, that it is more efficient when i only create 1 Buffer ,which stores vertices,texturecoords,normals and indices.


Answer:

glGenBuffers(int n, ByteBuffer buffer) generates n vertex buffer objects (VBOs), which you can use to store your data, and puts them in the specified buffer. This buffer is not actually the one that holds your data, but the ids of the VBOs just generated. You have to manually define the VBO data with glBufferData.

The function is useful if you want to create multiple VBOs with a single call. Each VBO id is an integer, and the buffer has to be large enough to hold n (in this case 4) buffers.

ByteBuffer buffer = BufferUtils.createByteBuffer(4 * Integer.BYTES);
glGenBuffers(4, buffer);

However, to make things easier, you can also use an IntBuffer.

IntBuffer buffer = BufferUtils.createIntBuffer(4);
glGenBuffers(4, buffer);

You can then attach the data to each of the VBOs.

glBindBuffer(GL_ARRAY_BUFFER, buffer.get(2); /*value from 0 to 3*/
glBufferData(GL_ARRAY_BUFFER, data, GL_STATIC_DRAW);

(If you are using a ByteBuffer, you have to call buffer.getInt(2) instead.)


It is generally more efficient to have all data in a single buffer, but note that in this case you have to use at least two because indices have to be in a GL_ELEMENT_ARRAY_BUFFER. However, the performance difference is very small, so it may be easier to use several different VBOs.

It is preferred to tightly pack all the data in a buffer and upload that with glBufferData instead of calling glBufferSubData for each type of data. Your data layout will then look something like this (P = position, T = texture coordinate, N = normal vector):

PPPTTNNNPPPTTNNNPPPTTN...

Now you can setup the vertex attribute pointers to correctly read the values from this buffer.

int vbo = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, tightlyPackedData, GL_STATIC_DRAW);

int stride = (3 + 2 + 3) * Float.BYTES;

glVertexAttribPointer(positionIndex, 3, GL_FLOAT, false, stride, 0);
glVertexAttribPointer(texCoordIndex, 2, GL_FLOAT, false, stride, 3 * Float.BYTES);
glVertexAttribPointer(normalIndex,   3, GL_FLOAT, false, stride, (3 + 2) * Float.BYTES);

positionIndex, texCoordIndex and normalIndex are the attribute locations of your vertex shader attributes. You can get them with glGetAttribLocation.

stride is the number of bytes between the value of one vertex and the value of the next one. We have 3 positions, 2 texture coordinates and 3 normals, which are all floats, so we multiply them with Float.BYTES.

The last parameter to glVertexAttribPointer is the offset in bytes, i.e. the number of bytes from the start of the buffer to where the first value is located.

Question:

So i was watching a tutorial for java on how to create a window using Lwjgl and i got to this part where you get the primary monitor:

    ByteBuffer vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());

    glfwSetWindowPos(
            window,
            (GLFWVidMode.width(vidmode) - width) / 2,
            (GLFWVidMode.height(vidmode) - height) / 2
        ); 

However i get this error on eclipse : "Type mismatch: cannot convert from GLFWVidMode to ByteBuffer"

which results in this not being allowed: GLFWVidMode.width GLFWVidMode.height (it says: "The method height() in the type GLFWVidMode is not applicable for the arguments (ByteBuffer)")

I have searched for another tutorial and it also uses the methods in that order so I'm not sure what should i replace for it to work or if they updated something in Lwjgl 3.0.


Answer:

Never mind, i checked the source site and it appears that in fact they changed it so it's now this:

GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());

    glfwSetWindowPos(
            window,
             (vidmode.width() - width) / 2,
            (vidmode.height() - height) / 2
        ); 

Question:

I keep getting this exception:

Exception in thread "main" org.lwjgl.opengl.OpenGLException: Cannot use offsets when Array Buffer Object is disabled
at org.lwjgl.opengl.GLChecks.ensureArrayVBOenabled(GLChecks.java:93)
at org.lwjgl.opengl.GL11.glVertexPointer(GL11.java:2680)
at Joehot200.TerrainDemo.render(TerrainDemo.java:2074)
at Joehot200.TerrainDemo.enterGameLoop(TerrainDemo.java:3266)
at Joehot200.TerrainDemo.startGame(TerrainDemo.java:3490)
at StartScreenExperiments.Test2.resartTDemo(Test2.java:55)
at StartScreenExperiments.Test2.main(Test2.java:41)

However, the array buffer object IS enabled!

glEnableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
glVertexPointer(3, GL_FLOAT, 0, 0L);

As you can see, two lines before the glVertexPointer call (the one that the error is at), then I am clearly enabling the array buffer!

What is wrong here?


Answer:

Vertex Buffers are not something you enable or disable - LWJGL is misleading you.

You need to undertand that the glVertexPointer command uses whatever is bound to GL_ARRAY_BUFFER ("Array Buffer Object") as its memory source (beginning with OpenGL 1.5).

In certain versions of OpenGL (1.5-3.0 and 3.1+ compatibility) if you have 0 bound to GL_ARRAY_BUFFER, then the last parameter to glVertexPointer is an actual pointer to your program's memory (client memory) rather than an offset into GPU memory (server memory). Core OpenGL 3.1+ does not even support client-side vertex storage, so that last parameter is always an offset.


LWJGL's error message is poorly worded:

Exception in thread "main" org.lwjgl.opengl.OpenGLException: Cannot use offsets when Array Buffer Object is disabled.

The error message really means that you have 0 bound to GL_ARRAY_BUFFER when you call glVertexPointer (...). LWJGL apparently considers Array Buffer Objects "disabled" whenever nothing is bound to GL_ARRAY_BUFFER. That is not too unreasonable, but it does lead you to believe that this is a state that can be enabled or disabled using glEnable or glDisable; it is not.

Remember how I described the last parameter to glVertexPointer as an offset when you have something bound to GL_ARRAY_BUFFER? Since LWJGL is Java-based, there is no way to pass an arbitrary memory address as an integer. An integer value passed to glVertexPointer (...) must be an offset into the currently bound vertex buffer's memory.

Client-side vertex specification (unsupported in core GL 3.1+)
void glVertexPointer(int size, int type, int stride, java.nio.ByteBuffer pointer);
Server-side vertex specification (takes an offset into GL_ARRAY_BUFFER)
void glVertexPointer(int size, int type, int stride, long pointer_buffer_offset);

As you can see, there is an alternate form of the glVertexPointer function in LWJGL that can take memory not stored in a buffer object, where you pass a specialization of java.nio.Buffer. That is the form you are expected to use when you have no vertex buffer bound and that is what the error message is really telling you.


That explains what the error message you are seeing actually means, but not its cause.

For some reason vboVertexHandle appears to be 0 or some value not generated using glGenBuffers (...) in your application. Showing the code where you initialize the VBO would be helfpul.

Question:

I understand that a EBO can be bound to a VAO, unlike the other OpenGL buffer objects. I also know that if no VAO is bound at the time of binding the EBO, the EBO is bound to the OpenGL context or the global state. My question is when you bind a EBO to a VAO, then unbind the VAO, and bind the EBO again, is the EBO bound to the VAO, the global state, or both? Thanks in advance for any help.


Answer:

I understand that a EBO can be bound to a VAO, unlike the other OpenGL buffer objects.

First, some terminology.

In OpenGL, you do not bind an object to another object. You attach one object to another. "Bind" is only used when putting the object in the context.

When you call glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,...), you are attaching the buffer to the current VAO. Yes, I know the function says "bind", and it behaves a lot like a regular context binding point, but OpenGL functions say a lot of stupid things. There's a reason why the DSA-equivalent is called glVertexArrayElementBuffer, with no "bind" in sight.

I also know that if no VAO is bound at the time of binding the EBO, the EBO is bound to the OpenGL context or the global state.

This is half true. In a compatibility context, VAO 0 is a default VAO object. That is, glBindVertexArray(0) is a valid object. So if you call glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,...) with VAO object 0 bound, you are attaching the buffer to VAO 0.

In a core context, there is no VAO 0. Therefore, glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ...) will result in a GL_INVALID_OPERATION error.

My question is when you bind a EBO to a VAO, then unbind the VAO, and bind the EBO again, is the EBO bound to the VAO, the global state, or both?

A buffer can be attached to any number of VAOs. So the fact that you attach a buffer to VAO 0 will not change the fact that it is attached to some other VAO.

Question:

I have the following matrix in a text file that brought into a floatbuffer, then stored it into the Matrix4f class in LWJGL. This is the matrix in the text file

1.0, 0.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, -1.0, 0.0, 0.0,
0.0, 0.0, 0.03641997277736664, 1.0

When I add the float buffer to the matrix like this

   System.out.println("------------");
   for(float x : nums){
       System.out.println(x);
   }
   System.out.println("------------");
   Matrix4f matrix4f = new Matrix4f();
   FloatBuffer buffer = BufferUtils.createFloatBuffer(nums.length);
   buffer.put(nums);
   buffer.flip();
   matrix4f.load(buffer);

where nums is the float array of values. When I print out the Matrix4f class, it shows

   1.0 0.0 0.0 0.0
   0.0 0.0 -1.0 0.0
   0.0 1.0 0.0 0.036419973
   0.0 0.0 0.0 1.0

But if I use the transpose function in the Matrix4f class, it goes back to

1.0, 0.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, -1.0, 0.0, 0.0,
0.0, 0.0, 0.03641997277736664, 1.0

Why does LWJGL change the order I of the values when I create a Matrix4f? The text file holds the matrix in colum major matrix ordering, which is what I need for OpenGl. What format is LWJGL changing the matrix to? Does it make a difference, should I use the transpose function to change it back?


Answer:

Okay so here is the answer:

The load function of the Matrix4f class expects the float values to be column major.

So if your matrix is like this:

11 12 13 14
21 22 23 24
31 32 33 34
41 42 43 44

The column-major order is: 11 21 31 41 12 22 ...

The more natural order of reading the file how ever is row major. And the comments showed that you did exactly that.

My suggestion is that you leave it like this. Loading the file as column major is more afford than transposing the matrix.

Question:

I'm writing some stuff that uses ByteBuffers. In the docs of the API it says

There is no way to free a buffer explicitly (without JVM specific reflection). Buffer objects are subject to GC and it usually takes two GC cycles to free the off-heap memory after the buffer object becomes unreachable.

However in a SO post's accepted answer I read

BigMemory uses the memory address space of the JVM process, via direct ByteBuffers that are not subject to GC unlike other native Java objects.

Now what should I do, shall I free the created buffer? Or do I misunderstand something in the docs or the answer?


Answer:

It depends how you create the buffer, there are many possible use cases. Regular ByteBuffer.allocate() will be created on the heap and will be collected by the GC. Other options e.g. native memory might not.

Terracotta BigMemory is a type of native off-heap memory which is not governed by the JVM GC. If you allocate a buffer in this type of memory you have to clear it yourself.

It might be a good idea to clear the buffer even if it's allocated in the heap memory. GC will take care of collecting unused buffer it but this will take some time.

Question:

I just tried updating a Vertex Buffer Object (vbo) which has data with static draw in it. Why can I update it with glBufferSubData? I always thought static vbo's can't be changed.


Answer:

GL_STATIC_DRAW does not mean that the data can't be changed. The usage parameter of glBufferData is a hint for the underlying implementation and might allow some performance improvements, but it does not constrain the actual usage. The documentation states:

usage is a hint to the GL implementation as to how a buffer object's data store will be accessed. This enables the GL implementation to make more intelligent decisions that may significantly impact buffer object performance. It does not, however, constrain the actual usage of the data store.

Question:

I'm trying to call the glTexImage2D function using the OpenGL library. I'm using the LWJGL as the framework to use OpenGL in Java.

According to the documentation, this method accepts the following parameters:

public static void glTexImage2D(int target,
            int level,
            int internalformat,
            int width,
            int height,
            int border,
            int format,
            int type,
            java.nio.ByteBuffer pixels)

My implementation of this is below.

GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, 1092, 1092, 0, GL11.GL_RGB, GL11.GL_INT, imageData);

However, I am getting an error:

Exception in thread "main" java.lang.IllegalArgumentException: Number of remaining buffer elements is 3577392, must be at least 14309568. Because at most 14309568 elements can be returned, a buffer with at least 14309568 elements is required, regardless of actual returned element count
    at org.lwjgl.BufferChecks.throwBufferSizeException(BufferChecks.java:162)
    at org.lwjgl.BufferChecks.checkBufferSize(BufferChecks.java:189)
    at org.lwjgl.BufferChecks.checkBuffer(BufferChecks.java:230)
    at org.lwjgl.opengl.GL11.glTexImage2D(GL11.java:2855)
    at TextureLab.testTexture(TextureLab.java:100)
    at TextureLab.start(TextureLab.java:39)
    at TextureLab.main(TextureLab.java:20)

I've done allot of querying, and I assume my method of creating a ByteBuffer for the last parameter is what is causing the issue.

My code implementation for getting a ByteBuffer form an is as follows:

img = ImageIO.read(file);
byte[] pixels = ((DataBufferByte) img.getRaster().getDataBuffer()).getData();

ByteBuffer buffer = BufferUtils.createByteBuffer(pixels.length);
buffer.put(pixels);
buffer.flip();
buffer.rewind();

I've substituted the length of the buffer for the width*height*4 and even hardcoded to the number contained in the error, all to no luck. Any ideas what I'm doing wrong? I think the issue is in my ByteBuffer, but even that I'm not sure of.


Answer:

The lwjgl layer is telling you that your buffer should be at least 14309568 bytes big, but you provide only 3577392. The reason for this is that you used GL_INT as the format parameter of the glTexImage2D call, so each pixel is assumed to be represented by 3 4-byte integer values bz the GL.

You just want to use GL_UNSIGNED_BYTE for typical 8 bit per channel image content, which exaclty maps to the 3577392 bytes you are currently providing.

Question:

I'm going through the OGLdev tutorials, and I'm getting stuck on getting Vertex Array Objects to work. Here's the relevant code:

glBindBuffer(GL_ARRAY_BUFFER, buffers[POS_VB]);

FloatBuffer posBuf = BufferUtils.createFloatBuffer(positions.size() * 3);
for (Vector3f v : positions) {
    posBuf.put(v.toFloatArray());
}
posBuf.flip();

glBufferData(GL_ARRAY_BUFFER, posBuf, GL_STATIC_DRAW);

POS_VB is 1, and positions is an ArrayList filled with the positions (as Vector3f's) of the mesh. v.toFloatArray() just returns a float array with the members of the vector.

Having checked the code where glGetError() starts generating anything other than 0, I've found that this line:

glBufferData(GL_ARRAY_BUFFER, posBuf, GL_STATIC_DRAW);

is the culprit. However, checking the documentation, GL_INVALID_OPERATION is only generated when the first parameter is set to the reserved value (0). This is obviously not the case, so what's happening here?


Answer:

There are only two conditions where glBufferData() will trigger a GL_INVALID_OPERATION error. This is from the OpenGL 4.5 spec:

An INVALID_OPERATION error is generated by BufferData if zero is bound to target.

An INVALID_OPERATION error is generated if the BUFFER_IMMUTABLE_STORAGE flag of the buffer object is TRUE.

The second error condition only applies to OpenGL 4.4 and later, where immutable buffers can be allocated with glBufferStorage().

Therefore, the only logical explanation in your case is that you have 0 bound for GL_ARRAY_BUFFER. You're binding the buffer in the first line of the posted code:

glBindBuffer(GL_ARRAY_BUFFER, buffers[POS_VB]);

This means that buffer[POS_VB] is 0 at this point. Buffer ids need to be generated with glGenBuffers() before being used. It looks like either you missed the glGenBuffers() call, or used it improperly.

Question:

So I am currently learning OpenGL and the tutorial I am following says:

The first thing that we must do is to store our array of floats into a FloatBuffer. This is mainly due to the fact that we must interface with the OpenGL library, which is C-based, so we must transform our array of floats into something that can be managed by the library.

And I totally get the point, but what was strange that every OpenGL method provided by LWJGL works with Buffers, but also with simple Arrays.

Why is this the case and why should I use buffers then?

Some examples:

This works with indices being an IntBuffer but also being a int[].

glBufferData(GL_ARRAY_BUFFER, indices, GL_STATIC_DRAW);

This works with value being a FloatBuffer but also being a float[].

glUniformMatrix4fv(
     uniforms.get(uniformName),
     false,
     value
);

Answer:

Based on the quote, I'm assuming the tutorial wasn't written for LWJGL 3.

LWJGL 3.0.0 was the first version to add support to "Java array parameters" flavored methods that previously only used/supported NIO buffers.

Added support for Java array parameters and HotSpot Critical Natives.

Based on a discussion that can be found in issue 175

Question:

Whenever I use GL_ELEMENT_ARRAY_BUFFER to draw my objects, GLFW throws me a segfault on glfwSwapBuffers();

Here's the problematic code:

public Mesh( float[] verts, int[] indices ) {
    indicesCount = indices.length;

    vertexBuffer = glGenBuffers();
    elementBuffer = glGenBuffers();
    vertexArray = glGenVertexArrays();

    glBindVertexArray( vertexArray );
    glBindBuffer( GL_ARRAY_BUFFER, vertexBuffer );
    glBufferData( GL_ARRAY_BUFFER, verts, GL_STATIC_DRAW );

    glVertexAttribPointer( 0, 3, GL_FLOAT, false, 6 * 4, 0 * 4 );
    glEnableVertexAttribArray( 0 );

    glVertexAttribPointer( 1, 3, GL_FLOAT, false, 6 * 4, 3 * 4 );
    glEnableVertexAttribArray( 1 );

    // Uncommenting this code causes segfault
    //glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, elementBuffer );
    //glBufferData( elementBuffer, indices, GL_STATIC_DRAW );

    glBindVertexArray( 0 );
    glBindBuffer( GL_ARRAY_BUFFER, 0 );
    glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
}

public void draw() {
    glBindVertexArray( vertexArray );

    //glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, elementBuffer );
    //glDrawElements( GL_TRIANGLES, indicesCount, GL_UNSIGNED_INT, 0 );
    glDrawArrays( GL_TRIANGLES, 0, 3 );
    glBindVertexArray( 0 );
}

Segfault is caused by this code:

System.out.println( "Hello" );  // <- Would get printed 
glfwSwapBuffers( windowID );    // <- SIGSEGV
System.out.println( "Hello2" ); // <- Would not get printed

I am using latest LWJGL version 3.2.0, although I also tried 3.1.6, to no avail. I am completely lost, and if nothing works I guess I'll just have to stick to using C++, cause the same code works perfectly there.


Answer:

The 1st parameter of glBufferData has to be the target (GL_ELEMENT_ARRAY_BUFFER) to which the buffer object is bound and not the named buffer object. glBufferData affects the named buffer which is bound to the target.

Use the following code to solve your issue:

glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, elementBuffer );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, indices, GL_STATIC_DRAW );

Question:

I have the following code:

  IntBuffer DrawBuffers = Utils.createIntBuffer(2);
  int bfs[] = {GL30.GL_COLOR_ATTACHMENT0, GL30.GL_COLOR_ATTACHMENT1};
  for(int i = 0; i < 2; i++)
      DrawBuffers.put(bfs[i]);
  DrawBuffers.flip();
  GL20.glDrawBuffers(DrawBuffers);

If I flip the IntBuffer then the int Status = GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER); don't equal GL_FRAMEBUFFER_COMPLETE, if I don't flip it then I get the Status right, but I get a black texture instead of the desired texture, I looked throught my code over and over for 2 days now, my best bet is that this part of the code is somehow wrong, the rest seems ok.

Should the IntBuffer be flipped before using it in glDrawBuffers(IntBuffer) ?


Answer:

Yes, all buffers should be flipped before being passed to LWJGL.

The underlying GL API expects an array for functions that take a Java buffer. The size of that array is a parameter in GL's C language bindings, but hidden from you in Java because LWJGL calculates it as the difference between the current position and the end position.

Unless you flip a java.nio.Buffer, which sets the "current" position to the beginning of a buffer, the current position is going to be the end position after calling put (...). Thus, LWJGL passes an array of size 0 to the C-based OpenGL API it sits on top of. If you call glDrawBuffers (...) with size 0, it sets everything to GL_NONE, which is definitely going to produce the behavior your described.

Question:

I was having a problem due to not flipping the buffer previously, but now I can't get the buffer to add anything with the .put() or .putInt() it constantly throws the BufferOverflowException at the first attempt of:

buffer.put((byte) c.getRed());

The relevant code below:

BufferedImage image = loadImage(".\\res\\" + fileName);
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() * 4);
buffer.flip();
Color c;

for (int y = 0; y < image.getHeight(); y++) {
    for (int x = 0; x < image.getWidth(); x++) {
        c = new Color(image.getRGB(x, y));
        buffer.put((byte) c.getRed());     // Red component
        buffer.put((byte) c.getGreen());      // Green component
        buffer.put((byte) c.getBlue());               // Blue component
        buffer.put((byte) c.getAlpha());    // Alpha component. Only for RGBA
    }
}

Answer:

Your call to buffer.flip() is in the wrong place. From the documentation:

Flips this buffer. The limit is set to the current position and then the position is set to zero.

Where limit is defined as:

A buffer's limit is the index of the first element that should not be read or written. A buffer's limit is never negative and is never greater than its capacity.

Since you call flip() immediately after allocating the buffer, where the current position is 0, the flip() call sets the limit to 0. Which means that nothing can get written at index 0, or after it. Which in turn means that nothing can be written at all.

To fix this, you need to move the buffer.flip() call after the loop that fills the buffer with values using buffer.put().

The main point that your original code was missing is that the buffer position needs to be set to 0 after you write the data to it. Otherwise, future operations will start reading at the current position, which is the end of the buffer after you completed all the buffer.put() operations.

There are various ways to reset the position to 0 after filling the buffer with data. Any one of these should do the job:

buffer.flip();
buffer.position(0);
buffer.rewind();

Question:

I am trying to draw a textured quad. Since it is a quad I want to use glDrawElements and a VEO, but that requires a ShortBuffer instead of a FloatBuffer. I tried changing my code, but now nothing draws. Old code: Uploading and drawing:

 public void flush() {
    if (numVertices > 0) {
        vertices.flip();

        if (vao != null) {
            vao.bind();
        } else {
            vbo.bind(GL_ARRAY_BUFFER);
            specifyVertexAttributes();
        }
        program.use();

        /* Upload the new vertex data */
        vbo.bind(GL_ARRAY_BUFFER);
        vbo.uploadSubData(GL_ARRAY_BUFFER, 0, vertices);

        /* Draw batch */
        glDrawArrays(GL_TRIANGLES, 0, numVertices);

        /* Clear vertex data for next batch */
        vertices.clear();
        numVertices = 0;
    }
}

Adding texture to buffer:

if (vertices.remaining() < 7 * 6) {
        /* We need more space in the buffer, so flush it */
        flush();
    }

    float r = c.getRed();
    float g = c.getGreen();
    float b = c.getBlue();
    float a = c.getAlpha();

    vertices.put(x1).put(y1).put(r).put(g).put(b).put(a).put(s1).put(t1);
    vertices.put(x1).put(y2).put(r).put(g).put(b).put(a).put(s1).put(t2);
    vertices.put(x2).put(y2).put(r).put(g).put(b).put(a).put(s2).put(t2);

    vertices.put(x1).put(y1).put(r).put(g).put(b).put(a).put(s1).put(t1);
    vertices.put(x2).put(y2).put(r).put(g).put(b).put(a).put(s2).put(t2);
    vertices.put(x2).put(y1).put(r).put(g).put(b).put(a).put(s2).put(t1);

    numVertices += 6;

Updated code: Uploading and Drawing:

public void flush() {
    if (numVertices > 0) {
        vertices.flip();

        if (vao != null) {
            vao.bind();
        } else {
            vbo.bind(GL_ARRAY_BUFFER);
            specifyVertexAttributes();
        }
        program.use();

        /* Upload the new vertex data */
        vbo.bind(GL_ARRAY_BUFFER);
        vbo.uploadSubData(GL_ARRAY_BUFFER, 0, vertices);

        /* Draw batch */
        glDrawArrays(GL_TRIANGLES, 0, numVertices);

        /* Clear vertex data for next batch */
        vertices.clear();
        numVertices = 0;
    }
}

Adding texture to buffer:

if (vertices.remaining() < 7 * 6) {
        /* We need more space in the buffer, so flush it */
        flush();
    }

    short r = (short) c.getRed();
    short g = (short) c.getGreen();
    short b = (short) c.getBlue();
    short a = (short) c.getAlpha();

    short sx1 = (short) Math.round(x1), sx2 = (short) Math.round(x2), sy1 = (short) Math.round(y1), sy2 = (short) Math.round(y2), ss1 = (short) Math.round(s1), ss2 = (short) Math.round(s2), st1 = (short) Math.round(t1), st2 = (short) Math.round(t2);
    vertices.put(sx1).put(sy1).put(r).put(g).put(b).put(a).put(ss1).put(st1);
    vertices.put(sx1).put(sy2).put(r).put(g).put(b).put(a).put(ss1).put(st2);
    vertices.put(sx2).put(sy2).put(r).put(g).put(b).put(a).put(ss2).put(st2);

    vertices.put(sx1).put(sy1).put(r).put(g).put(b).put(a).put(ss1).put(st1);
    vertices.put(sx2).put(sy2).put(r).put(g).put(b).put(a).put(ss2).put(st2);
    vertices.put(sx2).put(sy1).put(r).put(g).put(b).put(a).put(ss2).put(st1);

    numVertices += 6;

There were no other changes to the code, except replacing FloatBuffer with ShortBuffer in my uploadSubData method. The VBO class is just a wrapper for the OpenGL methods, so uploadSubData is glUploadSubData, etc... What am I missing? Why doesn't glDrawArrays draw the ShortBuffer? If I left out anything, please tell me, I didn't have much time to write this.


Answer:

You are confusing indices and vertex coordinates. The coordinates are tuples of type GL_FLOAT in an GL_ARRAY_BUFFER. But the indices are a list of integral indices (e.g. type GL_SHORT) in a GL_ELEMENT_ARRAY_BUFFER which refer to the vertex coordinates.

A quad can be be drawn by 2 triangles. You can define 6 vertex coordinates and attributes and use glDrawArrays.

In the following vertices is of type FloatBuffer:

vertices.put(x1).put(y1).put(r).put(g).put(b).put(a).put(s1).put(t1);
vertices.put(x1).put(y2).put(r).put(g).put(b).put(a).put(s1).put(t2);
vertices.put(x2).put(y2).put(r).put(g).put(b).put(a).put(s2).put(t2);

vertices.put(x1).put(y1).put(r).put(g).put(b).put(a).put(s1).put(t1);
vertices.put(x2).put(y2).put(r).put(g).put(b).put(a).put(s2).put(t2);
vertices.put(x2).put(y1).put(r).put(g).put(b).put(a).put(s2).put(t1);

numVertices += 6;
vbo.bind(GL_ARRAY_BUFFER);
vbo.uploadSubData(GL_ARRAY_BUFFER, 0, vertices);

glDrawArrays(GL_TRIANGLES, 0, numVertices);

Or you can define 4 vertex coordinates respectively attributes and 6 indices and use glDrawElements.

In the following vertices still is of type FloatBuffer, but indices is of type ShortBuffer:

vertices.put(x1).put(y1).put(r).put(g).put(b).put(a).put(s1).put(t1);
vertices.put(x1).put(y2).put(r).put(g).put(b).put(a).put(s1).put(t2);
vertices.put(x2).put(y2).put(r).put(g).put(b).put(a).put(s2).put(t2);
vertices.put(x2).put(y1).put(r).put(g).put(b).put(a).put(s2).put(t1);

numVertices += 4;
indices.put(0).put(1).put(2);
indices.put(0).put(2).put(3);

numIndices += 4;
vbo.bind(GL_ARRAY_BUFFER);
vbo.uploadSubData(GL_ARRAY_BUFFER, 0, vertices);
ibo.bind(GL_ELEMENT_ARRAY_BUFFER);
ibo.uploadSubData(GL_ELEMENT_ARRAY_BUFFER, 0, indices);

glDrawElements(GL_TRIANGLES, GL_SHORT, numIndices, null);

So the key is that you'll need 2 uploadSubData methods. The former hast to deal with FloatBuffer and the later has to deal with ShortBuffer. Note, in common the vertex attributes are floating point values. Colors are often floating point values in the range [0, 1]. Texture coordinates are in range [0, 1]. Of course it is possible to encode this to an integral data type, but at least for the vertex coordinates this would cause a loss of accuracy.

Question:

I just got a test texture working in my LWJGL code using an array of floats. Now, though, I need to load an image from a file and store it in the texture. I have gotten the image loaded and the data into a ByteBuffer object, but when I use glTexImage2D like so:

GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB,
    4, 4, 0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, buffer);

the texture is empty and will render as completely black. I've looked at how other people do this but nothing seems to be helping... The function call is also the same as with the float array, except for the type parameter, of course. And yes, my image is RGB and yes, it's 4x4. There's probably something really simple I'm not getting, so any help is appreciated.

Full working test program:

static org.lwjgl.system.MemoryUtil.NULL;

import java.nio.ByteBuffer;

import org.lwjgl.glfw.GLFW;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL11;

public class Example {

    public static void main(String[] args) {
        if (!GLFW.glfwInit()) {
            throw new IllegalStateException("Unable to initialize GLFW");
        }

        // Create a window as the GL context
        long window = GLFW.glfwCreateWindow(100, 100, "", NULL, NULL);

        if (window == NULL) {
            GLFW.glfwTerminate();
            throw new RuntimeException("Failed to create the GLFW window");
        }

        GLFW.glfwMakeContextCurrent(window);

        GL.createCapabilities();

        // Generate the texture and set parameters
        int textureID = GL11.glGenTextures();
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID);
        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);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);

        // A byte array of 4x4 RBG values
        byte[] data = new byte[] {
                127, 127, 0, 127, 127, 0, 127, 127, 0, 127, 127, 0,
                127, 127, 0, 127, 127, 0, 127, 127, 0, 127, 127, 0,
                127, 127, 0, 127, 127, 0, 127, 127, 0, 127, 127, 0,
                127, 127, 0, 127, 127, 0, 127, 127, 0, 127, 127, 0,
        };
        ByteBuffer buffer = ByteBuffer.wrap(data);

        // Load the data to the texture
        GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, 4, 4, 0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, buffer);
        // glGetError returns 0.

        // Test if the buffer data is correctly stored in the texture.
        // I have unrelated problems while getting the data using a
        // ByteBuffer, so it's a float array for debug purposes.
        float[] floats = new float[data.length];
        GL11.glGetTexImage(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, GL11.GL_FLOAT, floats);
        // glGetError returns 0.

        for (float f : floats) {
            System.out.println(f);
        }
        // Expected output is 16 times the following:
        //   0.5
        //   0.5
        //   0.0
        // Actual output: Random (garbage?) values
        // Examples:
        //   0.003921569
        //   0.87843144
        //   1.0
    }
}

This reproduced the problem for me. Usual LWJGL libs (lwjgl, opengl and glfw) are needed for this. As mentioned in the code comments, glGetError returns zero after each GL call.


Answer:

If you use

ByteBuffer buffer = ByteBuffer.wrap(data);

the the buffer is not "direct".

You have to use BufferUtils.createByteBuffer:

ByteBuffer buffer = BufferUtils.createByteBuffer(data.length);
buffer.put(data);
buffer.flip();

Explanation:

BufferUtils.createByteBuffer allocates a direct native-ordered bytebuffer with the specified capacity.

put(vboData) 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.

Question:

i'm trying to learn LWJGL (OpenGL) and i have to say i'm having a hard time.

I was trying to draw a triangle and a quad on the window and i finally managed to do it.

But i still have a question. Sorry in advance if the question sounds stupid to you but i haven't been able to find a very detailed tutorial on the web so it's hard to understand since it's the first time i use OpenGL.

That being said, this is the relevant part of code:

public void init() {
    vertexCount = indices.length;

    vaoId = GL30.glGenVertexArrays();
    GL30.glBindVertexArray(vaoId);

    vboId = GL15.glGenBuffers();
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboId);
    GL15.glBufferData(GL15.GL_ARRAY_BUFFER, coords, GL15.GL_STATIC_DRAW);
    GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);

    idxVboId = GL15.glGenBuffers();
    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, idxVboId);
    GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indices, GL15.GL_STATIC_DRAW);

    GL30.glBindVertexArray(0);
}

public void render() {
    GL30.glBindVertexArray(vaoId);
    GL20.glEnableVertexAttribArray(0);
    GL11.glDrawElements(GL11.GL_TRIANGLES, vertexCount, GL11.GL_UNSIGNED_INT, 0);

    GL20.glDisableVertexAttribArray(0);
    GL30.glBindVertexArray(0);
}

Let's say that the program is running at 60 fps.This means that the render method is being called by the game loop 60 times every second.

The render method steps are:

  1. glBindVertexArray(vaoId)
  2. glEnableVertexAttribArray(0)
  3. Draw the quad
  4. glDisableVertexAttribArray(0)
  5. glBindVertexArray(0)

My question is: Is it necessary to call steps 1, 2, 4 and 5 every time? If yes why?

And the same question applies to the last line of the init() method (glBindVertexArray(0)).

Sorry for my english, it's not my mother tongue. Thanks in advance.


Answer:

My question is: Is it necessary to call steps 1, 2, 4 and 5 every time? If yes why?

No, it is not. OpenGL is designed as a state machine. You have a GL context which contains global state, and objects which you create (like VAOs, VBOs). The objects itself can contain data and per-object state. What matters is the state which is set at the time of some particular GL function call which somehow depends on some of these state values.

In the case of glDrawElements(), the vertex array pointers and enable bits as well as the GL_ELEMENT_ARRAY_BUFFER binding is relevant for providing the input data for the draw call. (All other state that is influencing the drawing, like texture bindings, shader programs, depth test setting, ... is relevant as well, but lets not focus on these here.). All that state is actually encapsulated in the Vertex Array Object (VAO).

With the state machine design of OpenGL, state stays the same unless it is explicitely changed. Since you seem to draw only a single object and never need different attrib pointers or element arrays, you simply can set these up once and reduce your render() method to just the glDrawElements() call. This of course assumes that no other code in your render loop does any influencing state changes.

One thing worth noting: The VAO does store the enables per attribute array, so your step 2 belongs into the VAO initalization, and step 4 is completely useless in this scheme.

This also means that when you want to manage different objects, you could create a VAO, VBO and EBO per object, and your render mothod would just loop over the objects, set the appropriate VAO, and issue the draw call:

for every object obj
    glBindVertexArray(obj.vao);
    glDrawElements(...values depending on obj...);

Binding VAO 0 is actually never strictly required in modern OpenGL. You will always have to have some VAO bound at the time of the draw call, so you eventually have to bind a non-0 VAO later again anyway. The only value such unbinding is providing is that it prevents accidental changes to some objects. Since the tradition OpenGL API always uses the indirection of biding targets to modify an object, one can create situations where objects are bound which are not supposed to be bound at that time, resulting in hard to debug misbehaviors between apparently unrelated code parts.

Question:

I am trying to render a basic model using lwjgl (java OpenGL binding). I am trying to do this off my own knowledge as much as possible using what I remember. I created a vbo like this:

    int verticesVBO = GL15.glGenBuffers ( );
    vboIDs.add ( verticesVBO );
    FloatBuffer verticesData = bufferFromData ( vertices );// Custom Method
    GL15.glBindBuffer ( GL15.GL_ARRAY_BUFFER , verticesVBO );
    GL15.glBufferData ( GL15.GL_ARRAY_BUFFER , verticesData , GL15.GL_STATIC_DRAW );
    GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);// Binds the vbo to the bound vao
    if(( error = GL11.glGetError()) != GL11.GL_NO_ERROR) System.err.println(GLU.gluErrorString(error));

I got about this far with the index buffer object:

    int indicesVBO = GL15.glGenBuffers ( );
    vboIDs.add ( verticesVBO );
    IntBuffer indicesData = bufferFromData ( indices );
    GL15.glBindBuffer ( GL15.GL_ELEMENT_ARRAY_BUFFER , indicesVBO );
    GL15.glBufferData ( GL15.GL_ELEMENT_ARRAY_BUFFER , indicesData , GL15.GL_STATIC_DRAW );
    //Problem Here
    if(( error = GL11.glGetError()) != GL11.GL_NO_ERROR) System.err.println(GLU.gluErrorString(error));

The probelm I am having is that I don't know the method to use to bind the index buffer to the vao. For the vbo containing the vertex data I know to use GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0); but I remember index buffers behaving differently. This is a learning process so please be constructive with your criticism.


Answer:

All you need to do is bind the index buffer while the VAO is bound.

See https://www.opengl.org/wiki/Buffer_Object#General_use:

GL_ELEMENT_ARRAY_BUFFER

All rendering functions of the form gl*Draw*Elements*​ will use the pointer field as a byte offset from the beginning of the buffer object bound to this target. The indices used for indexed rendering will be taken from the buffer object. Note that this binding target is part of a Vertex Array Objects state, so a VAO must be bound before binding a buffer here.

Question:

Another depth buffer question:

I've matrix based camera - matrix comuptations are on OpenGL side (glPushMatrix, rotations, get matrix from OpenGL, glPopMatrix) and when updating camera, I send those computed matrix stuff to OpenGL via glLoadMatrix. Everything is ok (movement and rotation), but depth buffer is messed up:

without glLoadMatrix (no movement/rotation):

with glLoadMatrix:

I don't understand, why are these things happen (if i move camera by "classic" trigonometric functions, everything is ok).

public class Camera implements ICamera {
private final FloatBuffer matrix = BufferUtils.createFloatBuffer(16);

private final FloatBuffer buffer = BufferUtils.createFloatBuffer(16);

/**
 * absolutní pozice kamery v prostoru
 */
private final Vector3f position = new Vector3f();

/**
 * aktuální pohled kamery
 */
private final Vector3f look = new Vector3f();

/**
 * nastavení pozice kamery
 */
@Override
public void setPosition(Vector3f aPosition) {
    matrix.clear();
    matrix.put(0, 1.0f);
    matrix.put(5, 1.0f);
    matrix.put(10, -1.0f);
    matrix.put(15, 1.0f);
    matrix.put(12, aPosition.getX());
    matrix.put(13, aPosition.getY());
    matrix.put(14, aPosition.getZ());
    position.set(matrix.get(12), matrix.get(13), matrix.get(14));
}

/**
 * commonly called with move vector
 */
public void move(Vector3f aPosition) {
    matrix.clear();
    float x = aPosition.getX();
    float y = aPosition.getY();
    float z = aPosition.getZ();
    matrix.put(12, matrix.get(12) + x * matrix.get(0) + y * matrix.get(4) + z * matrix.get(8));
    matrix.put(13, matrix.get(13) + x * matrix.get(1) + y * matrix.get(5) + z * matrix.get(9));
    matrix.put(14, matrix.get(14) + x * matrix.get(2) + y * matrix.get(6) + z * matrix.get(10));
    position.set(matrix.get(12), matrix.get(13), matrix.get(14));
}

/**
 * nastaví směr pohledu na zadaný bod (slouží k otáčení kamery)
 */
public void look(Vector3f aTarget) {
    matrix.clear();
    // realne neovlivni scenu, pouze vyuziva OpenGL pro vypocty matic
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadMatrix(matrix);
    glRotatef(aTarget.getY(), 1, 0, 0);
    glGetFloat(GL_MODELVIEW_MATRIX, matrix);
    glRotatef(-aTarget.getX(), matrix.get(1), matrix.get(5), matrix.get(9));
    glGetFloat(GL_MODELVIEW_MATRIX, matrix);
    glPopMatrix();
    /**
     * - není potřeba normalizovat, poněvadž v matici už normalizovaný je
     * - 12, 13, 14 je pozice kamery, 8, 9, 10 je rotace kamery; výsledek dá absolutní vektor pohledu kamery
     */
    look.set(matrix.get(12) - matrix.get(8), matrix.get(13) - matrix.get(9), matrix.get(14) - matrix.get(10));
}

// this thing update camera rotation/position
@Override
public void tick(float aTick) {
    // nevypada to hezky, nicmene usetri to nejmene 1 volani navic
    float m00 = matrix.get(0);
    float m01 = matrix.get(1);
    float m02 = matrix.get(2);
    float m04 = matrix.get(4);
    float m05 = matrix.get(5);
    float m06 = matrix.get(6);
    float m08 = matrix.get(8);
    float m09 = matrix.get(9);
    float m10 = matrix.get(10);
    float m12 = matrix.get(12);
    float m13 = matrix.get(13);
    float m14 = matrix.get(14);
    buffer.put(0, m00);
    buffer.put(1, m04);
    buffer.put(2, m08);
    buffer.put(4, m01);
    buffer.put(5, m05);
    buffer.put(6, m09);
    buffer.put(8, m02);
    buffer.put(9, m06);
    buffer.put(10, m10);
    buffer.put(12, -(m00 * m12 + m01 * m13 + m02 * m14));
    buffer.put(13, -(m04 * m12 + m05 * m13 + m06 * m14));
    buffer.put(14, -(m08 * m12 + m09 * m13 + m10 * m14));
    buffer.rewind();
    glMatrixMode(GL_MODELVIEW);
    // this line is true devil: if I comment this out, it produce image [1], in this case produce image [2]
    glLoadMatrix(buffer);
    }
}

Answer:

I've modified tick method:

@Override
public void tick(float aTick) {
    float m01 = matrix.get(1);
    float m02 = matrix.get(2);
    float m04 = matrix.get(4);
    float m06 = matrix.get(6);
    float m08 = matrix.get(8);
    float m09 = matrix.get(9);
    float m12 = matrix.get(12);
    float m13 = matrix.get(13);
    float m14 = matrix.get(14);
    buffer.put(matrix);
    buffer.put(1, m04);
    buffer.put(2, m08);
    buffer.put(4, m01);
    buffer.put(6, m09);
    buffer.put(8, m02);
    buffer.put(9, m06);
    buffer.put(12, -(matrix.get(0) * m12 + m01 * m13 + m02 * m14));
    buffer.put(13, -(m04 * m12 + matrix.get(5) * m13 + m06 * m14));
    buffer.put(14, -(m08 * m12 + m09 * m13 + matrix.get(10) * m14));
    buffer.rewind();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glLoadMatrix(buffer);
}

As immibis pointed out - I havent copy all values of matrix do buffer - and bad side-effect was wrong depth buffer calculations.

Now its ok.

Question:

I cannot figure out why some of my objects are being rendered on top of each other. I have Depth testing on.

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);

Do I need to draw by order of what is closest to the camera? (I thought OpenGL did that for you.)

Setup code:

 private  void setUpStates() {
    glShadeModel(GL_SMOOTH);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);        
    glLightModel(GL_LIGHT_MODEL_AMBIENT, BufferTools.asFlippedFloatBuffer(new float[]{0, 0f, 0f, 1f}));         
    glLight(GL_LIGHT0, GL_CONSTANT_ATTENUATION,BufferTools.asFlippedFloatBuffer(new float[]{1, 1, 1, 1}) );

    glEnable(GL_COLOR_MATERIAL);
    glColorMaterial(GL_FRONT, GL_DIFFUSE);   
    glMaterialf(GL_FRONT, GL_SHININESS, 50f);           
    camera.applyOptimalStates();       

    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);

    glEnable(GL_TEXTURE_2D);

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);



    glEnableClientState(GL_VERTEX_ARRAY);       
    glEnableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);

    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}

Render Code:

private void render() {

    // Clear the pixels on the screen and clear the contents of the depth buffer (3D contents of the scene)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    // Reset any translations the camera made last frame update
    glLoadIdentity();
    // Apply the camera position and orientation to the scene
    camera.applyTranslations();
    glLight(GL_LIGHT0, GL_POSITION, BufferTools.asFlippedFloatBuffer(500f, 100f, 500f, 1));        
    //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);       

    for(ChunkBatch cb : InterthreadHolder.getInstance().getBatches()){
        cb.draw(camera.x(), camera.y(), camera.z());
    }


}

The draw method in ChunkBatch:

    public void draw(float x, float y, float z) {
    shader.bind();
    shader.setUniform("cameraPosition", x,y,z);      
   for(ChunkVBO c : VBOs){  
        glBindBuffer(GL_ARRAY_BUFFER, c.vertexid);
        glVertexPointer(3, GL_FLOAT, 0, 0L);
        glBindBuffer(GL_ARRAY_BUFFER, c.colorid);
        glColorPointer(3, GL_FLOAT, 0, 0L);
        glBindBuffer(GL_ARRAY_BUFFER, c.normalid);
        glNormalPointer(GL_FLOAT, 0, 0L);
        glDrawArrays(GL_QUADS, 0, c.visibleFaces * 6);          
    }
    ShaderProgram.unbind();     
}

Answer:

I had forgotten to ask for a depth buffer when creating my window:

Before:

Display.create(new PixelFormat(4,0,0,4));

After

Display.create(new PixelFormat(4,24,0,4));

Question:

I am trying to render a basic cube in LWJGL (Java). But the program keeps crashing, telling me that it "Cannot use offsets when Element Array Buffer Object is disabled". I am guessing that this is not the exact error right here and there might be something less obvious than that.

(I actually did the code that I'm about to show you in C++ and it was working very fine)

Init function (called once)

FloatBuffer vertices = BufferUtils.createFloatBuffer(4 * 5);
    vertices.put(new float[]{
            // pos                  // Color
            0.5f, 0.5f,             1.0f, 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();

    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);

    // IBO
    IBO = glGenBuffers();
    glBindBuffer(GL_ARRAY_BUFFER, IBO);
    glBufferData(GL_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);
    glDisableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 3, GL11.GL_FLOAT, false, 5 * Float.SIZE , 2 * Float.SIZE);
    glDisableVertexAttribArray(1);

    glBindBuffer(GL_ARRAY_BUFFER, IBO);

    // Unbinds the VAO
    GL30.glBindVertexArray(0);

And here is the render function (static for now, until I figure this out)

glUseProgram(shaderProgram.getID());

    GL30.glBindVertexArray(VAO);

// Error in the line bellow
    GL11.glDrawElements(GL11.GL_TRIANGLES, 4, GL11.GL_UNSIGNED_BYTE, 0);

    GL30.glBindVertexArray(0);

A little help would be very appreciated. Also, I might be something very wrong that I'm not aware of, so if you spot something that would be awesome.

Thank you

Edit : Shaders (pretty basic ones too)

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;
}

Answer:

The following lines

IBO = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, IBO);
glBufferData(GL_ARRAY_BUFFER, indices, GL_STATIC_DRAW);

are creating a new array buffer. from the name you choose and the data you copy to, I guess this is your index buffer and thus should be of type GL_ELEMENT_ARRAY_BUFFER.

What the error message is telling you is, that you draw command cannot use 0 as offset into your index buffer if there is non.

Why is there nothing drawn after fixing the index buffer?

Problem 1: You are only drawing 4 indices. If you want to draw 2 triangles, you will need 6 indices.

Problem 2: OpenGL is a statemachine and VAOs only store the last state that was set when they are unbound. This means your calls to glDisableVertexAttribArray will disable the attributes for your VAO. You should move this calls after GL30.glBindVertexArray(0);

Question:

When I just use the back buffer this works fine but when I use a framebuffer the objects aren't rendered at a distance greater than 1 (in view space). This is using an OpenGL 3.2 context.

    colorTextureID = GL11.glGenTextures();
    depthTexutreID = GL11.glGenTextures();
    frameBufferID = GL30.glGenFramebuffers();

    GL11.glBindTexture(GL11.GL_TEXTURE_2D, colorTextureID);
    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);
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
    GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, width, height, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, (ByteBuffer) null);
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);

    GL11.glBindTexture(GL11.GL_TEXTURE_2D, depthTexutreID);
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
    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);
    GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL14.GL_DEPTH_COMPONENT32, width, height, 0, GL11.GL_DEPTH_COMPONENT, GL11.GL_FLOAT, (ByteBuffer) null);
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);

    GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBufferID);
    GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0, GL11.GL_TEXTURE_2D, colorTextureID, 0);
    GL32.glFramebufferTexture(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, depthTexutreID, 0);

    if (GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER) != GL30.GL_FRAMEBUFFER_COMPLETE)
        throw new RuntimeException("Frame buffer is not complete");

    GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0);

Answer:

It was nothing to do with the framebuffer I forgot to set the model and view matrices to the identity when I rendered the framebuffer.

Question:

I have an issue with the water in my terrain, which is currently just a quad with a transparent blue colour.

When close up to it, it looks like this:

As you can see, it's simple enough - A flat transparent quad representing water.

However, when I get further away, this happens:

For those who can't see the GIF, or need an external link (or can't understand what's going on), the terrain is glitching around the water. If you look near the water near enough, you will see the terrain glitching above/below it.

Here is the code where I prepare the 3D view:

static void ready3D()
{
    glViewport(0, 0, Display.getWidth(),Display.getHeight());
    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();
    GLU.gluPerspective(45, (float) Display.getWidth()/Display.getHeight(), 50f, 500f);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glDepthFunc(GL_LEQUAL);
    glEnable(GL_DEPTH_TEST);
}

Does anyone know what the issue is, and how I could improve the precision of the depth buffer (presuming the depth buffer is the issue)?


Answer:

It's difficult to tell from the GIF, but what I'm gathering is that you're experiencing an instance of Z-Fighting.

There are several solutions that tend to be most effective for dealing with Z-Fighting:

  • Increase the Resolution of the Z-Buffer.
  • Adjust the relative positions of the Water & Land to separate them further, thus reducing the chance of the two geometries colliding like this
  • Make use of the Stencil Buffer to ensure that objects are drawn correctly.

I've also seen solutions that try to disable Depth Testing when handling certain objects, but those are almost never good as a general solution.

Question:

My problem is that I have drawn a small quad to a Frame Buffer Object and am trying to draw it to the framebuffer on the window. This is my java code:

import static org.lwjgl.opengl.GL30.*;
import static org.lwjgl.opengl.GL11.*;
import java.nio.ByteBuffer;
import org.lwjgl.opengl.*;

public class Main
{
    private static int fboID;
    private static int texID;
    private static int depthBuff;

    public static void main(String[] args)
    {
        try
        {
            Display.setDisplayMode(new DisplayMode(640, 480));
            Display.create();
        } catch (Exception e)
        {
            e.printStackTrace();
            System.exit(1);
        }

        glEnable(GL_TEXTURE_2D);
        initFramebuffer();
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(0, 640, 480, 0, 1, -1);
        glMatrixMode(GL_MODELVIEW);

        while (!Display.isCloseRequested())
        {
            glBindTexture(GL_TEXTURE_2D, texID);
            glBegin(GL_QUADS);

            glTexCoord2f(0, 0);
            glVertex2i(10, 10);

            glTexCoord2f(0, 1);
            glVertex2i(10, 470);

            glTexCoord2f(1, 1);
            glVertex2i(630, 470);

            glTexCoord2f(1, 0);
            glVertex2i(630, 10);

            glEnd();
            glBindTexture(GL_TEXTURE_2D, 0);

            Display.update();
            Display.sync(60);
        }
    }

    public static void initFramebuffer()
    {
        fboID = glGenFramebuffers();
        glBindFramebuffer(GL_FRAMEBUFFER, fboID);

        texID = glGenTextures();
        glBindTexture(GL_TEXTURE_2D, texID);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 640, 480, 0, GL_RGBA, GL_UNSIGNED_BYTE, (ByteBuffer) null);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        depthBuff = glGenRenderbuffers();
        glBindRenderbuffer(GL_RENDERBUFFER, depthBuff);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 640, 480);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuff);

        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texID, 0);

        if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
            System.out.println("GOD DAMT");

        glBindFramebuffer(GL_FRAMEBUFFER, fboID);
        {
            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
            glOrtho(0, 640, 480, 0, 1, -1);
            glMatrixMode(GL_MODELVIEW);

            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            glViewport(0, 0, 640, 480);

            //glLoadIdentity();

            glBegin(GL_QUADS);
            glColor3f(1, 0, 0);
            glVertex2i(0, 0);
            glVertex2i(100, 0);
            glVertex2i(100, 100);
            glVertex2i(0, 100);
            glEnd();
        }
        glBindFramebuffer(GL_FRAMEBUFFER, 0);

    }
}

Whenever I run this code I get nothing but a black screen. What am I doing wrong?


Answer:

I'm not tooooo familar with OpenGL but

Instead of

    glEnable(GL_TEXTURE_2D);
    initFramebuffer();

you should set texturing enabled after initializing fb:

    initFramebuffer();
    glEnable(GL_TEXTURE_2D);

this is caused by glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); which seems to render uninitialized (non-fb texture) in front of your fb texture box, which causes blank screen

Question:

So I'm new to OpenGL, and I've been following several tutorials on how to draw a simple triangle. I don't use shaders here, even though I know how to use them. The tutorials say to create a buffer using glCreateBuffers, but everything I change in the code doesn't prevent the error. I've been following the OpenGL Programming Guide, and watched several YouTube videos on the topic. I've also updated to the most recent NVIDIA drivers for my graphics card. What did I do wrong?

The error, which also contains all of the hardware specifications:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007fffa120235d, pid=4592, tid=0x00000000000035a8
#
# JRE version: Java(TM) SE Runtime Environment (8.0_101-b13) (build 1.8.0_101-b13)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.101-b13 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C  [lwjgl_opengl.dll+0x235d]
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

---------------  T H R E A D  ---------------

Current thread (0x00000000032a9000):  JavaThread "main" [_thread_in_native, id=13736, stack(0x0000000003160000,0x0000000003260000)]

siginfo: ExceptionCode=0xc0000005, reading address 0x0000000000000830

Registers:
RAX=0x000000005619ed50, RBX=0x000000001a523d28, RCX=0x0000000000000001, RDX=0x000000001daa7d5c
RSP=0x000000000325f4f8, RBP=0x000000000325f580, RSI=0x0000000000000048, RDI=0x0000000003507e70
R8 =0x0000000000000001, R9 =0x000000001daa7d5c, R10=0x0000000000000000, R11=0x0000000055c2b4a0
R12=0x0000000000000000, R13=0x000000001a523d28, R14=0x000000000325f5b0, R15=0x00000000032a9000
RIP=0x00007fffa120235d, EFLAGS=0x0000000000010202

Top of Stack: (sp=0x000000000325f4f8)
0x000000000325f4f8:   0000000003517f54 0000000003507e70
0x000000000325f508:   0000000003517cbd 00000000032a9000
0x000000000325f518:   000000001a523d28 0000000000000048
0x000000000325f528:   00000000032a9000 000000000325f628
0x000000000325f538:   0000000003517c82 000000000325f540
0x000000000325f548:   000000001a523d28 000000000325f5b0
0x000000000325f558:   000000001a539f98 0000000000000000
0x000000000325f568:   000000001a523d28 0000000000000000
0x000000000325f578:   000000000325f5a0 000000000325f5f8
0x000000000325f588:   000000000350835d 00000007813fb2d8
0x000000000325f598:   00000000035119d8 000000001daa7d5c
0x000000000325f5a8:   0000000781481140 0000000000000001
0x000000000325f5b8:   000000000325f5b8 000000001a523e7c
0x000000000325f5c8:   000000000325f628 000000001a539f98
0x000000000325f5d8:   0000000000000000 000000001a523ee0
0x000000000325f5e8:   000000000325f5a0 000000000325f630 

Instructions: (pc=0x00007fffa120235d)
0x00007fffa120233d:   ff a2 28 17 00 00 cc cc cc cc cc cc cc cc cc cc
0x00007fffa120234d:   cc cc cc 48 8b 01 49 8b d1 41 8b c8 4c 8b 50 18
0x00007fffa120235d:   49 ff a2 30 08 00 00 cc cc cc cc cc cc cc cc cc
0x00007fffa120236d:   cc cc cc 40 53 48 8b 01 41 8b d8 4c 8b 44 24 30 


Register to memory mapping:

RAX=0x000000005619ed50 is an unknown value
RBX={method} {0x000000001a523d30} 'nglCreateBuffers' '(IJ)V' in 'org/lwjgl/opengl/GL45'
RCX=0x0000000000000001 is an unknown value
RDX=0x000000001daa7d5c is an unknown value
RSP=0x000000000325f4f8 is pointing into the stack for thread: 0x00000000032a9000
RBP=0x000000000325f580 is pointing into the stack for thread: 0x00000000032a9000
RSI=0x0000000000000048 is an unknown value
RDI=0x0000000003507e70 is at code_begin+1040 in an Interpreter codelet
invoke return entry points  [0x0000000003507a60, 0x0000000003508440]  2528 bytes
R8 =0x0000000000000001 is an unknown value
R9 =0x000000001daa7d5c is an unknown value
R10=0x0000000000000000 is an unknown value
R11=0x0000000055c2b4a0 is an unknown value
R12=0x0000000000000000 is an unknown value
R13={method} {0x000000001a523d30} 'nglCreateBuffers' '(IJ)V' in 'org/lwjgl/opengl/GL45'
R14=0x000000000325f5b0 is pointing into the stack for thread: 0x00000000032a9000
R15=0x00000000032a9000 is a thread


Stack: [0x0000000003160000,0x0000000003260000],  sp=0x000000000325f4f8,  free space=1021k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [lwjgl_opengl.dll+0x235d]

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  org.lwjgl.opengl.GL45.nglCreateBuffers(IJ)V+0
j  org.lwjgl.opengl.GL45.glCreateBuffers()I+20
j  com.meti.HelloTriangle.init()V+169
j  com.meti.HelloTriangle.run()V+1
j  com.meti.HelloTriangle.main([Ljava/lang/String;)V+7
v  ~StubRoutines::call_stub

---------------  P R O C E S S  ---------------

Java Threads: ( => current thread )
  0x000000001cbaf000 JavaThread "Service Thread" daemon [_thread_blocked, id=15408, stack(0x000000001d6a0000,0x000000001d7a0000)]
  0x000000001cbb6800 JavaThread "C1 CompilerThread3" daemon [_thread_blocked, id=4928, stack(0x000000001d5a0000,0x000000001d6a0000)]
  0x000000001cbae000 JavaThread "C2 CompilerThread2" daemon [_thread_blocked, id=15648, stack(0x000000001d4a0000,0x000000001d5a0000)]
  0x000000001cbb2800 JavaThread "C2 CompilerThread1" daemon [_thread_blocked, id=3528, stack(0x000000001d3a0000,0x000000001d4a0000)]
  0x000000001cbad800 JavaThread "C2 CompilerThread0" daemon [_thread_blocked, id=2988, stack(0x000000001d2a0000,0x000000001d3a0000)]
  0x000000001caf6000 JavaThread "Monitor Ctrl-Break" daemon [_thread_in_native, id=10828, stack(0x000000001d1a0000,0x000000001d2a0000)]
  0x000000001c8e4800 JavaThread "Attach Listener" daemon [_thread_blocked, id=15864, stack(0x000000001d0a0000,0x000000001d1a0000)]
  0x000000001c8e3000 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=13440, stack(0x000000001cfa0000,0x000000001d0a0000)]
  0x000000001a9e4000 JavaThread "Finalizer" daemon [_thread_blocked, id=15624, stack(0x000000001ccb0000,0x000000001cdb0000)]
  0x000000000339e000 JavaThread "Reference Handler" daemon [_thread_blocked, id=13760, stack(0x000000001c7b0000,0x000000001c8b0000)]
=>0x00000000032a9000 JavaThread "main" [_thread_in_native, id=13736, stack(0x0000000003160000,0x0000000003260000)]

Other Threads:
  0x000000001a9d9000 VMThread [stack: 0x000000001c6b0000,0x000000001c7b0000] [id=13368]
  0x000000001cbc0000 WatcherThread [stack: 0x000000001dfa0000,0x000000001e0a0000] [id=13180]

VM state:not at safepoint (normal execution)

VM Mutex/Monitor currently owned by a thread: None

Heap:
 PSYoungGen      total 57344K, used 11847K [0x0000000780900000, 0x0000000784900000, 0x00000007c0000000)
  eden space 49152K, 24% used [0x0000000780900000,0x0000000781491f48,0x0000000783900000)
  from space 8192K, 0% used [0x0000000784100000,0x0000000784100000,0x0000000784900000)
  to   space 8192K, 0% used [0x0000000783900000,0x0000000783900000,0x0000000784100000)
 ParOldGen       total 131072K, used 0K [0x0000000701a00000, 0x0000000709a00000, 0x0000000780900000)
  object space 131072K, 0% used [0x0000000701a00000,0x0000000701a00000,0x0000000709a00000)
 Metaspace       used 6034K, capacity 6220K, committed 6400K, reserved 1056768K
  class space    used 655K, capacity 738K, committed 768K, reserved 1048576K

Card table byte_map: [0x00000000128c0000,0x0000000012ec0000] byte_map_base: 0x000000000f0b3000

Marking Bits: (ParMarkBitMap*) 0x000000005621a6d0
 Begin Bits: [0x0000000013ac0000, 0x0000000016a58000)
 End Bits:   [0x0000000016a58000, 0x00000000199f0000)

Polling page: 0x0000000001300000

CodeCache: size=245760Kb used=2341Kb max_used=2353Kb free=243418Kb
 bounds [0x0000000003500000, 0x0000000003770000, 0x0000000012500000]
 total_blobs=1191 nmethods=469 adapters=635
 compilation: enabled

Compilation events (10 events):
Event: 0.540 Thread 0x000000001cbb6800  465       3       java.util.zip.InflaterInputStream::read (32 bytes)
Event: 0.540 Thread 0x000000001cbb6800 nmethod 465 0x0000000003745dd0 code [0x0000000003745f60, 0x00000000037463d8]
Event: 0.541 Thread 0x000000001cbb6800  466       3       java.util.WeakHashMap::remove (133 bytes)
Event: 0.542 Thread 0x000000001cbb6800 nmethod 466 0x0000000003746590 code [0x0000000003746780, 0x0000000003747268]
Event: 0.545 Thread 0x000000001cbad800 nmethod 463 0x000000000374a6d0 code [0x000000000374a820, 0x000000000374ac38]
Event: 0.545 Thread 0x000000001cbb6800  467       3       sun.misc.JarIndex::get (49 bytes)
Event: 0.545 Thread 0x000000001cbb6800 nmethod 467 0x0000000003749950 code [0x0000000003749b20, 0x000000000374a398]
Event: 0.546 Thread 0x000000001cbae000  468       4       java.lang.String::indexOf (166 bytes)
Event: 0.546 Thread 0x000000001cbb6800  469       3       java.net.URL::toString (5 bytes)
Event: 0.546 Thread 0x000000001cbb6800 nmethod 469 0x0000000003749410 code [0x0000000003749580, 0x0000000003749868]

GC Heap History (0 events):
No events

Deoptimization events (1 events):
Event: 0.270 Thread 0x00000000032a9000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x000000000367a394 method=java.lang.String.indexOf([CII[CIII)I @ 134

Internal exceptions (10 events):
Event: 0.039 Thread 0x00000000032a9000 Exception <a 'java/lang/NoSuchMethodError': Method sun.misc.Unsafe.prefetchRead(Ljava/lang/Object;J)V name or signature does not match> (0x0000000780907fa8) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u101\7261\hotspot\src\share\vm\prims\��1����?
Event: 0.234 Thread 0x00000000032a9000 Exception <a 'java/lang/NoSuchMethodError': java.lang.Object.lambda$static$0(Ljava/lang/String;)Ljava/lang/Boolean;> (0x0000000780f3d758) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u101\7261\hotspot\src\share\vm\interpreter\linkResolver.:%�l��?
Event: 0.248 Thread 0x00000000032a9000 Exception <a 'java/lang/NoSuchFieldError': method resolution failed> (0x0000000780fbfba0) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u101\7261\hotspot\src\share\vm\prims\methodHandles.cpp, line 1146]
Event: 0.249 Thread 0x00000000032a9000 Exception <a 'java/lang/NoSuchFieldError': method resolution failed> (0x0000000780fcda48) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u101\7261\hotspot\src\share\vm\prims\methodHandles.cpp, line 1146]
Event: 0.296 Thread 0x00000000032a9000 Exception <a 'java/security/PrivilegedActionException'> (0x00000007811bcef8) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u101\7261\hotspot\src\share\vm\prims\jvm.cpp, line 1386]
Event: 0.296 Thread 0x00000000032a9000 Exception <a 'java/security/PrivilegedActionException'> (0x00000007811bd108) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u101\7261\hotspot\src\share\vm\prims\jvm.cpp, line 1386]
Event: 0.296 Thread 0x00000000032a9000 Exception <a 'java/security/PrivilegedActionException'> (0x00000007811c11d8) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u101\7261\hotspot\src\share\vm\prims\jvm.cpp, line 1386]
Event: 0.296 Thread 0x00000000032a9000 Exception <a 'java/security/PrivilegedActionException'> (0x00000007811c13e8) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u101\7261\hotspot\src\share\vm\prims\jvm.cpp, line 1386]
Event: 0.543 Thread 0x00000000032a9000 Exception <a 'sun/nio/fs/WindowsException'> (0x0000000781462538) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u101\7261\hotspot\src\share\vm\prims\jni.cpp, line 709]
Event: 0.544 Thread 0x00000000032a9000 Exception <a 'sun/nio/fs/WindowsException'> (0x0000000781463f38) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u101\7261\hotspot\src\share\vm\prims\jni.cpp, line 709]

Events (10 events):
Event: 0.544 loading class java/nio/file/NoSuchFileException
Event: 0.544 loading class java/nio/file/FileSystemException
Event: 0.544 loading class java/nio/file/FileSystemException done
Event: 0.544 loading class java/nio/file/NoSuchFileException done
Event: 0.544 loading class org/lwjgl/opengl/GL$1
Event: 0.544 loading class org/lwjgl/opengl/GL$1 done
Event: 0.545 loading class org/lwjgl/opengl/GL$SharedLibraryGL
Event: 0.545 loading class org/lwjgl/opengl/GL$SharedLibraryGL done
Event: 0.545 loading class org/lwjgl/system/SharedLibrary$Delegate
Event: 0.545 loading class org/lwjgl/system/SharedLibrary$Delegate done


Dynamic libraries:
0x00007ff63a440000 - 0x00007ff63a477000     C:\Program Files\Java\jdk1.8.0_101\bin\java.exe
0x00007fffbc000000 - 0x00007fffbc1db000     C:\WINDOWS\SYSTEM32\ntdll.dll
0x00007fffbb630000 - 0x00007fffbb6de000     C:\WINDOWS\System32\KERNEL32.DLL
0x00007fffb86c0000 - 0x00007fffb8909000     C:\WINDOWS\System32\KERNELBASE.dll
0x00007fffbabe0000 - 0x00007fffbac81000     C:\WINDOWS\System32\ADVAPI32.dll
0x00007fffbbf60000 - 0x00007fffbbffd000     C:\WINDOWS\System32\msvcrt.dll
0x00007fffbb6e0000 - 0x00007fffbb739000     C:\WINDOWS\System32\sechost.dll
0x00007fffbb8a0000 - 0x00007fffbb9c5000     C:\WINDOWS\System32\RPCRT4.dll
0x00007fffbb750000 - 0x00007fffbb89a000     C:\WINDOWS\System32\USER32.dll
0x00007fffb8970000 - 0x00007fffb898e000     C:\WINDOWS\System32\win32u.dll
0x00007fffbaa60000 - 0x00007fffbaa87000     C:\WINDOWS\System32\GDI32.dll
0x00007fffb93d0000 - 0x00007fffb9558000     C:\WINDOWS\System32\gdi32full.dll
0x00007fffb8620000 - 0x00007fffb86ba000     C:\WINDOWS\System32\msvcp_win.dll
0x00007fffb8520000 - 0x00007fffb8616000     C:\WINDOWS\System32\ucrtbase.dll
0x00007fffa8480000 - 0x00007fffa86e7000     C:\WINDOWS\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.15063.483_none_26002d27e7c744a2\COMCTL32.dll
0x00007fffbba70000 - 0x00007fffbbd69000     C:\WINDOWS\System32\combase.dll
0x00007fffb8990000 - 0x00007fffb89fa000     C:\WINDOWS\System32\bcryptPrimitives.dll
0x00007fffbbd90000 - 0x00007fffbbdbd000     C:\WINDOWS\System32\IMM32.DLL
0x00000000562a0000 - 0x0000000056372000     C:\Program Files\Java\jdk1.8.0_101\jre\bin\msvcr100.dll
0x0000000055a00000 - 0x000000005629a000     C:\Program Files\Java\jdk1.8.0_101\jre\bin\server\jvm.dll
0x00007fffbb9d0000 - 0x00007fffbb9d8000     C:\WINDOWS\System32\PSAPI.DLL
0x00007fffb46f0000 - 0x00007fffb46f9000     C:\WINDOWS\SYSTEM32\WSOCK32.dll
0x00007fffb5410000 - 0x00007fffb5433000     C:\WINDOWS\SYSTEM32\WINMM.dll
0x00007fffbb360000 - 0x00007fffbb3cc000     C:\WINDOWS\System32\WS2_32.dll
0x00007fffabe10000 - 0x00007fffabe3b000     C:\WINDOWS\SYSTEM32\WINMMBASE.dll
0x00007fffad5f0000 - 0x00007fffad5fa000     C:\WINDOWS\SYSTEM32\VERSION.dll
0x00007fffb8a00000 - 0x00007fffb8a49000     C:\WINDOWS\System32\cfgmgr32.dll
0x0000000057380000 - 0x000000005738f000     C:\Program Files\Java\jdk1.8.0_101\jre\bin\verify.dll
0x0000000057350000 - 0x0000000057379000     C:\Program Files\Java\jdk1.8.0_101\jre\bin\java.dll
0x0000000057320000 - 0x0000000057343000     C:\Program Files\Java\jdk1.8.0_101\jre\bin\instrument.dll
0x0000000057300000 - 0x0000000057316000     C:\Program Files\Java\jdk1.8.0_101\jre\bin\zip.dll
0x00007fffb9620000 - 0x00007fffbaa56000     C:\WINDOWS\System32\SHELL32.dll
0x00007fffbaa90000 - 0x00007fffbab3a000     C:\WINDOWS\System32\shcore.dll
0x00007fffb8a50000 - 0x00007fffb9143000     C:\WINDOWS\System32\windows.storage.dll
0x00007fffbb190000 - 0x00007fffbb1e1000     C:\WINDOWS\System32\shlwapi.dll
0x00007fffb8490000 - 0x00007fffb84a1000     C:\WINDOWS\System32\kernel.appcore.dll
0x00007fffb84b0000 - 0x00007fffb84fc000     C:\WINDOWS\System32\powrprof.dll
0x00007fffb8470000 - 0x00007fffb8485000     C:\WINDOWS\System32\profapi.dll
0x00007fffabef0000 - 0x00007fffabf0a000     C:\Users\mathm\AppData\Local\JetBrains\Toolbox\apps\IDEA-C\ch-1\172.3968.16\bin\breakgen64.dll
0x00000000559e0000 - 0x00000000559fa000     C:\Program Files\Java\jdk1.8.0_101\jre\bin\net.dll
0x00007fffb7d20000 - 0x00007fffb7d7c000     C:\WINDOWS\system32\mswsock.dll
0x00000000559c0000 - 0x00000000559d1000     C:\Program Files\Java\jdk1.8.0_101\jre\bin\nio.dll
0x00007fffa87b0000 - 0x00007fffa8807000     C:\Users\mathm\AppData\Local\Temp\lwjglmathm\3.1.2-build-29\lwjgl.dll
0x00007fffa8770000 - 0x00007fffa87ac000     C:\Users\mathm\AppData\Local\Temp\lwjglmathm\3.1.2-build-29\jemalloc.dll
0x00007fffa5e30000 - 0x00007fffa5e6d000     C:\Users\mathm\AppData\Local\Temp\lwjglmathm\3.1.2-build-29\glfw.dll
0x00007fffb6ce0000 - 0x00007fffb6d75000     C:\WINDOWS\system32\uxtheme.dll
0x00007fffa4f50000 - 0x00007fffa4f92000     C:\WINDOWS\SYSTEM32\dinput8.dll
0x00007fffb4630000 - 0x00007fffb463e000     C:\WINDOWS\SYSTEM32\xinput1_4.dll
0x00007fffb6f90000 - 0x00007fffb6fb8000     C:\WINDOWS\SYSTEM32\DEVOBJ.dll
0x00007fffad130000 - 0x00007fffad15a000     C:\WINDOWS\SYSTEM32\dwmapi.dll
0x00007fffbb1f0000 - 0x00007fffbb356000     C:\WINDOWS\System32\MSCTF.dll
0x00007fffbb0d0000 - 0x00007fffbb190000     C:\WINDOWS\System32\OLEAUT32.dll
0x00007fffaccf0000 - 0x00007fffacd18000     c:\program files\nvidia corporation\nvstreamsrv\nvinject.dll
0x00007fffb7320000 - 0x00007fffb732d000     C:\WINDOWS\SYSTEM32\HID.DLL
0x00007fffbac90000 - 0x00007fffbb0cb000     C:\WINDOWS\System32\SETUPAPI.DLL
0x00007fffb8910000 - 0x00007fffb8966000     C:\WINDOWS\System32\WINTRUST.dll
0x00007fffb8500000 - 0x00007fffb8511000     C:\WINDOWS\System32\MSASN1.dll
0x00007fffb9200000 - 0x00007fffb93c9000     C:\WINDOWS\System32\CRYPT32.dll
0x00007fffa1290000 - 0x00007fffa13b1000     C:\WINDOWS\SYSTEM32\opengl32.dll
0x00007fffad870000 - 0x00007fffad89c000     C:\WINDOWS\SYSTEM32\GLU32.dll
0x00007fff66980000 - 0x00007fff676ca000     C:\WINDOWS\System32\DriverStore\FileRepository\igdlh64.inf_amd64_463164d40c3d26ce\ig9icd64.dll
0x00007fffb48f0000 - 0x00007fffb4903000     C:\WINDOWS\SYSTEM32\WTSAPI32.dll
0x00007fffa3730000 - 0x00007fffa488d000     C:\WINDOWS\System32\DriverStore\FileRepository\igdlh64.inf_amd64_463164d40c3d26ce\igc64.dll
0x00007fffaf3b0000 - 0x00007fffaf432000     C:\WINDOWS\System32\TextInputFramework.dll
0x00007fffb5ee0000 - 0x00007fffb5fc3000     C:\WINDOWS\System32\CoreMessaging.dll
0x00007fffa76a0000 - 0x00007fffa7972000     C:\WINDOWS\System32\CoreUIComponents.dll
0x00007fffb1f30000 - 0x00007fffb1f45000     C:\WINDOWS\SYSTEM32\usermgrcli.dll
0x00007fffb7670000 - 0x00007fffb76a1000     C:\WINDOWS\SYSTEM32\ntmarta.dll
0x00007fffb52d0000 - 0x00007fffb5409000     C:\WINDOWS\SYSTEM32\wintypes.dll
0x00007fffa1200000 - 0x00007fffa125c000     C:\Users\mathm\AppData\Local\Temp\lwjglmathm\3.1.2-build-29\lwjgl_opengl.dll
0x00007fffb42c0000 - 0x00007fffb4469000     C:\WINDOWS\SYSTEM32\dbghelp.dll

VM Arguments:
jvm_args: -javaagent:C:\Users\mathm\AppData\Local\JetBrains\Toolbox\apps\IDEA-C\ch-1\172.3968.16\lib\idea_rt.jar=53725:C:\Users\mathm\AppData\Local\JetBrains\Toolbox\apps\IDEA-C\ch-1\172.3968.16\bin -Dfile.encoding=UTF-8 
java_command: com.meti.HelloTriangle
java_class_path (initial): C:\Program Files\Java\jdk1.8.0_101\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\rt.jar;C:\Meticuli\Projects\LwjglProjects\out\production\LwjglProjects;C:\Meticuli\Projects\LwjglProjects\libraries\lwjgl-3.1.2\lwjgl\lwjgl.jar;C:\Meticuli\Projects\LwjglProjects\libraries\lwjgl-3.1.2\lwjgl\lwjgl-javadoc.jar;C:\Meticuli\Projects\LwjglProjects\libraries\lwjgl-3.1.2\lwjgl\lwjgl-sources.jar;C:\Meticuli\Projects\LwjglProjects\libraries\lwjgl-3.1.2\lwjgl\lwjgl-natives-linux.jar;C:\Meticuli\Projects\LwjglProjects\libraries\lwjgl-3.1.2\lwjgl\lwjgl-natives-macos.jar;C:\Meticuli\Projects\LwjglProjects\libraries\lwjgl-3.1.2\lwjgl\lwjgl-natives-windows.jar;C:\Meticuli\Projects\LwjglProjects\libraries\lwjgl-3.1.2\lwjgl-assimp\lwjgl-assimp.jar;
Launcher Type: SUN_STANDARD

Environment Variables:
PATH=C:\ProgramData\Oracle\Java\javapath;C:\Program Files (x86)\Intel\iCLS Client\;C:\Program Files\Intel\iCLS Client\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\WINDOWS\system32\config\systemprofile\.dnx\bin;C:\Program Files\Microsoft DNX\Dnvm\;C:\Program Files\Microsoft SQL Server\130\Tools\Binn\;C:\Program Files\Git\cmd;C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\GtkSharp\2.12\bin;C:\Program Files (x86)\Windows Live\Shared;C:\Program Files (x86)\Skype\Phone\;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Users\mathm\AppData\Local\Microsoft\WindowsApps;
USERNAME=mathm
OS=Windows_NT
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 94 Stepping 3, GenuineIntel



---------------  S Y S T E M  ---------------

OS: Windows 10.0 , 64 bit Build 15063 (10.0.15063.296)

CPU:total 8 (4 cores per cpu, 2 threads per core) family 6 model 94 stepping 3, cmov, cx8, fxsr, mmx, sse, sse2, sse3, ssse3, sse4.1, sse4.2, popcnt, avx, avx2, aes, clmul, erms, rtm, 3dnowpref, lzcnt, ht, tsc, tscinvbit, bmi1, bmi2, adx

Memory: 4k page, physical 12476176k(7696764k free), swap 13296400k(7350476k free)

vm_info: Java HotSpot(TM) 64-Bit Server VM (25.101-b13) for windows-amd64 JRE (1.8.0_101-b13), built on Jun 22 2016 01:21:29 by "java_re" with MS VC++ 10.0 (VS2010)

time: Sat Sep 16 16:46:48 2017
elapsed time: 0 seconds (0d 0h 0m 0s)

I do hate working with native code in Java, albeit knowing OpenGL is a good skill to have.

Here is the source code:

package com.meti;

import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.opengl.GL;

import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER;
import static org.lwjgl.opengl.GL15.glBindBuffer;
import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray;
import static org.lwjgl.opengl.GL20.glVertexAttribPointer;
import static org.lwjgl.opengl.GL30.glBindVertexArray;
import static org.lwjgl.opengl.GL30.glGenVertexArrays;
import static org.lwjgl.opengl.GL45.glCreateBuffers;
import static org.lwjgl.opengl.GL45.glNamedBufferStorage;
import static org.lwjgl.system.MemoryUtil.NULL;

/**
 * @author SirMathhman
 * @version 0.0.0
 * @since 9/8/2017
 */
public class HelloTriangle {
    private static final int WIDTH = 800;
    private static final int HEIGHT = 600;

    private long window;
    private int vaoID;

    public static void main(String[] args) {
        new HelloTriangle().run();
    }

    private void run() {
        init();
        loop();
    }

    private void init() {
        GLFWErrorCallback.createPrint(System.err).set();

        if (!glfwInit()) {
            System.out.println("GLFW failed to initialize");
            System.exit(-1);
        }

        glfwDefaultWindowHints();
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);

        window = glfwCreateWindow(WIDTH, HEIGHT, "HelloWindow", NULL, NULL);
        if (window == NULL) {
            System.out.println("GLFW failed to create window");
            glfwTerminate();
            System.exit(-1);
        }

        glfwMakeContextCurrent(window);
        glfwShowWindow(window);

        float[] vertices = {
                -0.9f, -0.9f,
                0.85f, -0.9f,
                -0.9f, 0.85f,
                0.9f, -0.85f,
                0.9f, 0.9f,
                -0.85f, 0.9f
        };

        int buffer = glCreateBuffers();
        glNamedBufferStorage(buffer, vertices, vertices.length);

        vaoID = glGenVertexArrays();
        glBindVertexArray(vaoID);
        glBindBuffer(GL_ARRAY_BUFFER, buffer);
        glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
        glEnableVertexAttribArray(0);
    }

    private void loop() {
        GL.createCapabilities();

        while (!glfwWindowShouldClose(window)) {
            glClear(GL_DEPTH_BUFFER_BIT);
            glBindVertexArray(vaoID);
            glDrawArrays(GL_TRIANGLES, 0, 6);

            glfwSwapBuffers(window);
            glfwPollEvents();
        }

        glfwTerminate();
        System.exit(0);
    }
}

PS: Is there also a way to return a more detailed error thrown by the driver by LWJGL?


Answer:

glCreateBuffers and glNamedBufferStorage are OpenGL 4.5 commands. But you are requesting 3.3 (the glfwWindowHint commands).

If you want to stick to 3.3 version, try creating a buffer with glGenBuffers

Question:

Can I bind a opengl buffer object to multiple targets. For instance, I bind a buffer to the target array buffer and then bind the same buffer to SHADER_STORAGE_BUFFER or some otger target, is the buffer bound to the first second or both targets?


Answer:

OpenGL specifications:

void [gl]BindBuffer( enum target, uint buffer ); If the buffer object named buffer has not been previously bound, the GL creates a new state vector, initialized with a zero-sized memory buffer and comprising all the state and with the same initial values listed in table...

And

BindBuffer may also be used to bind an existing buffer object. If the bind is successful no change is made to the state of the newly bound buffer object, and any previous binding to target is broken.

So, yes: you can use the same name (as created with glGenBuffers) and bind this existing bound buffer with a different use (target in OpenGL parlance). But I can't think of a reason to do this.

Question:

With "OpenGL Depth Buffer has short range" I don't mean that the far plane is too close, its a problem with the depth buffer as a texture. If I look at the buffer it only shows Objects that are very close. I don't know how to explain it better just look at the pictures.

In the top right corner you can see the depth buffer. Images can be found here: http://imgur.com/a/wL87b

As you can see I have to get very close to see some darkness in the depth buffer.

Here is the code for creating the depth buffer for a FBO:

For a depth texture:

depthTexture = GL11.glGenTextures();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, depthTexture);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL14.GL_DEPTH_COMPONENT24, width, height, 0, GL11.GL_DEPTH_COMPONENT, GL11.GL_FLOAT, (ByteBuffer) null);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL11.GL_TEXTURE_2D, depthTexture, 0);

For a depth buffer:

depthBuffer = GL30.glGenRenderbuffers();
GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, depthBuffer);
GL30.glRenderbufferStorageMultisample(GL30.GL_RENDERBUFFER, multisampleing, GL14.GL_DEPTH_COMPONENT24, width, height);
GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL30.GL_RENDERBUFFER, depthBuffer);

You can ignore the GLXX. at the beginning of the OpenGL Methods.

If you need more code just tell me.


Answer:

As you can see I have to get very close to see some darkness in the depth buffer.

That's just how the hyperbolic depth buffer works.

Let's have a look at the projection matrix (I'm using the classical OpenGL conventions where camera looks along -z in eye space, and projection matrix flip from right handed to left handed space):

.    0       .             0
0    .       .             0
0    0  -(f+n)/(f-n)  -2*f*n/(f-n)
0    0      -1             0

(the . symbolizes just some numbers we don't need to care about here).

When you multiply that matrix with some eye space vector (x_eye, y_eye, z_eye, 1), you'll end up with

x_clip = ...
y_clip = ....
z_clip =  [-(f+n)/(f-n) ] *z_eye + [-2*f*n/(f-n)] * 1
w_clip = -z_eye

After the perspective divide by w_clip, we end up with our z value in normalized device coordinates (ndc):

z_ndc = z_clip / w_clip = (f+n)/(f-n) + 2*f*n/[(f-n)*z_eye]

Finally, the glDepthRange is applied to reach window space z. The default is to go from [-1,1] to [0,1], so let's do that here:

z_win = 0.5 * z_ndc + 0.5 = 0.5*(f+n)/(f-n)  + f*n/[(f-n)*z_eye] + 0.5

This is obviously a function of z_eye, and also of f and n. Let's assume you are using a near plane at distance 1 and a far plane at distance 1001, so this will evaluate to:

z_win(z_eye) = 1002/2000 + 1001/(1000 *z_eye) + 0.5 = 1001/1000 + 1001/(1000 * z_eye)

So, let's check what we got so far:

z_win(-1) = 0.  a point on the near plane ends up as 0 in the depth buffer
z_win(-1001) = 1.  a point on the far plane ends up as 1 in the depth buffer

This shouldn't surprise us, as this is per construction. But what happens to the points in between:

z_win(-50)  = 1001/1000 - 1001/50000  = 0.98098
z_win(-100) = 1001/1000 - 1001/100000 = 0.99099
z_win(-250) = 1001/1000 - 1001/250000 = 0.996996
z_win(-500) = 1001/1000 - 1001/500000 = 0.998998
z_win(-750) = 1001/1000 - 1001/750000 = 0.999665333

So, as you see, any object farer away than 100 units in eye space will end up with a depth buffer value > 0.99.

To put it the other way around, we can just calculate the eye space z for a point which will get 0.5 in the depth buffer:

z_eye(z_win) = 1001/(1000*z_win -1001)
z_eye(0.5) = -1.99800399

Yes, that's right, with a frustum from 1 to 1001 units away, only the range from one to two units in front of the camera will be mapped to the first half of the depth buffer range, and the 998 units after that are stuffed into the second half.

So, if you try to visualize the depth buffer just as colors, you won't see anything but the closest parts. With 8 bit color, everything above 254/255 = .996 will be fully saturated (which would be ~200 units in my example), and even below that, the differences will be so minute to be hardly visible at all.

If you want to just visualize the depth buffer, you should invert the hyperbolic distortion, and visualize linear (=eye space) depth.

Question:

I'm trying to make a post processing shader using a framebuffer. But when I attempt to sample the texture in the shaders it doesn't do anything.

As soon as I comment the line(in the fragment shader)

vec4 textureColour = texture(screenTexture, textureCoords);

out everything works again

FrameBuffer.java

package postprocessing;

import java.nio.ByteBuffer;

import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL14;
import org.lwjgl.opengl.GL30;
import org.lwjgl.opengl.GL32;

public class FrameBuffer {

protected static final int WIDTH = Display.getWidth();
private static final int HEIGHT = Display.getHeight();

private int framebuffer;
private int texture;
private int depthBuffer;
private int depthTexture;

public FrameBuffer()
{
    initialise();
}

public void cleanUp()
{
    GL30.glDeleteFramebuffers(framebuffer);
    GL11.glDeleteTextures(texture);
    GL30.glDeleteRenderbuffers(depthBuffer);
    GL11.glDeleteTextures(depthTexture);
}

public int getTexture()
{
    return texture;
}

public int getDepthTexture()
{
    return depthTexture;
}

private void initialise()
{
    framebuffer = createFrameBuffer();
    texture = createTextureAttachment(WIDTH, HEIGHT);
    depthBuffer = createDepthBufferAttachment(WIDTH, HEIGHT);
    depthTexture = createDepthTextureAttachment(WIDTH, HEIGHT);
    unbindCurrentFrameBuffer();
}

public void bindFrameBuffer(){
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);//To make sure the texture isn't bound
    GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, framebuffer);
    GL11.glViewport(0, 0, WIDTH, HEIGHT);
}

public void unbindCurrentFrameBuffer() {//call to switch to default frame buffer
    GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0);
    GL11.glViewport(0, 0, Display.getWidth(), Display.getHeight());
}

private int createFrameBuffer() {
    int frameBuffer = GL30.glGenFramebuffers();
    //generate name for frame buffer
    GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBuffer);
    //create the framebuffer
    GL11.glDrawBuffer(GL30.GL_COLOR_ATTACHMENT0);
    //indicate that we will always render to color attachment 0
    return frameBuffer;
}

private int createTextureAttachment( int width, int height) {
    int texture = GL11.glGenTextures();
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture);
    GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, width, height,
            0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, (ByteBuffer) null);
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
    GL32.glFramebufferTexture(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0,
            texture, 0);
    return texture;
}

private int createDepthTextureAttachment(int width, int height){
    int texture = GL11.glGenTextures();
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture);
    GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL14.GL_DEPTH_COMPONENT32, width, height, 0, GL11.GL_DEPTH_COMPONENT, GL11.GL_FLOAT, (ByteBuffer) null);
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
    GL32.glFramebufferTexture(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, texture, 0);
    return texture;
}

private int createDepthBufferAttachment(int width, int height) {
    int depthBuffer = GL30.glGenRenderbuffers();
    GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, depthBuffer);
    GL30.glRenderbufferStorage(GL30.GL_RENDERBUFFER, GL11.GL_DEPTH_COMPONENT, width,
            height);
    GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT,
            GL30.GL_RENDERBUFFER, depthBuffer);
    return depthBuffer;
}
}

FrameBufferShader.java

package postprocessing;

import shaders.ShaderProgram;

public class FrameBufferShader extends ShaderProgram {

private static final String VERTEX_FILE = "src/postprocessing/vertexShader.txt";
private static final String FRAGMENT_FILE = "src/postprocessing/fragmentShader.txt";

private int location_texture;
private int location_depthMap;

public FrameBufferShader()
{
    super(VERTEX_FILE, FRAGMENT_FILE);
}

@Override
protected void getAllUniformLocations()
{
    bindAttributes(0, "position");
}

@Override
protected void bindAttributes()
{
    location_texture = super.getUniformLocation("screenTexture");
    location_depthMap = super.getUniformLocation("depthMap");
}

public void connectTextureUnits()
{
    super.loadInt(location_texture, 0);
    super.loadInt(location_depthMap, 1);
}
}

FrameBufferRenderer.java

package postprocessing;

import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;

import models.RawModel;
import renderEngine.Loader;

public class FrameBufferRenderer {

private RawModel quad;
private FrameBufferShader shader;
private FrameBuffer fbo;

public FrameBufferRenderer(Loader loader, FrameBufferShader shader, FrameBuffer fbo)
{
    this.fbo = fbo;
    this.shader = shader;
    setUpVAO(loader);
    shader.start();
    shader.connectTextureUnits();
    shader.stop();
}

public void render()
{
    prepareRender();
    GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, quad.getVertexCount());
    unbind();
}

private void prepareRender()
{
    shader.start();
    GL30.glBindVertexArray(quad.getVaoID());
    GL20.glEnableVertexAttribArray(0);
    GL13.glActiveTexture(GL13.GL_TEXTURE0);
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, fbo.getTexture());
    GL13.glActiveTexture(GL13.GL_TEXTURE1);
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, fbo.getDepthTexture());

    GL11.glEnable(GL11.GL_BLEND);
    GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
}

private void unbind()
{
    GL11.glDisable(GL11.GL_BLEND);
    GL20.glDisableVertexAttribArray(0);
    GL30.glBindVertexArray(0);
    shader.stop();
}

private void setUpVAO(Loader loader) {
    float[] vertices = { -1, -1, 1, -1, 1, 1, -1, 1 };
    quad = loader.loadtoVAO(vertices, 2);
}
}

Vertex Shader

#version 400

in vec2 position;

void main()
{
    gl_Position = vec4(position.x, position.y, 0.0, 1.0);
}

Fragment Shader

#version 400

in vec2 textureCoords;

out vec4 outColor;

uniform sampler2D screenTexture;
uniform sampler2D depthTexture;

void main()
{
    vec4 textureColour = texture(screenTexture, textureCoords);

    outColor = vec4(1.0, 1.0, 1.0, 1.0);
}

Answer:

You can't sample the destination texture in the shader.

What you can do is make a new texture and make that the destination texture for the previous step and use it as a normal texture in the current step.

Question:


Answer:

You misunderstood the glCreateBuffers() function. Instead of binding the buffer itself to OpenGL, you generate an ID:

IntBuffer buffer = BufferUtils.createIntBuffer(1);
glCreateBuffers(buffer);
int id = buffer.get(0);

You could also just call glCreateBuffers() without arguments and use the return value as ID:

int id = glCreateBuffers();

To write data to this buffer you first have to bind it, this just tells OpenGL that you want to write to the bound offer.

glBindBuffer(GL_ARRAY_BUFFER, id);

As you can see you pass in the generated ID, to bind the corresponding buffer.

Next you can write to the OpenGL buffer, like this:

glBufferData(GL_ARRAY_BUFFER, g_vertex_buffer_data, GL_STATIC_DRAW);

This sends the contents of g_vertex_buffer_data to the OpenGL context on the GPU. g_vertex_buffer_data contains your vertex data (model data) and you do not want to create a buffer OF this java.nio.Buffer, but let OpenGL generate an ID for a GPU-buffer and then send the contents of your java.nio.Buffer to the GPU-buffer.

For information look at the LWJGL Wikipage about Vertex Buffer.

Question:


Answer:

You need to set up the pointers with a VAO, a Vertex Array Object.

int vaoID = glGenVertexArrays();

Then you need to bind it, and set up the pointers with the VBOs, Vertex Array Objects.

glBindVertexArray(vaoID);
glEnableVertexAttribArray(indexLocation);

glBindBuffer(GL_ARRAY_BUFFER, vboID);
glVertexAttribPointer(indexLocation, 2, GL_FLOAT, false, 0, 0);

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);

Then everytime you render, bind the VAO, and issue a draw command.

glBindVertexArray(vaoID);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);

Then finally, you need to dispose the VAO object.

glBindVertexArray(0);
glDeleteVertexArrays(vaoID);

Hope this helps.

Question:

I am trying to render all my renderings to a framebuffer instead of the backbuffer, while using the LWJGL. I do the following things for the graphics. Setting up the display and setting up OpenGL:

    try {
        Display.setDisplayMode(new DisplayMode(1024, 768));
        Display.create();
    } catch (Exception e) {
        e.printStackTrace();
        System.exit(0);
    }
    Display.setTitle(WINDOW_NAME);

    GL11.glMatrixMode(GL11.GL_PROJECTION);
    GL11.glLoadIdentity();
    GL11.glOrtho(0, 1024, 0, 768, 1, -1);
    GL11.glMatrixMode(GL11.GL_MODELVIEW);

Then I create a framebuffer object:

    m_width = p_width;
    m_height = p_height;


    m_frameBufferObject = glGenFramebuffersEXT();
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_frameBufferObject);
    m_depthBuffer = glGenRenderbuffersEXT();
    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer);
    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, p_width, p_height);

    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer);
    m_frameBufferTexture = glGenTextures();
    glBindTexture(GL_TEXTURE_2D, m_frameBufferTexture);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, p_width, p_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (java.nio.ByteBuffer)null);
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_frameBufferTexture, 0);

The rendering is then done like this (currently I try only to draw one pixel):

    // Bind the framebuffer object.
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_frameBufferObject);
    glPushAttrib(GL_VIEWPORT_BIT);
    glViewport(0, 0, m_width, m_height);
    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);  

    // Clear with black
    GL11.glColor3f(0.0f, 0.0f, 0.0f);

    GL11.glBegin(GL11.GL_POINTS);
    setOpenGLColour(new Colour(Colour.RED));
    GL11.glVertex2f(100, 100);
    GL11.glEnd();

    //Deactivate the framebuffer object
    glPopAttrib();
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

    //Render the framebuffer object to the screen
    GL11.glBegin(GL11.GL_QUADS);
    GL11.glTexCoord2f(0f, 0f);
    GL11.glVertex2f(0, 0);
    GL11.glTexCoord2f(1f, 0f);
    GL11.glVertex2f(1024, 0); 
    GL11.glTexCoord2f(1f, 1f);
    GL11.glVertex2f(1024, 768);
    GL11.glTexCoord2f(0f, 1f);
    GL11.glVertex2f(0, 768);
    GL11.glEnd();

The problem is: The complete screen is red now. Not just a red pixel, but the complete screen is coloured red. If I do not draw the pixel, then the screen ist just black. Can someone tell me what I may be doing wrong, or how this is done right?


Answer:

It looks like you're not getting texturing when you try to copy the FBO rendering result to the screen. Since you set the current draw color to red, it will simply draw the screen size quad in red.

The one thing I see missing is that texturing is never enabled. Add this before starting the final draw command:

glEnable(GL_TEXTURE_2D);

The texture also needs to be bound, which would typically happen during the draw function. But since you bound the texture during setup, and never unbound it, that part is most likely not causing the issue.

Question:

I have a class that represents all the data for my quads, each class having a position and a color. How could I pass an array of that class to opengl? I tried this:

GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, VBO);

GL15.glBufferData(VBO, MAX_QUADS, GL15.GL_DYNAMIC_DRAW);
ByteBuffer data = GL15.glMapBuffer(GL15.GL_ARRAY_BUFFER, GL15.GL_WRITE_ONLY, null);

GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);

But now I don't know how to parse the array to bytes so I can pass to the GPU. This is the array:

Quad.Data[] vertexData = new Quad.Data[MAX_QUADS];

And this is the class with the position and color:

public class Data {
    public Vector3f position;
    public Vector4f color;
}

Answer:

You can put the float values of your Data Class in a FloatBuffer and then pass it to OpenGL by using glBufferData(), or glBufferSubData if the Buffer is already allocated.

With your code, it would look similar to this:

//Creating the FloatBuffer and store the Data
//n = number of floats you want to store, in this case 7 for each Quad;
FloatBuffer buffer = MemoryUtil.memAllocFloat(n);

//Do this for each "Data", thus for each Vertex of your Quad
buffer.put(position.x).put(position.y).put(position.z).put(color.r).put(color.g).put(color.b).put(color.a);
//Don't forget flipping the Buffer before passing it to OpenGL, otherwise you will get an EXCEPTION_ACCESS_VIOLATION
buffer.flip();

//Binding the VBO and allocate it
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER);
GL15.glBufferData(VBO, MAX_QUADS, GL15.GL_DYNAMIC_DRAW);

//Sending the Buffer to OpenGL
GL15.glBufferSubData(0, buffer);

//Unbind the Buffer
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);

Question:

I need to update my mesh with new vertices. I create the VBO as such (initially it gets created with only one vertex in it):

public Mesh(float[] vertex, int size)
{
    texture = null;
    meshType = 1;           //will draw lines

    FloatBuffer verticesBuffer = null;
    IntBuffer indicesBuffer = null;
    int vboID;

    try
    {
        vertexCount = size;

        vaoID = glGenVertexArrays();
        glBindVertexArray(vaoID);

        vboIDList = new ArrayList<>();

        // Vertices VBO generation
        vboID = glGenBuffers();
        vboIDList.add(vboID);
        verticesBuffer = MemoryUtil.memAllocFloat(size * 3);        // !!! Must Be manually freed!
        verticesBuffer.put(vertex).flip();
        glBindBuffer(GL_ARRAY_BUFFER, vboID);
        glBufferData(GL_ARRAY_BUFFER, verticesBuffer, GL_STATIC_DRAW);
        glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
        vertexAttrArrCount += 1;

        // Indices VBO generation
        vboID = glGenBuffers();
        vboIDList.add(vboID);
        indicesBuffer = MemoryUtil.memAllocInt(size);             // !!! Must be manually freed!
        indicesBuffer.put(new int[]{0}).flip();
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboID);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL_STATIC_DRAW);

        // unbinding
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindVertexArray(0);
    }
    finally
    {
        if (verticesBuffer != null)
        {
            MemoryUtil.memFree(verticesBuffer);                             // Freeing vertex buffer
        }

        if (indicesBuffer != null)
        {
            MemoryUtil.memFree(indicesBuffer);                              // Freeing indices buffer
        }
    }

}

then I want to update the VBO buffer and write new vertices into it. Note that I do create VBO to have enough space for my new vertices, and I do control that it doesn't get overfilled. I also control how many elements I draw with each render call, so I don't draw the empty 0/0/0 vertices.

My problem is, this code WORKS:

public void updateVBO(float[] vertices, int[] indices, int size)
{
    if (meshType == 1)
    {
        lineCount = size;

        FloatBuffer subDataF = null;
        IntBuffer subDataI = null;
        int vboID;

        try
        {
            //System.out.printf("Adding vertex (%f, %f, %f) to position %d\n",vertex.x,vertex.y,vertex.z,position);
            vboID = vboIDList.get(0);
            //float[] vert = new float[]{vertex.x, vertex.y, vertex.z};
            subDataF = MemoryUtil.memAllocFloat(vertices.length);        // !!! Must Be manually freed!
            subDataF.put(vertices).flip();
            glBindBuffer(GL_ARRAY_BUFFER, vboID);
            glBufferData(GL_ARRAY_BUFFER, subDataF, GL_STATIC_DRAW);
            glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);

            vboID = vboIDList.get(1);
            //int[] index = new int[]{ position };
            subDataI = MemoryUtil.memAllocInt(indices.length);        // !!! Must Be manually freed!
            subDataI.put(indices).flip();
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboID);
            glBufferData(GL_ELEMENT_ARRAY_BUFFER, subDataI, GL_STATIC_DRAW);

            //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        }
        finally
        {
            if (subDataF != null)
            {
                MemoryUtil.memFree(subDataF);
            }
            if (subDataI != null)
            {
                MemoryUtil.memFree(subDataI);
            }
        }
    }
}

so when I pass the entire vertices array, and re-allocate VBO memory from scratch - it draws exactly what I need it to. However I would like to use glBufferSubData, so that I don't re-allocate the momory each time I add new vertex. And this code DOESN'T WORK:

public void addVertex(Vector3f vertex, int position)
{
    if (meshType == 1)
    {
        FloatBuffer subDataF = null;
        IntBuffer subDataI = null;
        int vboID;

        lineCount = position+1;

        try
        {
            System.out.printf("Adding vertex (%f, %f, %f) to position %d\n",vertex.x,vertex.y,vertex.z,position);
            vboID = vboIDList.get(0);
            float[] vert = new float[]{vertex.x, vertex.y, vertex.z};
            subDataF = MemoryUtil.memAllocFloat(3);        // !!! Must Be manually freed!
            subDataF.put(vert).flip();
            glBindBuffer(GL_ARRAY_BUFFER, vboID);
            glBufferSubData(GL_ARRAY_BUFFER, position * 3 * 4, subDataF);
            glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);

            vboID = vboIDList.get(1);
            int[] index = new int[]{ position };
            subDataI = MemoryUtil.memAllocInt(1);        // !!! Must Be manually freed!
            subDataI.put(index).flip();
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboID);
            glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, position * 4, subDataI);

            glBindBuffer(GL_ARRAY_BUFFER, 0);
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        }
        finally
        {
            if (subDataF != null)
            {
                MemoryUtil.memFree(subDataF);
            }
            if (subDataI != null)
            {
                MemoryUtil.memFree(subDataI);
            }
        }
    }
}

Also I'm aware it's not optimized the way I create the floatbuffer and intbuffer, I just want to get it to work before I clean this up. I was trying a bunch of things, so the last piece of code is weird because of that.

Still, I don't understand what I'm doing wrong. I did check that I pass all the data correctly, and that the position (and offset) seem to be calculated how they should be. And it just doesn't draw anything, while when I use glBufferData it does.

Could someone explain where I'm making a mistake?

After all suggestions, here's what I end up with, but it still doesn't work at all:

public void addVertex(Vector3f vertex, int position)
{
    if (meshType == 1)
    {
        FloatBuffer subDataF = null;
        IntBuffer subDataI = null;
        int vboID;

        lineCount = position+1;

        try
        {
            System.out.printf("Adding vertex (%f, %f, %f) to position %d\n",vertex.x,vertex.y,vertex.z,position);
            vboID = vboIDList.get(0);
            float[] vert = new float[]{vertex.x, vertex.y, vertex.z};
            subDataF = MemoryUtil.memAllocFloat(3);        // !!! Must Be manually freed!
            subDataF.put(vert).flip();
            glBindBuffer(GL_ARRAY_BUFFER, vboID);
            glBufferSubData(GL_ARRAY_BUFFER, (long)(position * 3 * 4), (FloatBuffer)subDataF);
            glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);

            vboID = vboIDList.get(1);
            int[] index = new int[]{ position };
            subDataI = MemoryUtil.memAllocInt(1);        // !!! Must Be manually freed!
            subDataI.put(index).flip();

            glBindVertexArray(vaoID);
            glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, (long)(position * 4), (IntBuffer)subDataI);
        }
        finally
        {
            if (subDataF != null)
            {
                MemoryUtil.memFree(subDataF);
            }
            if (subDataI != null)
            {
                MemoryUtil.memFree(subDataI);
            }
        }
    }
}

I did check that VAO ID is correct.


Answer:

Just as I thought, it was something stupid, and not at all connected to VAO binding and such.

The thing is, when I create VBO initially, I do it like this:

// Vertices VBO generation
        vboID = glGenBuffers();
        vboIDList.add(vboID);
        verticesBuffer = MemoryUtil.memAllocFloat(size * 3);        // !!! Must Be manually freed!
        verticesBuffer.put(vertex).flip();
        glBindBuffer(GL_ARRAY_BUFFER, vboID);
        glBufferData(GL_ARRAY_BUFFER, verticesBuffer, GL_STATIC_DRAW);
        glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
        vertexAttrArrCount += 1;

I assumed that because I allocate buffer for size*3 floats, it will be of that size, and when I put it in the VBO - it will allocate size*3*4 bytes, i.e. enough for size*3 floats.

Turns out Nope! Because I put only one vertex (3 floats) into the buffer - it will allocate only that amount of space. So when I later try to use glBufferSubData - it only has spaces for 3 floats on the GPU, and naturally doesn't put the values where I need them. I'm actually surprised it doesn't flat-out crash on me.

To fix this, at the moment I did this instead:

// Vertices VBO generation
        ...
        verticesBuffer.put(vertex).put(new float[size*3 - 3]).flip();
        ...

So basically I'm manually putting an empty array into the FloatBuffer, and that ensures that the buffer is the right size.

Here's the result: Constructor:

public Mesh(float[] vertex, int size)
{
    texture = null;
    meshType = 1;           //will draw lines

    FloatBuffer verticesBuffer = null;
    IntBuffer indicesBuffer = null;
    int vboID;

    try
    {
        vertexCount = size;

        vaoID = glGenVertexArrays();
        glBindVertexArray(vaoID);

        vboIDList = new ArrayList<>();

        // Vertices VBO generation
        vboID = glGenBuffers();
        vboIDList.add(vboID);
        verticesBuffer = MemoryUtil.memAllocFloat(size * 3);        // !!! Must Be manually freed!
        verticesBuffer.put(vertex).put(new float[size*3 - 3]).flip();
        glBindBuffer(GL_ARRAY_BUFFER, vboID);
        glBufferData(GL_ARRAY_BUFFER, verticesBuffer, GL_STATIC_DRAW);
        glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
        vertexAttrArrCount += 1;

        // Indices VBO generation
        vboID = glGenBuffers();
        vboIDList.add(vboID);
        indicesBuffer = MemoryUtil.memAllocInt(size);             // !!! Must be manually freed!
        indicesBuffer.put(new int[size]).flip();                  // I need the first element 0 anyway
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboID);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL_STATIC_DRAW);

        // unbinding
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindVertexArray(0);
    }
    finally
    {
        if (verticesBuffer != null)
        {
            MemoryUtil.memFree(verticesBuffer);                             // Freeing vertex buffer
        }

        if (indicesBuffer != null)
        {
            MemoryUtil.memFree(indicesBuffer);                              // Freeing indices buffer
        }
    }

}

And then updating:

public void addVertex(Vector3f vertex, int position)
{
    if (meshType == 1)
    {
        FloatBuffer subDataF = null;
        IntBuffer subDataI = null;
        int vboID;

        lineCount = position+1;

        try
        {
            vboID = vboIDList.get(0);
            float[] vert = new float[]{vertex.x, vertex.y, vertex.z};
            subDataF = MemoryUtil.memAllocFloat(vert.length);        // !!! Must Be manually freed!
            subDataF.put(vert).flip();
            glBindBuffer(GL_ARRAY_BUFFER, vboID);
            glBufferSubData(GL_ARRAY_BUFFER, (long)(position * 3 * 4), (FloatBuffer)subDataF);
            glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);

            vboID = vboIDList.get(1);
            int[] index = new int[]{ position };
            subDataI = MemoryUtil.memAllocInt(index.length);        // !!! Must Be manually freed!
            subDataI.put(index).flip();
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboID);
            glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, (long)(position * 4), (IntBuffer)subDataI);

            glBindBuffer(GL_ARRAY_BUFFER, 0);
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        }
        finally
        {
            if (subDataF != null)
            {
                MemoryUtil.memFree(subDataF);
            }
            if (subDataI != null)
            {
                MemoryUtil.memFree(subDataI);
            }
        }
    }
}

And it works. Do note that the code is a bit dirty, I didn't clean it up before posting an answer.

Question:

Here is the file im trying to read:

P 1.0 0.0 0.0
80 10
80 30
230 37
280 30
280 10
T
t 100 -75
r 30 0 0
s 0.5 1.5 0 0

Heres part of my code:

File file = new File("coordinatess.txt");
BufferedReader br = new BufferedReader(new FileReader(file));
String st;
glPushMatrix();
while ((st = br.readLine()) != null){
                        String str[] = st.split(" ");
                        if(str[0].equalsIgnoreCase("P")){
                            glColor3f(Float.parseFloat(str[1]), Float.parseFloat(str[2]), Float.parseFloat(str[3]));

                        }
                        else if(str[0].equalsIgnoreCase("T")){
                            br.readLine();
                        }
                        else if(str[0].equalsIgnoreCase("r")){
                            glRotatef(Float.parseFloat(str[1]), Float.parseFloat(str[2]), Float.parseFloat(str[3]), 0);
                        }
                        else if(str[0].equalsIgnoreCase("s")){
                            glScalef(Float.parseFloat(str[1]), Float.parseFloat(str[2]), Float.parseFloat(str[3]));
                        }
                        else if(str[0].equalsIgnoreCase("t")){
                            glTranslatef(Float.parseFloat(str[1]), Float.parseFloat(str[2]), 0);
                        }

                    }

I'm kind of having trouble reading the line without any letters. Its just integers. How would I read those lines specifically, after "P"?


Answer:

use nested level to parse values Integer.parseInt(value) with exception handling

String str = "T 10 5.7";
String[] strings = str.split(" ");
for (String string : strings) {
    try {
        System.out.println(Integer.parseInt(string));
    } catch (Exception e) {
        try {
            System.out.println(Float.parseFloat(string));
        } catch (Exception e2) {
            System.out.println(string);
        }
    }
}

Question:

I'm following the 3D Game Development with LWJGL book from Antonio Bejarano. I have reached the point of being able to render a quad to the screen. After having implemented the vertex index buffer, only one triangle of the quad renders to the screen, so I think it is safe to assume the problem is with that code.

        // Vertex Index Buffer
        idxVboId = glGenBuffers();
        vertsIdxBuffer = MemoryUtil.memAllocInt(indices.length);
        vertsIdxBuffer.put(indices).flip();
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,idxVboId);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER,vertsIdxBuffer,GL_STATIC_DRAW);

The code for the vertices buffer and the colour buffer works, as I have removed the references to the index buffer and the full quad appears. I have also changed the render method to account for the new type to be rendered:

    shaderProgram.bind();

        //bind to vao
        glBindVertexArray(mesh.getVaoId());
        //enable positions buffer
        glEnableVertexAttribArray(0);
        //enable colour buffer
        glEnableVertexAttribArray(1);

        //draw verts
        glDrawElements(GL_TRIANGLES, 
        mesh.getVertexCount(),GL_UNSIGNED_INT,0);

        //restore state (?)
        glDisableVertexAttribArray(0);
        glDisableVertexAttribArray(1);
        glBindVertexArray(0);

        shaderProgram.unbind();

Any suggestions are appreciated as I have been staring at this for hours and can't really see where I've made the mistake.

EDIT: Quad Mesh Code

     renderer.init();

    float[] positions = 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,
            -0.5f, -0.5f, 0.0f,
            0.5f, -0.5f, 0.0f,
    };

    float[] colours = new float[]{0.5f,0f,0f,0f,0.5f,0f,0f,0f,0.5f,0f,0.5f,0.5f};

    int[] indices = new int[]{
            0, 1, 3, 3, 1, 2,
    };

    mesh = new BMesh(positions,colours,indices);

2ND Edit Before and after positions array change

Before

After


Answer:

After looking through the quad mesh initialization code, it seems the error is due to vertices 3 and 2 on the second quad being the same vertex, i.e. both are at (0.5, 0.5, 0.0). Perhaps you mistakenly copied the 4th and 5th vertices in your array?

i.e. perhaps you meant to have

float[] positions = 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
};

EDIT: Your indices seem to be wrong. Change them to { 0, 1, 3, 0, 3, 2 }

Question:

I tried to implement uniform buffer object to my game, but for some reason I haven't got it working. I don't think it currently sends anything to shaders. Before UBO everything worked fine. This is fully temporary system. I just wanted to get it working.

My UBO class:

private int ubo;

public void createUBO() {

    ubo = GL15.glGenBuffers();

}

public void allocate(int bytes) {

    bindBuffer();

    GL15.glBufferData(GL31.GL_UNIFORM_BUFFER, bytes, GL15.GL_STATIC_DRAW);

    unbindBuffer();

}

public void updateUBO(FloatBuffer buffer) {

    buffer.flip();

    bindBuffer();

    GL15.glBufferSubData(GL31.GL_UNIFORM_BUFFER, 0, buffer);

    unbindBuffer();

}

My gameloop:

public void init() {

    ubo = new UBO();

    ubo.createUBO();
    ubo.allocate(64);

}

public void render() {

    basicEntityShader.start();
    basicEntityShader.loadFog(fogColor, fogDensity, fogGradient);
    basicEntityShader.loadLights(lights);

    Matrix4f viewMatrix = Maths.createViewMatrix(camera);
    FloatBuffer buffer = BufferUtils.createFloatBuffer(16);
    viewMatrix.storeTranspose(buffer);

    ubo.updateUBO(buffer);

    basicEntityShader.setUBO(ubo);
    basicEntityShader.bindUniformBlocks();
    entityRenderer.render(entities, camera);

}

Shader:

layout (std140) uniform Matrices  {

    mat4 viewMatrix;

};

Bindings:

GL30.glBindBufferRange(GL31.GL_UNIFORM_BUFFER, 0, ubo.getUbo(), 0, 64);

int block = GL31.glGetUniformBlockIndex(programID, "Matrices");

GL31.glUniformBlockBinding(programID, block, 0);

Answer:

Before implementing a lot of sugar code, make sure you got it working and then shift step by step to util classes and so on.

So, get rid of the UBO class and in the init:

  • glGenBuffers, glBufferData, glBindBufferBase (later -range, it involves some additional offset stuff)

  • then set up your shader, be sure is >= 0 and glGetUniformBlockIndex != -1 and then glUniformBlockBinding

  • get rid also of:

    basicEntityShader.setUBO(ubo);
    basicEntityShader.bindUniformBlocks();
    
  • allocate a floatbuffer in the init, don't do it every time in the render loop.

Now, in the render:

  • better to avoid consuming your buffers and deal with position set/reset or flip/rewind in order to reduce error exposure. Then do a for and save your viewMatrix inside your buffer.

  • bind your buffer, glBufferSubData and unbind

Question:

I've tried to implement deferred shading but the gbuffer can't store any floating point numbers. The edges from the lighting is VERY rough since the framebuffer can't store negative components for the normals eventhough i passed in the correct internal format and data type.

Example picture of the rough edges

Texture generation:

    public TextureResource(int width, int height, int filter, int internalFormat, int format, boolean clamp, int dataType, ByteBuffer data) {
    id = glGenTextures();
    glBindTexture(GL_TEXTURE_2D, id);
    glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, dataType, data);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
    if(clamp) {
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    }
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
    glBindTexture(GL_TEXTURE_2D, 0);
}

Framebuffer generation:

this.width = width;
    this.height = height;
    this.attachments = attachments;
    boolean hasDepth = false;
    IntBuffer drawBuffers = Util.createIntBuffer(attachments.length);
    assert(attachments.length <= MAX_ATTACHMENTS);
    framebuffer = glGenFramebuffers();
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    for(int i = 0; i < attachments.length; i++) {
        if(attachments[i].getAttachmentType() == GL_DEPTH_ATTACHMENT) {
            drawBuffers.put(GL_NONE);
            hasDepth = true;
        } else {
            drawBuffers.put(attachments[i].getAttachmentType());
        }
        if(attachments[i].getAttachmentType() == GL_NONE) {
            continue;
        }
        attachments[i].createTexture(width, height);
        glFramebufferTexture2D(GL_FRAMEBUFFER, attachments[i].getAttachmentType(), GL_TEXTURE_2D, attachments[i].getTexture().getId(), 0);
    }
    if(!hasDepth) {
        renderbuffer = glGenRenderbuffers();
        glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer);
    }
    drawBuffers.flip();
    glDrawBuffers(drawBuffers);
    if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
        System.err.println("Framebuffer creation failed!");
        System.exit(1);
    }

GBuffer:

super(width, height, new FramebufferAttachment(GL_COLOR_ATTACHMENT1, GL_NEAREST, GL_RGB32F, GL_RGB, false, GL_FLOAT),
                         new FramebufferAttachment(GL_COLOR_ATTACHMENT0, GL_NEAREST, GL_RGB32F, GL_RGB, false, GL_FLOAT),
                         new FramebufferAttachment(GL_COLOR_ATTACHMENT2, GL_NEAREST, GL_RGB, GL_RGB, false, GL_UNSIGNED_BYTE));

Geometry pass fragment shader:

    #version 330 core

in vec3 worldPos0;
in vec2 texCoord0;
in vec3 normal0;

layout (location = 0) out vec3 gWorldPos;
layout (location = 1) out vec3 gNormal;
layout (location = 2) out vec3 gColor;

uniform sampler2D diffuse;

void main() {
    gWorldPos = worldPos0;
    gNormal = normalize(normal0);
    gColor = texture(diffuse, texCoord0).xyz;
}

Answer:

It's because it is 3.3 core. OpenGL standard somewhat contradicts itself on the matter of what format are renderable, some implementations actually support RGBxF formats. OpenGL 4.4 specs declare them renderable.

Ifit is really needed, I think is it possible to map integer values to floating point. Ofc you still have limited amount of values, but you can implement negative and fraction values, while having limited range

Question:

I have created 1 float buffer and 1 vbo with all my vertex data(position, texture coordinates, normals), they are stored as follow:

            bf.put(vertices[i].position.x);
            bf.put(vertices[i].position.y);
            bf.put(vertices[i].position.z);
            bf.put(vertices[i].texCoords.x);
            bf.put(vertices[i].texCoords.y);
            bf.put(vertices[i].normals.x);
            bf.put(vertices[i].normals.y);
            bf.put(vertices[i].normals.z);

How can I pass them to the shader using glVertexAttribPointer ?

Is it possible to do something like:

 glEnableVertexAttribArray(0);

            glBindBuffer(GL_ARRAY_BUFFER, vbo);
            glVertexAttribPointer(/*arguments for sending position*/);
 glEnableVertexAttribArray(1);

            glBindBuffer(GL_ARRAY_BUFFER, vbo);
            glVertexAttribPointer(/*arguments for sending texture coordinates*/);

glEnableVertexAttribArray(2);

            glBindBuffer(GL_ARRAY_BUFFER, vbo);
            glVertexAttribPointer(/*arguments for sending normals*/);

?

If it is, then please help me understand glVertexAttribPointer and what arguments I should put.


Answer:

The data arrangement you are using for your attributes is typically called "interleaved", and is in fact the recommended way of storing multiple attributes in a VBO. It favors local data access because all attributes for a vertex are next to each other in memory, which in turn tends to result in high cache hit rates.

Let's look at the signature of glVertexAttribPointer(), and then explain the arguments in some more detail. I intentionally won't copy the explanation from the documentation, in the hope that alternate wording will help you understand them better. In LWJGL, it is defined as:

static void glVertexAttribPointer(
    int index, int size, int type, boolean normalized,
    int stride, long pointerOffset)
  • index: Location of the vertex attribute in the vertex shader, as specified with glBindAttribLocation(), obtained with glGetAttribLocation(), or specified in the shader code with the location layout qualifier.
  • size: Number of components in the attribute. E.g. 3 for positions with 3 coordinates, 2 for texture coordinates with 2 components, etc.
  • type: Type of attribute. Mostly GL_FLOAT.
  • normalized: Does not matter for float attributes, read up on it if you ever start using integer type attributes.
  • stride: Spacing in bytes between subsequent vertices. Unless you have padding between vertices (which is fairly rare), this is the same as the size of a vertex in bytes.
  • pointerOffset: This has "pointer" in its name for historical reasons, but is in fact the offset in bytes of the first occurrence of the attribute relative to the start of the buffer. In an interleaved arrangement, this corresponds to the offset of the attribute within the vertex, in bytes.

In your case, stride will be 32, since each vertex consists of 8 float components, which are 4 bytes each.

The pointerOffset is 0 for the first attribute, and then the relative byte offset for all the rest of them, which results in 12 and 20 for the remaining two attributes.

This makes the calls for your example:

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * 4, 0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 8 * 4, 3 * 4);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 8 * 4, (3 + 2) * 4);

Question:

When I call glGetTexImage() on a texture from a Framebuffer, I get this error:

EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffabf967a2b, pid=1816, tid=14712

Here is my code:

MagicaAdventura.GAME.gameBuffer.bindTexture();
glGetTexImage(GL_TEXTURE_2D, 0, GL12.GL_BGR, GL_UNSIGNED_BYTE, buf);//line that causes the error

And here is the code for the bind method:

public void bind(int texture) {
    if(currentBound[texture] != resource.getID() || lastBoundInFramebuffer != Renderer.CURRENT_FRAMEBUFFER) {
        GL13.glActiveTexture(GL13.GL_TEXTURE0 + texture);
        lastBoundInFramebuffer = Renderer.CURRENT_FRAMEBUFFER;
        currentBound[texture] = resource.getID();
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, resource.getID());
    }
}

The texture binding code works fine for other things.


Answer:

The buffer wasn't allocating space for the padding the texture to a power of 2 so I switched to using glReadPixels.

Question:


Answer:

After a while, I found out, that you can use the glTexImage2D method, to store a ByteBuffer in a texture.