Я хочу добавить массив целых чисел в свой объект массива вершин, чтобы определить, какое изображение следует использовать для этой конкретной вершины, но каким-то образом данные повреждаются по пути или загружаются неправильно.
Я уже пытался загрузить предустановленный массив и просто выбрать правильный индекс с помощью 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);
}
Создание ВАО
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
Я не совсем уверен, что вы имеете в виду, но если вы имеете в виду, если у меня есть контекст OpenGL, то да, я вызываю функцию GL.createCapabilities();
и glfwMakeContextCurrent(windowPointer);
на этапе инициализации.
В десктопном OpenGL есть профиль совместимости и профиль Контекст. Профиль совместимости предоставляет устаревшую функциональность.
Интегральные атрибуты должны быть указаны glVertexAttribIPointer
— сосредоточьтесь на I
:
glVertexAttribIPointer(attributeNumber, coordinateSize, GL_INT, 0, 0);
См. Спецификация основного профиля API OpenGL 4.6; 10.2.1 Текущие общие атрибуты , стр. 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 typeBYTE
,SHORT
, orINT
for signed integer base type attributes; orVertexAttribIFormat
with typeUNSIGNED_BYTE
,UNSIGNED_SHORT
, orUNSIGNED_INT
for unsigned integer base type attributes.
Далее обратите внимание, что Индексный буфер указывается в Объект вершинного массива. Если ни один объект 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;
}
Используете ли вы контекст основного профиля?