OpenGL (ES) — хранение и использование массива цветов в VBO и применение его к треугольнику VBO

#android #graphics #opengl-es

#Android #графика #opengl-es

Вопрос:

Как это можно сделать? Этот код не работает:

 
//////////INIT COLOR VBO FOR USE WITH A TRIANGLE    
triColorBuffer = ByteBuffer.allocateDirect(3 * 4
    * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();        

float[] colors = { 
1f, 0f, 0f, 1f,
0f, 1f, 0f, 1f, 
0f, 0f, 1f, 1f,};

triColorBuffer.put(colors);
triColorBuffer.flip();
int[] buffer = new int[1];
gl11.glGenBuffers(1, buffer, 0);
colorPointerTri = buffer[0];
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, colorPointerTri);
gl11.glBufferData(GL11.GL_ARRAY_BUFFER, triColorBuffer.capacity() 
    * 4, triColorBuffer, GL11.GL_STATIC_DRAW);

////////////DRAW USING COLOR VBO
gl11.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl11.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl11.glPushMatrix();

gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, vertexPointerTri);
gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, indexPointerTri);
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, colorPointerTri);
gl11.glColorPointer(4, GL10.GL_FLOAT, 0, 0);
gl11.glVertexPointer(3, GL10.GL_FLOAT, 0, 0);
gl11.glDrawElements(GL10.GL_TRIANGLES, 3, GL10.GL_UNSIGNED_SHORT, 0);
gl11.glDisableClientState(GL10.GL_COLOR_ARRAY);
gl11.glDisableClientState(GL10.GL_VERTEX_ARRAY);

gl11.glPopMatrix();
gl11.glDisableClientState(GL10.GL_COLOR_ARRAY);
gl11.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0);
gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, 0);

  

Треугольник рисует VBO’d или nor, а цветовой градиент (glcolorpointer) работает без VBO’d, но я не могу раскрасить треугольник VBO’d с помощью цветового указателя (VBO или без него). Помощь приветствуется.

Комментарии:

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

2. Подойдет…. Я не хотел публиковать слишком много кода.

Ответ №1:

Вы привязываете буфер вершин, и сразу после этого вы привязываете буфер цветов. Когда вы теперь вызываете glColor / VertexPointer, оба цвета и вершины берутся из цветового буфера. Вам нужно написать:

 gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, vertexPointerTri);
gl11.glVertexPointer(3, GL10.GL_FLOAT, 0, 0);
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, colorPointerTri);
gl11.glColorPointer(4, GL10.GL_FLOAT, 0, 0);
  

В качестве gl…Команда Pointer использует буфер, который в данный момент привязан.

Ответ №2:

Пожалуйста, поправьте меня, если я ошибаюсь, я начал с VBO всего 15 минут назад.

В любом случае, похоже, что вам придется использовать VBO «в двух». Сначала вы связываете свои данные / массив, и сразу после этого сообщаете контексту GL, что вы только что ему дали. Мне потребовалось немало времени, чтобы прочитать этот исходный файл, чтобы понять, что происходит, и искренне надеяться, что я не совсем неправильно его понял. Выдержка из этого файла;

 if (useTexture) {
    gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, mTextureCoordBufferIndex);
    gl11.glTexCoordPointer(2, mCoordinateType, 0, 0);
}            
if (useColor) {
    gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, mColorBufferIndex);
    gl11.glColorPointer(4, mCoordinateType, 0, 0);
}
  

В вашем коде вы выполняете привязку 3 раза и сразу после начала переключаете то, что было привязано. Я не знаю, что именно там происходит, но я бы попробовал, например

 gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, vertexPointerTri);
gl11.glVertexPointer(3, GL10.GL_FLOAT, 0, 0);
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, colorPointerTri);
gl11.glColorPointer(4, GL10.GL_FLOAT, 0, 0);
gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, indexPointerTri);
gl11.glDrawElements(GL10.GL_TRIANGLES, 3, GL10.GL_UNSIGNED_SHORT, 0);
  

Также из того, что я видел, не должно нанести никакого вреда, если вы отвяжете свои массивы после рендеринга. Возможно, это в вашем коде, который не скопирован / вставлен сюда, но на всякий случай.

 gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0);
gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, 0);
  

Комментарии:

1. Я думаю, я знаю, о чем вы говорите. Но в конечном итоге мы доберемся до этого 🙂

2. Вам не нужно привязывать буфер массива элементов непосредственно перед вызовом draw, поскольку это другая точка привязки, чем буфер массива. С вашим кодом проблем нет, просто для наглядности.