2013-06-19 6 views
9

Когда я использую glDrawArrays, я получаю треугольник в середине экрана, как и ожидалось. Но когда я пытаюсь использовать glDrawElements, ничего не возникает.Нет отображения из glDrawElements

Я пробовал всевозможные вещи, такие как переупорядочение вызовов gl, перемещение указателей на атрибуты и даже жесткие кодирующие вершины и индекс, как представляется, ничего не делают, как показано в моем коде.

Этот код выполняется один раз:

// Initialise GLFW 
if(!glfwInit()) 
{ 
     fprintf(stderr, "Failed to initialize GLFW\n"); 
     //return -1; 
} 

glfwOpenWindowHint(GLFW_FSAA_SAMPLES, 4); // 4x antialiasing 
glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3); // We want OpenGL 3.3 
glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 3); 
glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE); //We don't want the old OpenGL 

// Open a window and create its OpenGL context 
if(!glfwOpenWindow(mApplication->getWindowWidth(), mApplication->getWindowHeight(), 0,0,0,0, 32,0, GLFW_WINDOW)) 
{ 
     fprintf(stderr, "Failed to open GLFW window\n"); 
     glfwTerminate(); 
     //return -1; 
} 

// Initialize GLEW 
glewExperimental=true; // Needed in core profile 
if (glewInit() != GLEW_OK) 
{ 
     fprintf(stderr, "Failed to initialize GLEW\n"); 
     //return -1; 
} 

glfwSetWindowTitle("Hello World"); 
glViewport(0, 0, mApplication->getWindowWidth(), mApplication->getWindowHeight()); 
glEnable(GL_BLEND); 
glEnable(GL_TEXTURE_2D); 
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
glClearColor(0.0f, 0.0f, 0.4f, 0.0f); // colour to use when clearing 

Это выполняется каждый шаг:

float verts[] = { 
     -0.5f, 0.0f, 0.0f, 
     0.5f, 0.0f, 0.0f, 
     0.0f, 0.5f, 0.0f, 
}; 

unsigned int index[] = { 
     1, 2, 3, 
}; 

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

// VAO 
glGenVertexArrays(1, &VAO); 
glBindVertexArray(VAO); 

// VBO 
glGenBuffers(1, &VBO); 
glBindBuffer(GL_ARRAY_BUFFER, VBO); 
glBufferData(GL_ARRAY_BUFFER, sizeof(verts) * sizeof(float), verts, GL_STATIC_DRAW); 
glEnableVertexAttribArray(0); 
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); 

// IBO 
glGenBuffers(1, &IBO); 
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO); 
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(index) * sizeof(unsigned int), index, GL_STATIC_DRAW); 

glDrawArrays(GL_TRIANGLES, 0, 3); // this works 
//glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, &index); // this doesnt 

glfwSwapBuffers(); 

Это очень урезанная версия о том, что я пытаюсь достичь, но проблема в точности то же самое.

+4

Итак, вы создаете свои VAO/VBOs каждый раз, когда рисуете? Это не способ сделать это. Создайте один раз .. затем нарисуйте. – Grimmy

+0

@ legendends2k Я прочитал это, и он по-прежнему выглядит как мой код должен работать. – Neros

ответ

20

glDrawElements (GL_TRIANGLES, 3, GL_UNSIGNED_INT, & индекс); // это не работает

Конечно, это не так. Вы сохраняете свои индексы в буферном объекте. Точно так же последний аргумент указателя на glVertexAttribPointer интерпретируется как смещение в текущем связанном GL_ARRAY_BUFFER (если он связан), последний аргумент указателя glDrawElements интерпретируется как смещение в буфер, привязанный в настоящее время к GL_ELEMENT_ARRAY_BUFFER. Вы уже правильно хранить свои показатели в том, что, так что вы должны сказать `glDrawElements, что индексы начинаются со смещения 0 из этого буфера, как вы сделали с glVertexAttribPointer:

glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, nullptr); 

EDIT: И как bwroga баллов из в своем ответе вы должны ввести свои индексы с 0 вместо 1.

EDIT: И вы также передаете неправильные размеры в glBufferData. Вы используете sizeof(verts) * sizeof(floats) (а также для index), но verts - это массив, а sizeof массив уже является размером всей вещи в байтах, а не только количеством элементов, поэтому он должен быть просто sizeof(verts), иначе glBufferData будет попробуйте прочитать данные за пределами фактического размера массива, который является неопределенным поведением (и, к сожалению, в вашем случае, похоже, работает).

EDIT: И конечно же, как Grimmy указывает в своем комментарии, вы не должны воссоздать свой ВАО и ВБО каждый раз, когда вы рисуете, это инициализация вещи. Но это скорее концептуальная/оптимизационная ошибка (хотя и серьезная), а не фактическая «нерабочая» ошибка.

+0

вещь nullptr была ключом, спасибо. документация на gl довольно запутанна во времени, она читается так, как будто вам нужно указывать на расположение памяти в списке индексов. – Neros

+0

@Brae. Именно так использовались 'glDrawElements' (и' glVertexAttribPointer') до того, как VBOs вошли в игру. –

+2

@Brae * "вещь nullptr была ключом" * - Но все же не игнорируйте другие ошибки, они одинаково жестоки. –

2

Я думаю, что это:

unsigned int index[] = { 
    1, 2, 3, 
}; 

должен быть таким:

unsigned int index[] = { 
    0, 1, 2, 
}; 
+6

Да, хорошо заметили, но это не его единственная ошибка. –

+0

Протестировано, без кубиков. – Neros

0

Я бы начал ваш индекс в ноль, как указали другие. Но есть еще одна проблема, которую я вижу ...

glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, &index); 

должно быть ...

glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, index); 

... как индекс является массивом, то это уже указатель, нет необходимости в &.