Неверный VBO для сетки: некоторые треугольники связаны и не должны [2D]
Я генерирую свой VBO с этим кодом
int SCREEN_WIDTH = 800;
int SCREEN_HEIGHT = 480;
int PIXEL_PER_VERTEX = 4;
int CAVERN_TEXTURE_WIDTH = 1024;
int CAVERN_TEXTURE_HEIGHT = 512;
final int vertexCount = ((SCREEN_WIDTH / PIXEL_PER_VERTEX) +1 ) * 2;
final float[] bufferDataLowerCave = new float[vertexCount * CavernBoundMesh.VERTEX_SIZE];
for(int i=0; i < vertexCount; i += 2) {
bufferDataLowerCave[i * CavernBoundMesh.VERTEX_SIZE + CavernBoundMesh.VERTEX_INDEX_X] = PIXEL_PER_VERTEX * i / 2.f;
bufferDataLowerCave[i * CavernBoundMesh.VERTEX_SIZE + CavernBoundMesh.VERTEX_INDEX_Y] = 200;
bufferDataLowerCave[i * CavernBoundMesh.VERTEX_SIZE + CavernBoundMesh.TEXTURECOORDINATES_INDEX_U] = ( (float) PIXEL_PER_VERTEX * i / 2.f) / SCREEN_WIDTH;
bufferDataLowerCave[i * CavernBoundMesh.VERTEX_SIZE + CavernBoundMesh.TEXTURECOORDINATES_INDEX_V] = 0.f;
bufferDataLowerCave[(i + 1 ) * CavernBoundMesh.VERTEX_SIZE + CavernBoundMesh.VERTEX_INDEX_X] = PIXEL_PER_VERTEX * i / 2;
bufferDataLowerCave[(i + 1 ) * CavernBoundMesh.VERTEX_SIZE + CavernBoundMesh.VERTEX_INDEX_Y] = 0;
bufferDataLowerCave[(i + 1 ) * CavernBoundMesh.VERTEX_SIZE + CavernBoundMesh.TEXTURECOORDINATES_INDEX_U] = ( (float) PIXEL_PER_VERTEX * i / 2.f) / SCREEN_WIDTH;
bufferDataLowerCave[(i + 1 ) * CavernBoundMesh.VERTEX_SIZE + CavernBoundMesh.TEXTURECOORDINATES_INDEX_V] = 0.5f;
}
Я рисую сетку (по центру в начале координат) с помощью TRIANGLE_STRIP.
Извините, нет кода openGL, так как я использую движок (AndEngine). Но если вам действительно нужно, я могу попытаться отследить это..
Как вы можете видеть на изображении, последние 2 вершины связаны с вершиной в начале координат. Я отладил создание VBO, и это первая и последняя вершины.
//X Y U V
[0.0, 200.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.5,
4.0, 200.0, 0.0050, 0.0,
4.0, 0.0, 0.0050, 0.5,
8.0, 200.0, 0.01, 0.0,
8.0, 0.0, 0.01, 0.5,
12.0, 200.0, 0.015, 0.0,
12.0, 0.0, 0.015, 0.5,
16.0, 200.0, 0.02, 0.0,
16.0, 0.0, 0.02, 0.5
[..]
780.0, 200.0, 0.975, 0.0,
780.0, 0.0, 0.975, 0.5,
784.0, 200.0, 0.98, 0.0,
784.0, 0.0, 0.98, 0.5,
788.0, 200.0, 0.985, 0.0,
788.0, 0.0, 0.985, 0.5,
792.0, 200.0, 0.99, 0.0,
792.0, 0.0, 0.99, 0.5,
796.0, 200.0, 0.995, 0.0,
796.0, 0.0, 0.995, 0.5]
Это вершинный шейдер, который я использовал
uniform mat4 u_modelViewProjectionMatrix;
uniform float u_elapsedSeconds;
attribute vec4 a_position;
attribute vec2 a_textureCoordinates;
varying vec2 v_textureCoordinates;
void main(void)
{
v_textureCoordinates = a_textureCoordinates;
vec4 temp_position = u_modelViewProjectionMatrix * a_position;
float variation = 0.3*sin((u_elapsedSeconds + 1.5 * temp_position.x))*(1.0 + temp_position.y);
temp_position.y += variation;
gl_Position = temp_position;
}
Я очень новичок в этом, так что я не очень хорошо знаю спецификации и как это работает, но я не могу понять, что происходит, чтобы создать этот странный эффект. Можете ли вы помочь мне?
EDIT1:
Я сделал еще несколько тестов. Даже со стандартным вершинным и фрагментным шейдерами, который просто устанавливает положение и цвет, выбирая его из текстур, он дает странные результаты.
РЕДАКТИРОВАТЬ 2: Еще несколько изображений, на этот раз только с помощью 2-х стандартных верт и шейдерных фрагментов для определения положения и цвета текстуры (эти изображения взяты с планшета, а первое с телефона)
2 ответа
Я почти уверен, что вы указываете неправильное количество примитивов для своего кода рисования, так как сами вершины выглядят хорошо для меня. Когда вы выполняете вызов рисования для openGL или любого другого трехмерного примитивного чертежа, вы указываете не количество вершин для рисования, а количество примитивов. Примитив в вашем случае - это треугольник.
Так как вы рисуете треугольную полосу, это всегда numberOfVertices - 2
Примитивы в вашем звонке. Если бы это был список треугольников, это было бы numberOfVertices/3
и для поклонника треугольника это numberOfVertices - 2
снова.
Поскольку вы, вероятно, указываете больше треугольников, которые должны быть нарисованы, чем у него есть данные для рисования, вероятно, он использует некоторые значения по умолчанию (0,0,0,0)
который объясняет, что он пытается нарисовать два вырожденных треугольника в нижнем левом углу, который также ссылается на координату текстуры 0,0
, Это также имеет смысл, так как нет даже вершины, которая имеет позицию 0,0
и T/U 0,0
в вашем списке, поэтому последняя вершина должна иметь значение по умолчанию.
Хорошо, я решил это.
Попробовав libgdx (мне это не очень нравится, кажется, что многие служебные функции отсутствуют, и я не совсем понял концепцию, лежащую в основе, например, как он обрабатывает текстуры, как управляет объектами и т. Д.) И реализовал действительно маленький рендерер на родном языке с jni, а также настроил cocos-2d-x (но я не пробовал, так как я сначала немного поиграл с кодом jni и написал вышеупомянутый рендерер), я вернулся к AndEngine.
Мне удалось реализовать меш с VBO, а также с IBO, но, наконец, я решил свою проблему, дублируя (добавляя 2 одинаковые вершины) в начале и конце VBO, так что дополнительные треугольники вырождаются и не рисуются. Итак, это самый обходной путь, но пока он работает..