Why doesn't this attribute data get loaded to the vertex shader correctly?

1

I want add an array of integers to my vertex array object, to define, which image should be used for that specific vertex, but somehow, the data is getting corrupted on the way or isn't loaded correctly.

I've already tried loading a preset array and just selecting the correct index using the gl_VertexID, which worked, but I would prefer having all the data in the vertex array and not having to load a uniform integer array each frame.

The vertex shader

#version 330 core

layout (location = 0) in vec4 position;
layout (location = 1) in vec2 textureCoordinate;
//layout (location = 2) in vec3 normals;
layout (location = 3) in int textureIndex;
//layout (location = 4) in mat4 modelMatrix;

// ---------------Temporary--------------
uniform mat4 view;
uniform mat4 model;
// ---------------Temporary end----------

flat out int textureIndexOut;

out DATA {
    vec2 tc;
} vs_out;

void main() {
    mat4 mvp = view * model; 
    gl_Position = mvp * position;
    vs_out.tc = textureCoordinate;
    textureIndexOut = textureIndex;
}

The fragment shader

#version 330 core

layout (location = 0) out vec4 color;

flat in int textureIndexOut;

in DATA {
    vec2 tc;
} fs_in;

uniform sampler2D textureSamplers[32];

void main() {
    color = texture(textureSamplers[1], fs_in.tc);
}

