Почему эти данные атрибута не загружаются в вершинный шейдер правильно? - PullRequest
1 голос
/ 27 мая 2019

Я хочу добавить массив целых чисел к моему объекту массива вершин, чтобы определить, какое изображение следует использовать для этой конкретной вершины, но каким-то образом данные повреждены в пути или не загружаются правильно.

Я уже пытался загрузить предустановленный массив и просто выбрать правильный индекс, используя gl_VertexID, который сработал, но я бы предпочел иметь все данные в массиве вершин и не загружать однородный целочисленный массив в каждом кадре.

Вершинный шейдер

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

Фрагмент шейдера

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

Создание массива вершин`

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

Создание VAO

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

Создание 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;
    }

Функция storeDataInAttributeList

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

Рендеринг партии

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

Если я загружу целочисленный массив, состоящий из 0 для всех вершин первого объекта и 1 для всех вершин второго объекта, я бы ожидал, что первый объект будет затенен первой текстурой и вторым объект должен быть закрашен второй текстурой. Это работает, если я добавлю 0 для обоих объектов, но как только я добавлю 1 для любого объекта, я получаю это гигантское сообщение об ошибке:

#
# 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

1 Ответ

1 голос
/ 27 мая 2019

Интегральные атрибуты должны быть указаны как glVertexAttribIPointer - фокус на I:

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

См. Спецификация профиля ядра API OpenGL 4.6;10.2.1 Текущие общие атрибуты , стр. 349:

Когда значения для переменной атрибута вершинного шейдера получены из включенного универсального массива атрибутов вершины, массив должен быть указан командой, совместимой стип данных переменной.Значения, загруженные в переменную атрибута шейдера, привязанную к индексу общего атрибута, не определены, если массив для индекса не был указан с помощью:

  • VertexAttribFormat, для атрибутов базового типа с плавающей точкой;
  • VertexAttribIFormat с типом BYTE, SHORT или INT для атрибутов целочисленного базового типа со знаком; или
  • VertexAttribIFormat с типом UNSIGNED_BYTE, UNSIGNED_SHORT или UNSIGNED_INT для атрибутов базового типа без знака.

Также обратите внимание, что индексный буфер указан в Vertex Array Object.Если объект Vertex Array не привязан, то индексный буфер не может быть привязан.(В контексте профиля совместимости существует объект массива вершин по умолчанию 0).

Таким образом, объект массива вершин должен быть создан и связан с индексным буфером.

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

Конечно, связь с VAO не должна быть нарушена 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;
}
...