glDrawArrays vs glDrawElements

Хорошо, я все еще пытаюсь заставить это работать. важные части моего кода:

def __init__(self, vertices, normals, triangles):
    self.bufferVertices = glGenBuffersARB(1)
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, self.bufferVertices)
    glBufferDataARB(GL_ARRAY_BUFFER_ARB, ADT.arrayByteCount(vertices), ADT.voidDataPointer(vertices), GL_STATIC_DRAW_ARB)
    self.vertices = vertices
    self.bufferNormals = glGenBuffersARB(1)
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, self.bufferNormals)
    glBufferDataARB(GL_ARRAY_BUFFER_ARB, ADT.arrayByteCount(normals), ADT.voidDataPointer(normals), GL_STATIC_DRAW_ARB)
    self.normals = normals
    self.bufferTriangles = glGenBuffersARB(1)

    glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, self.bufferTriangles)
    glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ADT.arrayByteCount(triangles), ADT.voidDataPointer(triangles), GL_STATIC_DRAW_ARB)

    self.triangles = triangles
    glDisableClientState(GL_VERTEX_ARRAY) **(Not sure if any of the following influence in any way)** 
    glDisableClientState(GL_NORMAL_ARRAY)
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)
    glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)

Я не думаю, что здесь что-то не так из того, что я читал о VBO. Итак, теперь у меня есть буферы вершин, нормалей (пока не используются) и индексов треугольников. Теперь для фактического рисования:

def draw(self, type):
    glDisableClientState(GL_VERTEX_ARRAY)  
    glDisableClientState(GL_NORMAL_ARRAY)
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)
    glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)
    **Again above line not sure if they have any use.**        
    glEnableClientState(GL_VERTEX_ARRAY)         
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, self.bufferVertices)
    glVertexPointer(3, GL_FLOAT, 0, None)

    glEnableClientState(GL_NORMAL_ARRAY);
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, self.bufferNormals)
    glNormalPointer(GL_FLOAT, 0, None)

    if type == GL_POINTS:    
        #glDrawArrays( GL_POINTS, 0, len(self.vertices) );    
        glDrawElements(type, len(self.vertices), GL_UNSIGNED_SHORT, 0)
    else:
        #glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, self.bufferTriangles)**(If I uncomment this doesnt seem to make any difference?!)**
        #glDrawArrays( GL_TRIANGLES, 0, len(self.triangles) );  
        glDrawElements(GL_TRIANGLES, len(self.triangles) , GL_UNSIGNED_SHORT, 0)**(What does it draw now since GL_ELEMENT_ARRAY_BUFFER_ARB is binded to 0 ?!)**

Теперь glDrawArrays работает. Но в случае, когда мне нужно рисовать свои треугольники, он не работает. t рисовать треугольники, которые я определил в bufferTriangles (это нормально из того, что я читал, поскольку drawArrays не использует индексы? Или я здесь ошибаюсь?). Проблема в том, что если я попытаюсь использовать glDrawElements, все выйдет из строя:

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x000000003150ebbc
Crashed Thread:  0

Thread 0 Crashed:
0   com.apple.GeForce8xxxGLDriver   0x1a3e7050 gldGetTextureLevel + 743600
1   com.apple.GeForce8xxxGLDriver   0x1a3e7563 gldGetTextureLevel + 744899
2   GLEngine                        0x1a206eee gleDrawArraysOrElements_VBO_Exec + 1950

Что мне здесь не хватает? Насколько я понимаю, я, вероятно, передаю где-то плохой указатель? Обратите внимание, что даже если я попытаюсь использовать glDrawElements (type, 24, GL_UNSIGNED_INT, 0), он все равно выйдет из строя, даже несмотря на то, что количество определенных треугольников намного больше, поэтому я не думаю, что это имеет какое-либо отношение к размеру.