Creating a vertex array`

public static VertexArray createVAO(float[] vertices, int[] indices, float[] textureCoordinates, 
            float[] normals, int[]textureIndices) {
        int count = indices.length;
        int indexBufferObject = createIndexBuffer(indices);
        int vertexArrayObject = laodVertexArrayObject();
        storeDataInAttributeList(ShaderProgram.VERTEX_ATTRIB, vertices, 3);
        storeDataInAttributeList(ShaderProgram.TEXTURECOORDINATE_ATTRIB, textureCoordinates, 2);
        storeDataInAttributeList(ShaderProgram.TEXTURE_INDEX_ATTRIB, textureIndices, 1);
        return new VertexArray(count, vertexArrayObject, indexBufferObject, indices, vertices, normals, textureCoordinates);
    }

Creating a VAO

private static int laodVertexArrayObject() {
        int vertexArrayObjectID = glGenVertexArrays();
        vaos.add(vertexArrayObjectID);                                                          //Adding the VAO to the list of all VAOs
        glBindVertexArray(vertexArrayObjectID);
        return vertexArrayObjectID;
    }

Creating a VBO

private static int createIndexBuffer(int[] indices) {
        int indexBufferObjectID = glGenBuffers();
        ibos.add(indexBufferObjectID);                                                          //Adding the IBO to the list of all IBOs
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObjectID);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, BufferUtils.createIntBuffer(indices), GL_STATIC_DRAW);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        return indexBufferObjectID;
    }

The storeDataInAttributeList function

private static void storeDataInAttributeList(int attributeNumber, float[] data, int coordinateSize) {
        int vertexBufferObjectID = glGenBuffers();
        vbos.add(vertexBufferObjectID);                                                         //Adding the VBO to the list of all VBOs
        glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjectID);
        glBufferData(GL_ARRAY_BUFFER, BufferUtils.createFloatBuffer(data), GL_STATIC_DRAW);
        glVertexAttribPointer(attributeNumber, coordinateSize, GL_FLOAT, false, 0, 0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
    }

private static void storeDataInAttributeList(int attributeNumber, int[] data, int coordinateSize) {
        int vertexBufferObjectID = glGenBuffers();
        vbos.add(vertexBufferObjectID);                                                         //Adding the VBO to the list of all VBOs
        glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjectID);
        glBufferData(GL_ARRAY_BUFFER, BufferUtils.createIntBuffer(data), GL_STATIC_DRAW);
        glVertexAttribPointer(attributeNumber, coordinateSize, GL_INT, false, 0, 0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
    }

Rendering a batch

public void render() {
        // Final arrays
        float[] vertices = null;
        float[] textureCoordinates = null;
        float[] normals = null;
        int[] indices = null;
        int[] textureIndices = null;
        // The temporary array list of data
        ArrayList<Float> rawVertices = new ArrayList<Float>();
        ArrayList<Float> rawTextureCoordinates = new ArrayList<Float>();
        ArrayList<Float> rawNormals = new ArrayList<Float>();
        ArrayList<Integer> rawIndices = new ArrayList<Integer>();
        ArrayList<Integer> rawTextureIndices = new ArrayList<Integer>();
        // Adding all the data of all the vaos into the temporary array lists
        for(int j = 0; j < rawVAOs.size(); j++) {
            for(int i = 0; i < rawVAOs.get(j).getVertices().length; i++) {
                rawVertices.add(rawVAOs.get(j).getVertices()[i]);
            }
            for(int i = 0; i < rawVAOs.get(j).getIndices().length; i++) {
                if(j == 0) {
                    rawIndices.add(rawVAOs.get(j).getIndices()[i]);
                } else {
                    rawIndices.add(j*rawVAOs.get(j-1).getIndices().length + rawVAOs.get(j).getIndices()[i]);
                }
            }
            for(int i = 0; i < rawVAOs.get(j).getNormals().length; i++) {
                rawNormals.add(rawVAOs.get(j).getNormals()[i]);
            }
            for(int i = 0; i < rawVAOs.get(j).getTextureCoordinates().length; i++) {
                rawTextureCoordinates.add(rawVAOs.get(j).getTextureCoordinates()[i]);
            }
            for(int i = 0; i < rawVAOs.get(j).getTextureIndices().length; i++) {
                rawTextureIndices.add(rawVAOs.get(j).getTextureIndices()[i]);
            }
        }
        // Adding all the data from the temporaray array lists into the final arrays
        vertices = new float[rawVertices.size()];
        for(int i = 0; i < rawVertices.size(); i++) {
            vertices[i] = rawVertices.get(i);
        }
        indices = new int[rawIndices.size()];
        for(int i = 0; i < rawIndices.size(); i++) {
            indices[i] = rawIndices.get(i);
        }
        normals = new float[rawNormals.size()];
        for(int i = 0; i < rawNormals.size(); i++) {
            normals[i] = rawNormals.get(i);
        }
        textureCoordinates = new float[rawTextureCoordinates.size()];
        for(int i = 0; i < rawTextureCoordinates.size(); i++) {
            textureCoordinates[i] = rawTextureCoordinates.get(i);
        }
        textureIndices = new int[rawTextureIndices.size()];
        for(int i = 0; i < rawTextureIndices.size(); i++) {
            textureIndices[i] = rawTextureIndices.get(i);
        }
        // Creating the final vao and rendering it
        this.finalVAO = Loader.createVAO(vertices, indices, textureCoordinates, normals, textureIndices);
        Main.ShaderList.get(shaderIndex).prepare();
        //load transformation matrices
        for(int i = 0; i < texturePointers.size(); i++) {
            glActiveTexture(GL_TEXTURE0+i);
            Main.TextureBufferPointerList.get(texturePointers.get(i)).bind();
        }
        this.finalVAO.render();
        Main.ShaderList.get(shaderIndex).finish();
    }

If I load up an integer array consisting of 0 for all the vertices of the first object and 1 for the all the vertices of the second object, i would expect the first object to be shaded in with the first texture and the second object to be shaded in with the second texture. It works if I add 0 for both objects, but once I add 1 for the any object, I get this giant error message:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffee7914d6e, pid=5992, tid=0x00000000000006bc
#
# JRE version: Java(TM) SE Runtime Environment (8.0_211-b12) (build 1.8.0_211-b12)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.211-b12 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C  [ig9icd64.dll+0x24d6e]
#
# 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 (0x000000001f03c800):  JavaThread "renderer" [_thread_in_native, id=1724, stack(0x0000000020990000,0x0000000020a90000)]

siginfo: ExceptionCode=0xc0000005, reading address 0x0000000000000220

Registers:
RAX=0x0000000024f20080, RBX=0x00000000013ae000, RCX=0x00000000013ae000, RDX=0x000000002d611b10
RSP=0x0000000020a8ebb0, RBP=0x000000002d611a50, RSI=0x0000000000000000, RDI=0x0000000024f20080
R8 =0x0000000001221bc0, R9 =0x0000000000008000, R10=0x00000000ffffffff, R11=0x0000000000000000
R12=0x0000000000000000, R13=0x000000001ca43bd0, R14=0x0000000025042310, R15=0x0000000000000000
RIP=0x00007ffee7914d6e, EFLAGS=0x0000000000010246

Top of Stack: (sp=0x0000000020a8ebb0)
0x0000000020a8ebb0:   0000000000000001 0000000001387e50
0x0000000020a8ebc0:   00000000228e5360 00007ffee7a6171f
0x0000000020a8ebd0:   fffffffffffffffe 000000001ca43bd0
0x0000000020a8ebe0:   000000000137ff20 00007ffee79145cf
0x0000000020a8ebf0:   0000000001394720 0000000000000000
0x0000000020a8ec00:   00000000013ae000 000000002d611a50
0x0000000020a8ec10:   000000000000000e 00007ffee7e35300
0x0000000020a8ec20:   0000000000000000 0000000025042310
0x0000000020a8ec30:   0000000024f20080 00007ffee790b731
0x0000000020a8ec40:   0000000001394720 00000000ffffffff
0x0000000020a8ec50:   0000000000000000 00000000ffffffff
0x0000000020a8ec60:   000000000137ff20 00007ffee7b0f4e2
0x0000000020a8ec70:   0000000000000000 00000000ffffffff
0x0000000020a8ec80:   0000000024f20080 000000000137ff20
0x0000000020a8ec90:   fffffffffffffffe 0000000025042310
0x0000000020a8eca0:   0000000000000000 0000000025042310 

Instructions: (pc=0x00007ffee7914d6e)
0x00007ffee7914d4e:   02 00 00 83 e6 01 0f 1f 40 00 0f 1f 84 00 00 00
0x00007ffee7914d5e:   00 00 4c 8b 9f 70 42 03 00 48 8d 95 c0 00 00 00
0x00007ffee7914d6e:   41 8b 8b 20 02 00 00 85 f6 0f 84 81 00 00 00 83
0x00007ffee7914d7e:   f9 10 73 06 48 6b c1 38 eb 5b 44 8d 41 f0 41 8b 


Register to memory mapping:

RAX=0x0000000024f20080 is an unknown value
RBX=0x00000000013ae000 is an unknown value
RCX=0x00000000013ae000 is an unknown value
RDX=0x000000002d611b10 is an unknown value
RSP=0x0000000020a8ebb0 is pointing into the stack for thread: 0x000000001f03c800
RBP=0x000000002d611a50 is an unknown value
RSI=0x0000000000000000 is an unknown value
RDI=0x0000000024f20080 is an unknown value
R8 =0x0000000001221bc0 is an unknown value
R9 =0x0000000000008000 is an unknown value
R10=0x00000000ffffffff is an unknown value
R11=0x0000000000000000 is an unknown value
R12=0x0000000000000000 is an unknown value
R13={method} {0x000000001ca43bd8} 'invokeV' '(J)V' in 'org/lwjgl/system/JNI'
R14=0x0000000025042310 is an unknown value
R15=0x0000000000000000 is an unknown value


Stack: [0x0000000020990000,0x0000000020a90000],  sp=0x0000000020a8ebb0,  free space=1018k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [ig9icd64.dll+0x24d6e]
C  [ig9icd64.dll+0x245cf]
C
java
opengl
attributes
glsl
lwjgl
asked on Stack Overflow May 27, 2019 by A. Hof

1 Answer

1

Integral attributes have to be specified by glVertexAttribIPointer - focus on I:

glVertexAttribIPointer(attributeNumber, coordinateSize, GL_INT, 0, 0);

See OpenGL 4.6 API Core Profile Specification; 10.2.1 Current Generic Attributes , page 349:

When values for a vertex shader attribute variable are sourced from an enabled generic vertex attribute array, the array must be specified by a command compatible with the data type of the variable. The values loaded into a shader attribute variable bound to generic attribute index are undefined if the array for index was not specified by:

  • VertexAttribFormat, for floating-point base type attributes;
  • VertexAttribIFormat with type BYTE, SHORT, or INT for signed integer base type attributes; or
  • VertexAttribIFormat with type UNSIGNED_BYTE, UNSIGNED_SHORT, or UNSIGNED_INT for unsigned integer base type attributes.

Further note that the Index buffer is stated in the Vertex Array Object. If no Vertex Array Object is bound, then no index buffer can be bound. (In a compatibility profile context there is the default vertex array object 0).

So the vertex array object has to be created and bound before the index buffer.

int vertexArrayObject = laodVertexArrayObject();
int count = indices.length;
int indexBufferObject = createIndexBuffer(indices);

Of course the association to the VAO must not be broken by glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);:

private static int createIndexBuffer(int[] indices) {
    int indexBufferObjectID = glGenBuffers();
    ibos.add(indexBufferObjectID);                                                          
    //Adding the IBO to the list of all IBOs
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObjectID);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, BufferUtils.createIntBuffer(indices), GL_STATIC_DRAW);

    // glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); <----- delete

    return indexBufferObjectID;
}
answered on Stack Overflow May 27, 2019 by Rabbid76 • edited May 27, 2019 by Rabbid76

User contributions licensed under CC BY-SA 3.0