Повторить UV для нескольких кубов в одном объекте буфера вершин (VBO)?

Я делаю небольшой воксельный движок, используя систему чанков (как в Minecraft). Я решил сделать 1 VBO на чанк, чтобы VBO содержал несколько кубов, которые будут использовать разные текстуры.

На самом деле у меня есть UV куба, и я хотел бы использовать его на всех кубах в VBO, чтобы текстура оборачивала все кубы одинаково, если бы кубы были в отдельных VBO.

Вот что я на самом деле получаю:

фактический результат

Как заставить OpenGL делать то же самое, что и первый куб, на всех кубах?

РЕДАКТИРОВАТЬ: вот мои шейдеры: вершинный шейдер #версия 400

layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec2 vertexUV;

out vec2 UV;

uniform mat4 MVP;

void main() {
    gl_Position = MVP * vec4(vertexPosition_modelspace, 1);
    UV = vertexUV;
}

фрагментный шейдер

#version 400

in vec2 UV;

out vec3 color;

uniform sampler2D textureSampler;

void main(){
  color = texture(textureSampler, UV).rgb;
}

мой цикл glfw:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(programID);
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &chunkHandler.player.mvp[0][0]);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, grass);
glUniform1i(textureID, 0);

glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, chunkHandler.loaded_chunks[0]->vboID);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, tboID);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);

glDrawArrays(GL_TRIANGLES, 0, chunkHandler.loaded_chunks[0]->nbVertices);

glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);

glfwSwapBuffers(window);
glfwPollEvents();

tboID: tbo для объекта буфера текстуры

как я создаю TBO:

glGenBuffers(1, &tboID);
    glBindBuffer(GL_ARRAY_BUFFER, tboID);
    glBufferData(GL_ARRAY_BUFFER, 36 * 2 * sizeof(float), uvcube, GL_STATIC_DRAW);

person Shirakawa42    schedule 08.02.2019    source источник
comment
Это не совсем ясно. Вы хотите иметь 1 уникальную текстуру для вашего VBO (применяемую ко всем кубам в VBO) или 1 текстуру для каждого куба в VBO?   -  person xryl669    schedule 08.02.2019
comment
1 уникальная текстура для VBO, применяемая ко всем кубам в VBO. (Несколько текстур - еще одна проблема, мне не нужна помощь)   -  person Shirakawa42    schedule 08.02.2019
comment
Не является частью вопроса, но я бы подумал об экземпляре, если вы отображаете много кубов.   -  person Guillaume Racicot    schedule 08.02.2019
comment
Кроме того, будет ли работать glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);?   -  person Guillaume Racicot    schedule 08.02.2019
comment
Тогда я не понимаю вашей проблемы. Когда вы сохраняете свою вершину в VBO, вы сохраняете UV-координату текстуры для каждой вершины, верно? Вы также правильно установили текстурный блок (из вашего скриншота), так что это просто вопрос вызова вызова texture2D в вашем шейдере.   -  person xryl669    schedule 08.02.2019
comment
Думаете, проблема только в шейдерах? я отредактирую свой вопрос с моими текущими шейдерами и моим циклом   -  person Shirakawa42    schedule 08.02.2019
comment
@GuillaumeRacicot нет, это не работает, я уже пробовал   -  person Shirakawa42    schedule 08.02.2019
comment
Я не понимаю. Насколько я понимаю, на изображении 4 кубика. Есть 1 шейдерная программа и 1 текстура, не так ли? Поэтому, если текстура травы привязана, она должна быть наложена на каждый куб. А как насчет tboID? Является ли буфер массива tboID (для координат текстуры) действительным для всех 4 кубов?   -  person Rabbid76    schedule 08.02.2019
comment
@Rabbid76 да, на этом изображении 4 куба, все кубы в 1 VBO, есть 1 шейдер и 1 текстура, но текстура оборачивает только 1 куб (со всех его сторон, а также замаскированные стороны), но я не знаю, как чтобы он обернул все кубики 1 на 1, оставаясь с 1 VBO   -  person Shirakawa42    schedule 08.02.2019
comment
@ Shirakawa42 Вам не нужно делать ничего особенного, сделайте то же самое для всех 4 кубов. Я предполагаю, что tboID подходит только для 1-го куба. Вы его где-то удаляете? Не задана ли переменная tboID для 2-го, 3-го и 4-го куба?   -  person Rabbid76    schedule 08.02.2019
comment
@Rabbid76 это то, что я ищу, я создаю tbo непосредственно перед входом в цикл и никогда не удаляю его, но я не знаю, почему он не повторяет tbo на всех кубах.   -  person Shirakawa42    schedule 08.02.2019
comment
@Rabbid76 Rabbid76 я добавил, как создать TBO, но я не знаю, что добавить в код :/   -  person Shirakawa42    schedule 08.02.2019
comment
@ Shirakawa42 Попробуйте следующее; добавить glBindBuffer(GL_ARRAY_BUFFER, 0); справа после glBindBuffer(GL_ARRAY_BUFFER, tboID); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);   -  person Rabbid76    schedule 08.02.2019
comment
@Rabbid76 не работает :/   -  person Shirakawa42    schedule 08.02.2019
comment
@ Shirakawa42 У меня нет идей. Но прочитайте объект OpenGL в классе C++ RAII больше не работает   -  person Rabbid76    schedule 08.02.2019


Ответы (1)


Хотя это не полный ответ, я могу помочь в отладке. Мне кажется координаты текстуры неправильные (вы не даете код их заполнения).

В вашем фрагментном шейдере я бы вывел координаты U и V в виде цветов:

#version 400

in vec2 UV;

out vec3 color;

uniform sampler2D textureSampler;

void main(){
  color = vec3(UV.u, UV.v, 0);
}

Если координаты правильные, у вас должен быть градиент на каждой грани куба (каждая вершина куба будет окрашена в зависимости от ее UV, поэтому вершина (0,0) будет черной, а (0,1) — зеленой и т. д.). Если это не так, попробуйте исправить значение текстуры, пока вы не сможете видеть их правильно.

Мне это кажется подозрительным: glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);

person xryl669    schedule 08.02.2019
comment
Координаты текстуры хорошие, на самом деле все стороны текстурированного куба текстурированы, в том числе и замаскированные стороны. И когда я показываю только один куб, он выглядит великолепно - person Shirakawa42; 08.02.2019
comment
Вы получили кубики градиента? Потому что, если координаты вашей текстуры равны 0 (или 1) (кроме нижнего левого куба), вы получите одинаковый цвет для всех остальных кубов. Предоставьте дамп массива uvcube. Размер массива странный, у вас должно быть 18 вершин для 4 смежных кубов (если общие вершины) или 32, если независимые, а не 36. Убедитесь, что он соответствует количеству вершин в VBO. - person xryl669; 09.02.2019
comment
Кроме того, было бы лучше связать положение и координату текстуры в одном объекте (сохранить x,y,z,u,v для каждой вершины и использовать 5-й параметр, чтобы указать шаг для пары u, v). Таким образом, вы не можете смешивать количество вершин, у вас есть один буфер для загрузки, и вам не нужно много причудливой последовательности включения и отключения. - person xryl669; 09.02.2019