#c #opengl #glsl #shader
#c #opengl #glsl #шейдер
Вопрос:
Я загрузил информацию о материале и текстуре из Obj-файла на основе этого кода (https://github.com/Bly7/OBJ-Loader ). Теперь я хочу загрузить Sponza и отобразить его. Однако существует 10 или более текстур, и даже если все они передаются шейдеру, необходимо, чтобы они соответствовали соответствующим вершинам. Глядя на результат загрузки из Obj-файла, текстуры назначаются каждой части.
Пример.
Mesh 0 : Pillar
position0(x, y, z), position1(x, y, z), uv0(x, y) ...
diffuse texture : tex0.png
Mesh 1 : Wall
position0(x, y, z), position1(x, y, z), uv0(x, y) ...
diffuse texture : tex1.png
.
.
.
Текстуры хранятся в виде массива, и каждая из них имеет соответствующий индекс сетки. На мой взгляд, при передаче информации о вершинах шейдеру хорошо работает, если вы делите ее на количество сеток и одновременно передаете текстуру. Однако я не уверен, верна ли эта идея, и я пробовал несколько методов, но это не работает.
Это текущий простой код.
main.cpp :
do {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture[i]); // texture[] : Array of textures loaded from obj file.
glUniform1i(glGetUniformLocation(shaderID, "myTex"), 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertex_position);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, texCoord);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, element);
glDrawElements(GL_TRIANGLES, element_indices.size(), GL_UNSIGNED_INT, (void*)0);
} while(glfwWindowShouldClose(window) == 0);
Fragment shader :
layout(location = 0) out vec4 out_color;
// from vertex shader
in vec2 texCoord;
uniform sampler2D myTex;
void main() {
out_color = texture(myTex, texCoord);
}
Я хочу соответствовать индексу сетки, загруженному с помощью «i» в приведенном выше коде. Пожалуйста, дайте мне знать, если моя идея неверна или есть другой способ.
Комментарии:
1. Вы должны визуализировать
Mesh 0
сtex0.png
помощью,Mesh 1
сtex1.png
помощью и т.д. Для этого вы загружаете все текстуры и привязываете соответствующий идентификатор текстуры для соответствующей сетки, прежде чем рисовать ее буферы. Существует также возможность привязать несколько текстур к одной сетке, но ИМХО это не то, что вы собираетесь делать. Посмотрите на Learn OpenGL — Текстуры , как это делается в деталях.2. Я бы порекомендовал вам взглянуть на Model — LearnOpenGL . На это должен быть ваш ответ.
3. @Scheff, снова посмотрев на ваши ссылки, дал мне несколько советов о том, как действовать дальше. Спасибо.
Ответ №1:
Поскольку ваша модель имеет только одну текстуру на сетку, я могу предложить этот простой код для использования:
do {
glActiveTexture(GL_TEXTURE0);
glUniform1i(glGetUniformLocation(shaderID, "myTex"), 0);
for (unsigned int i = 0; i < mesh_count; i ) {
glcall(glBindTexture(type, texture[i]));
// Bind vertex and index (or element) buffer and setup vertex attribute pointers
// Draw mesh
}
} while (window_open);
Код очень понятен. Сначала он активирует слот текстуры 0, затем для каждой сетки он связывает текстуру, буфер вершин, индекс или буфер элементов и выполняет какую-либо подготовку для рисования сетки. Затем он выдает вызов рисования.
Обратите внимание, что это очень простой пример. Большинство моделей выглядели бы странно с этим кодом. Я бы рекомендовал этот учебник из LearnOpenGL, который объясняет это более широко, но простым способом.
Комментарии:
1. Я решил эту проблему, передав массив, содержащий индекс каждой сетки, в glDrawElements. Спасибо, что подумали вместе.