2015-09-15 3 views
2

У меня есть два 'std :: vector's, один для индексов и один для вершин, который я заполняю std :: vector.push_back(). Тогда яOpenGL Draw Vertex Buffer Object

glGenBuffers(1, &verticesbuffer); 
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, verticesbuffer); 
glBufferData(GL_ELEMENT_ARRAY_BUFFER, /*EDITED-->*/vertices.size() * sizeof(vertices[0])/*<--EDITED*/, &vertices[0], GL_STATIC_DRAW); 

для создания буферов для каждого, а затем попытаться нарисовать многоугольник с

glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 

glBindBuffer(GL_ARRAY_BUFFER, verticesbuffer); 
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesbuffer); 

glDrawElements(
    GL_TRIANGLES, 
    indices.size(), 
    GL_UNSIGNED_INT, 
    &indices[0] 
    ); 

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 

Когда я запускаю программу, ничего не отображается. Я могу заставить его работать с использованием glBegin()/glEnd(), но проиндексированное vbo просто не работает (glGetError() также не дает никаких ошибок). Я даже не знаю, насколько это дистанционно близко к правильному, поскольку я искал бесчисленные учебники и другие вопросы о стеке и пытался много чего исправить. Я должен также упомянуть, что я назвал

glLoadIdentity(); 
glMatrixMode(GL_MODELVIEW); 
glOrtho(0.0f, windowX, windowY, 0.0f, 0.0f, 1000.0f); 

в начале программы, в которой я понятия не имею, если это правильно (как вы можете видеть, я довольно новый в этом материале).

+0

Уверены, что glEnable или glEnableClientState отсутствует? –

+0

Я исправил ошибку, указанную в ответах, но я все еще ничего не вижу. Я пропустил glEnable или glEnableClientState? Вызов метода OpenGL, который я опубликовал в вопросе, это единственные, которые я сделал, связанные с чертежом. – ArcaneEnforcer

+0

. Проблема с этим вопросом заключается в том, что вы не предоставили [MCVE] (http://stackoverflow.com/help/mcve). Мы рассмотрели очевидную причину проблемы с помощью кода, который вы предоставили. Если вы хотите продолжить получать помощь, вам следует опубликовать новый вопрос, включая MCVE. – paddy

ответ

2

Вы неправильно понимаете, как работает sizeof. Это оператор, который выполняется во время компиляции и возвращает размер (в байтах) указанного типа или переменной.

float f; 
std::cout << sizeof(f); // prints 4 
std::cout << sizeof(float); // prints 4 

Но что происходит, когда мы используем sizeof на указатель на массив? Давайте рассмотрим следующий случай:

float array1[50]; // static size array, allocated on the stack 
float *array2 = new float[50]; // dynamic size array, allocated on the heap 

std::cout << sizeof(array1); // prints 200, which is ok (50*4 == 200) 
std::cout << sizeof(array2); // prints out the size of a float pointer, not the array 

В первом случае мы используем sizeof на статический массив, который выделяется в стеке. Поскольку размер array1 постоянный, компилятор знает об этом и возвращает его фактический размер в байтах на sizeof(array1).

Во втором случае мы используем sizeof для динамического массива, который выделяется в куче. Размер array2 в идеале не может быть известен во время компиляции (в противном случае вы должны использовать статический массив, если вписывается в стек), поэтому компилятор ничего не знает о размере массива array2, поэтому он возвращает размер указатель к нашему массиву.

Что происходит, когда вы используете sizeof на std :: vector?

std::vector<float> vec(50); 
std::cout << sizeof(vec); // prints out the size of the vector (but it's not 4*50) 

Но если sizeof(vec) возвращает размер вектора, почему не возвращается 4 * 50? std :: vector управляет базовым динамически распределенным массивом (второй случай в предыдущем примере), поэтому компилятор ничего не знает о размере этого базового массива. Вот почему он возвращает размер общих инкапсулированных (скрытых) переменных векторного объекта, включая размер указателя на фактические данные массива. Если вам нужно количество элементов в вашем базовом массиве, вам нужно использовать vec.size(). Чтобы получить размер базового массива float в байтах, просто используйтеvec.size() * sizeof(float).

Фиксация кода со знанием свыше:

std::vector<float> vertices; 
// ...add vertices with push_back()... 
glBufferData(GL_ELEMENT_ARRAY_BUFFER, vertices.size() * sizeof(float), &vertices[0], GL_STATIC_DRAW); 

или

std::vector<float> vertices; 
// ..add vertices with push_back()... 
glBufferData(GL_ELEMENT_ARRAY_BUFFER, vertices.size() * sizeof(vertices[0]), &vertices[0], GL_STATIC_DRAW); 
3

Проблема в том, что вы ожидали sizeof(vertices), чтобы дать вам общее количество байтов, хранящихся в векторе. Однако он дает только размер самого векторного объекта, а не динамические данные, которые он содержит.

Вместо этого вы должны использовать vertices.size() * sizeof(vertices[0]).

0

В дальнейшем вы также можете использовать графический отладчик, чтобы помочь с этими вопросами. В зависимости от вашей карты вы можете использовать студию AMD gpu perf или nVidia nsight на окнах или отладчик графики в Linux. Это экономит много времени и головных болей.

Если вы снова получите пустой экран. Запустите приложение с прикрепленным отладчиком и следуйте по конвейеру.

Вы должны увидеть данные, поданные в вершинный шейдер, и поскольку они были короче, чем вы ожидали, это будет указывать на проблему, и вы можете начать там.