Как работают цветовые атрибуты в VBO? - PullRequest
5 голосов
/ 05 мая 2010

Я пишу код для OpenGL ES 2.0 (Webgl). Я использую VBO для рисования примитивов. У меня есть массив вершин, массив цветов и массив индексов. Я просмотрел примеры кодов, книги и учебные пособия, но одну вещь я не понимаю - если цвет определяется для каждой вершины, как это влияет на полигональные поверхности, смежные с этими вершинами? (Я новичок в OpenGL (ES))

Я объясню на примере. У меня есть куб для рисования. Из того, что я прочитал в книге OpenGLES, цвет определен как атрибут вершины. В этом случае, если я хочу нарисовать 6 граней куба с 6 различными цветами, как я должен определить цвета. Источник моей путаницы: каждая вершина является общей для 3 граней, тогда как это поможет определить цвет для каждой вершины? (Или цвет должен быть определен по индексу?). Тот факт, что нам нужно разделить эти лица на треугольники, затрудняет мне понимание того, как работают эти отношения. Та же самая путаница идет с краями. Вместо того, чтобы рисовать треугольники, скажем, я хочу рисовать края, используя примитивы LINES. Каждый край разного цвета. Как мне определить цветовые атрибуты в этом случае?

Я видел несколько рабочих примеров. Конкретно этот урок: http://learningwebgl.com/blog/?p=370

Я вижу, как в приведенном выше примере определяется цветовой массив для рисования куба с 6 разноцветными гранями, но я не понимаю, почему определяется таким образом. (Почему каждый цвет копируется 4 раза в распакованный цвет, например?)

Может кто-нибудь объяснить, как атрибуты цвета работают в VBO?

[Ссылка выше кажется недоступной, поэтому я выложу соответствующий код здесь]

cubeVertexPositionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);
vertices = [
  // Front face
  -1.0, -1.0,  1.0,
   1.0, -1.0,  1.0,
   1.0,  1.0,  1.0,
  -1.0,  1.0,  1.0,

  // Back face
  -1.0, -1.0, -1.0,
  -1.0,  1.0, -1.0,
   1.0,  1.0, -1.0,
   1.0, -1.0, -1.0,

  // Top face
  -1.0,  1.0, -1.0,
  -1.0,  1.0,  1.0,
   1.0,  1.0,  1.0,
   1.0,  1.0, -1.0,

  // Bottom face
  -1.0, -1.0, -1.0,
   1.0, -1.0, -1.0,
   1.0, -1.0,  1.0,
  -1.0, -1.0,  1.0,

  // Right face
   1.0, -1.0, -1.0,
   1.0,  1.0, -1.0,
   1.0,  1.0,  1.0,
   1.0, -1.0,  1.0,

  // Left face
  -1.0, -1.0, -1.0,
  -1.0, -1.0,  1.0,
  -1.0,  1.0,  1.0,
  -1.0,  1.0, -1.0,
];
gl.bufferData(gl.ARRAY_BUFFER, new WebGLFloatArray(vertices), gl.STATIC_DRAW);
cubeVertexPositionBuffer.itemSize = 3;
cubeVertexPositionBuffer.numItems = 24;

cubeVertexColorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer);
var colors = [
  [1.0, 0.0, 0.0, 1.0],     // Front face
  [1.0, 1.0, 0.0, 1.0],     // Back face
  [0.0, 1.0, 0.0, 1.0],     // Top face
  [1.0, 0.5, 0.5, 1.0],     // Bottom face
  [1.0, 0.0, 1.0, 1.0],     // Right face
  [0.0, 0.0, 1.0, 1.0],     // Left face
];
var unpackedColors = []
for (var i in colors) {
  var color = colors[i];
  for (var j=0; j < 4; j++) {
    unpackedColors = unpackedColors.concat(color);
  }
}
gl.bufferData(gl.ARRAY_BUFFER, new WebGLFloatArray(unpackedColors), gl.STATIC_DRAW);
cubeVertexColorBuffer.itemSize = 4;
cubeVertexColorBuffer.numItems = 24;

cubeVertexIndexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer);
var cubeVertexIndices = [
  0, 1, 2,      0, 2, 3,    // Front face
  4, 5, 6,      4, 6, 7,    // Back face
  8, 9, 10,     8, 10, 11,  // Top face
  12, 13, 14,   12, 14, 15, // Bottom face
  16, 17, 18,   16, 18, 19, // Right face
  20, 21, 22,   20, 22, 23  // Left face
]
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new WebGLUnsignedShortArray(cubeVertexIndices), gl.STATIC_DRAW);
cubeVertexIndexBuffer.itemSize = 1;
cubeVertexIndexBuffer.numItems = 36;

Ответы [ 2 ]

9 голосов
/ 06 мая 2010

Мне нравится смотреть на это так, что каждая вершина - это не точка в пространстве, а скорее набор атрибутов. Они обычно (но не всегда) включают его местоположение, и может включать его цвет, координаты текстуры и т. Д. И т. Д. И т. Д. Треугольник (или линия, или другой примитив) определяется путем указания набора вершин, затем генерируя значения для каждого атрибута в каждом пикселе путем линейной интерполяции значений для каждой вершины.

Как говорит Лиам, и как вы поняли в своем комментарии, это означает, что если вы хотите иметь точку в пространстве, которая используется вершиной для нескольких примитивов - например, угол куба - поскольку другие атрибуты не-местоположения меняются в зависимости от примитива, вам нужна отдельная вершина для каждой комбинации атрибутов.

Это в некоторой степени бесполезно расходует память, но сложность, связанная с выполнением этого каким-либо иным способом, усугубит ситуацию и потребует от графического оборудования гораздо большей работы по распаковке и перепаковке данных. Мне кажется, что отходы сопоставимы с отходами, которые мы получаем, используя 32-битные значения RGBA для каждого пикселя в нашей видеопамяти вместо хранения таблицы соответствия палитры каждого цвета, который мы хотим использовать, а затем просто сохраняя индекс на этот пиксель (что, конечно, мы привыкли делать, когда оперативная память была дороже).

3 голосов
/ 06 мая 2010

Если цвет набора многоугольников один и тот же, то вершина, общая для всех многоугольников, вместе с ее цветом может быть определена один раз и совместно использоваться многоугольниками (используя индекс).

Если цвет полигонов различен, то, хотя положение вершины может быть общим, цвет - нет, и поэтому вершина в целом не может быть общей.Вам нужно будет определить вершину для каждого многоугольника.

...