2013-11-28 6 views
0

Итак, я успешно нарисовал ряд строк, используя два VBOs для вершин и один для индексов. Списки Python являются:Pyopengl - несколько строк, сделанных из VBO, однако индексированный цвет VBO не работает

vertices = [ 
      [0,1],[0,2],[0,3], # Axes 1 
      [1,4],[1,5],[1,6], # Axes 2 
      [2,10],[2,11],[2,12] # Axes 3 
      ] 

indexes = [ 
      0,4,4,7, # Line 1 
      1,4,4,8, # Line 2 
      3,6,6,9 # Line 3 
      ] 

Я затем преобразовать их в Numpy массив и Асо в РВО:

vertexarray = np.array(vertices, dtype=np.float32) 
indexarray = np.array(indexes, dtype=np.int32) 

vertexvbo = glvbo.VBO(vertexarray) 
indexvbo = glvbo.VBO(indexarray, target=GL_ELEMENT_ARRAY_BUFFER) 

А потом я связываю и сделать эти строки с помощью:

glLineWidth(1) 
glColor4f(1,1,1,1) 

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 
glEnable(GL_BLEND) 

glEnableClientState(GL_VERTEX_ARRAY) 
vertexvbo.bind() 
indexvbo.bind() 
glVertexPointer(2, GL_FLOAT, 0, None) 

glDrawElements(GL_LINES, len(indexarray), GL_UNSIGNED_INT, None) 

glDisableClientState(GL_VERTEX_ARRAY) 
glDisable(GL_BLEND) 

As на этом рисунке показано (жирные белые линии - это просто оси, которые рисуются с использованием стандартных команд OpenGL):

Uncolored Lines

Теперь проблема возникает, когда я пытаюсь их покрасить. В каждой из 3-х линий состоит из 2 меньших линий, создать цветовой массив размером 3:

colors = [] 

for i in range(0,3): 
     r = random.uniform(0.1,1) 
     g = random.uniform(0.1,1) 
     b = random.uniform(0.1,1) 
     color = [r,g,b,0.7] 
     colors.append(color) 

, а затем цветовой индекс массива со следующими значениями:

colorindexes = [ 
       0,0,0,0, # Line 1 
       1,1,1,1, # Line 2 
       2,2,2,2 # Line 3 
       ] 

Я тогда преобразующие их в Numpy массивов и создавать о:

colorarray = np.array(colors, dtype=np.float32) 
colorindexarray = np.array(colorindexes, dtype=np.int32) 

colorvbo = glvbo.VBO(colorarray) 
colorindexvbo = glvbo.VBO(colorindexarray, target=GL_ELEMENT_ARRAY_BUFFER) 

для того, чтобы затем связать и использовать эту VBO добавить следующий код перед строкой glEnableClientState (GL_VERTEX_ARRAY) из предыдущего кода:

glEnableClientState(GL_COLOR_ARRAY) 
colorvbo.bind() 
colorindexvbo.bind() 
glColorPointer(4, GL_FLOAT, 0, None) 

Однако линии не окрашивать должным образом, как показано в следующем рисунке, (данные для линий является случайным, так что эти линии не должны пересекаться в тех же точках, что и в предыдущем снимке):

Colored Lines

+1

Я полностью смущен вашим использованием слова «индекс цвета» здесь. В некоторых местах ваш код, кажется, использует их в [правильном смысле] (http://web.agelid.com/protect/utile/documentation/OpenGL/OpenGL%204%20-%20Color%20Index%20Mode.htm) (например, альтернативный режим цвета RGB [A]), но в других местах вы используете их как буфер массива элементов (например, индексы для рисования вершин). Можете ли вы точно определить, что вы пытаетесь сделать здесь? Индексы цвета будут установлены с помощью вызова 'glIndexPointer (...)', но я не уверен, что вы действительно используете термин «индекс цвета» правильно. –

+0

Я имею в виду индекс в список цветовых кортежей. Там, где каждая из двух сегментов имеет другой цвет и, следовательно, разные значения цветового индекса. В основном я пытаюсь найти способ, при котором я могу покрасить каждую из строк отдельно, если вы нарисованы из VBO вершин. Помните, что в моем полном коде я рисую миллионы строк ... –

+0

Также почему я не могу использовать функцию 'glColorPointer (...)' здесь [http://www.opengl.org/sdk/docs /man2/xhtml/glColorPointer.xml), я использовал это раньше, когда рисовал линии из неиндексированного VBO? –

ответ

1

всего ХА, "indexed colour" на самом деле имеет совершенно иной смысл, что вы подразумеваете здесь. Сначала я думал, что вы на самом деле используете индексированные цвета вместо RGB [A]. То, что вы здесь делаете, это рисовать вершины (с цветом), используя буфер массива элементов, который вы называете индексами. Это может звучать педантично, тем более, что в наши дни почти никто не использует режимы индексного цвета, но вначале он определенно меня поймал.

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

Это не тот случай, когда вы можете использовать несколько VBO для хранения каждого атрибута вершины, они функционируют так, как если бы они были одним единственным массивом структурированных данных. То есть вы не можете сделать что-то вроде выбора вершинной позиции # 0, цвет вершины # 4 и вершина нормальная # 2 с помощью отдельных элементов массивов. У вас есть единственный массив элементов, и он всегда вытягивает каждый атрибут вершины из того же индекса.

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

+0

Хорошо, я надеялся, что этого не будет. Я знал, что структура вершин может хранить цвет и нормали и т. Д., Но, очевидно, как вы сказали, это не будет работать в моем случае, когда линия состоит из нескольких меньших строк. Также спасибо за разъяснение о «индексированных цветах». –

+0

Также я понимаю, что это выходит за рамки оригинального вопроса, но есть способ, которым я могу изменить свой VBO, чтобы я мог нарисовать полную линию (т. Е. 2 ​​сегмента) в одном «вызове» (используя этот термин здесь свободно, потому что очевидно, я использую VBOs), и поэтому я могу хранить меньше цветов и индексов и, следовательно, уменьшать передачу данных на GPU? –

+1

@JamesElder: Я не совсем уверен, что вы имеете в виду. Когда GL рисует примитивы (т. Е. Линии), нет необходимости передавать новый набор вершин или выборку и повторное вычисление каждой вершины. Особенно, когда вы используете индексированную команду рисования или примитив вентилятора или полосы. Он будет повторно использовать вершины, когда произойдет одна из этих двух вещей, что важно для таких вещей, как вершинное затенение, поскольку это уменьшает рабочую нагрузку преобразования. Здесь вы используете команду индексированного чертежа, поэтому (при наличии хорошего набора индексов) вершин повторно используются, и вы используете память GPU так же эффективно, как вы могли бы надеяться. –