С Уважением, м, наверное, где-то передал плохой указатель? Обратите внимание, что даже если я попытаюсь использовать glDrawElements (type, 24, GL_UNSIGNED_INT, 0), он все равно выйдет из строя, даже несмотря на то, что количество определенных треугольников намного больше, поэтому я не думаю, что это имеет какое-либо отношение к размеру.

С Уважением, м, наверное, где-то передал плохой указатель? Обратите внимание, что даже если я попытаюсь использовать glDrawElements (type, 24, GL_UNSIGNED_INT, 0), он все равно выйдет из строя, даже несмотря на то, что количество определенных треугольников намного больше, поэтому я не думаю, что это имеет какое-либо отношение к размеру.

С Уважением, Богдан

РЕДАКТИРОВАТЬ: Хорошо, теперь я провел дополнительную проверку, и вот моя текущая ситуация: я изменил len (треугольники) на ADT.byteCount, решения пока нет. Итак, я проверил все данные, которые получал, и получилось так: массив вершин содержит ~ 60000 * 3 = 180000 записей вершин типа GL_Float, как и массив нормалей. Так как вершин всего <62535, я использую беззнаковые сокращения для треугольников. Итак, у меня len (треугольников) ~ 135000. Я также изменил glDrawElements (GL_TRIANGLES, len (self.triangles), GL_UNSIGNED_SHORT , 0). Я также проверил, и все данные из массива треугольников находятся в диапазоне от 0 до 62534, как и я. подумав, может быть, какой-то индекс, который находится вне диапазона, поскользнулся. Что еще здесь могло быть не так? Ох, и как работает glDrawElements (GL_POINTS, ...)? Нужны ли еще какие-то индексы?

EDIT2 Я обновил приведенный выше код и, как там сказано, теперь элементы draw рисуют мои GL_POINTS, но я не уверен, где он берет индексы? Или они не нужны в случае GL_POINTS? А для GL_TRIANGLES это работает так, с комментариями glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, self.bufferTriangles), но опять же, какие индексы нужны здесь теперь, когда буфер элемента привязан к 0 ?! И еще одно: glDrawElements не будет рисовать все точки, которые делает glDrawArrays. Для лучшего объяснения:

glDrawArrays( GL_POINTS, 0, len(self.vertices) );

Это показывает все мои точки правильно:

glDrawElements(type, len(self.vertices), GL_UNSIGNED_SHORT, 0)

Кажется, что здесь заметно меньше точек, чем у glDrawArrays. Забавно то, что если я передам размер что-то вроде 10 * len (self.vertices) для рисования элементов, он будет рисовать все точки (некоторые, возможно, дважды или больше; могу я это проверить? ), но разве это не должно было произойти?

С уважением

EDIT3

Более точная информация о массивах:

vertices - массив чисел с плавающей запятой,

len (vertices) = 180000 byteCount (вершины) = 720000

треугольников - массив из numpy.uint16

len (треугольников) = 353439 byteCount (треугольники) = 706878 min (треугольники) = 0 max (triangles) = 59999, поэтому они должны указывать на допустимые вершины

Рисование готово:

glDrawElements (GL_TRIANGLES, len (self.triangles), GL_UNSIGNED_SHORT, 0)

UPDATE

Хорошо, просто Когда я понял, как это должно работать, я попытался пропустить VBO для элементов и просто сказал:

glDrawElements(GL_TRIANGLES, len(self.triangles) , GL_UNSIGNED_SHORT, ADT.voidDataPointer(self.triangles))

Теперь это не только работает и отлично рисует все мои треугольники, но и FPS лучше. Разве VBO не должен быть быстрее? И что могло привести к срабатыванию вышеуказанного подхода, но к сбою следующего:

glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, self.bufferTriangles)
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ADT.arrayByteCount(triangles), ADT.voidDataPointer(triangles), GL_STATIC_DRAW_ARB)
glDrawElements(GL_TRIANGLES, len(self.triangles) , GL_UNSIGNED_SHORT, 0)
8
задан Bogdan 27 May 2011 в 07:46
поделиться