OpenGL Vertex Buffer Объектный код, выдающий неверный вывод - PullRequest
1 голос
/ 01 июня 2010

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

Что происходит - http://godofgod.co.uk/my_files/wrong.png

Что должно произойти - http://godofgod.co.uk/my_files/right.png

Эта функция создает VBO и устанавливает данные вершин и координат текстуры:

extern "C" GLuint create_box_vbo(GLdouble size[2]){
    GLuint vbo;
    glGenBuffers(1,&vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    GLsizeiptr data_size = 8*sizeof(GLdouble);
    GLdouble vertices[] = {0,0,  0,size[1],  size[0],0,  size[0],size[1]};
    glBufferData(GL_ARRAY_BUFFER, data_size, vertices, GL_STATIC_DRAW);
    data_size = 8*sizeof(GLint);
    GLint textcoords[] = {0,0,  0,1,  1,0, 1,1};
    glBufferData(GL_ARRAY_BUFFER, data_size, textcoords, GL_STATIC_DRAW);
    return vbo;
}

Вот некоторый соответствующий код из другой функции, которая должна рисовать текстуры с помощью VBO.

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor4d(1,1,1,a/255);
glBindTexture(GL_TEXTURE_2D, texture);
glTranslated(offset[0],offset[1],0);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexPointer(2, GL_DOUBLE, 0, 0);
glEnableClientState(GL_VERTEX_ARRAY);
glTexCoordPointer (2, GL_INT, 0, 0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDrawArrays(GL_TRIANGLES, 1, 3);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);

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

Я спрашиваю, что сломано, но я также поступаю правильно в целом?

Спасибо.

Ответы [ 2 ]

1 голос
/ 02 июня 2010

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

Определите ваши данные:

typedef struct {
    GLdouble x, y;
    GLint    s, t;
} VertexData;

VertexData data[] = {
//  x        y        s  t
    {0.0,     0.0,     0, 0},
    {0.0,     size[1], 0, 1},
    {size[0], 0.0,     1, 0},
    {size[0], size[1], 1, 1}
};

Скопируйте его в VBO:

glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(data), (GLvoid*)data, GL_STATIC_DRAW);

Установить указатели. Обратите внимание, что размер шага - это размер вашей структуры, а сам указатель служит смещением:

glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexPointer(2, GL_DOUBLE, sizeof(VertexData), (GLvoid*)offsetof(VertexData, x));
glTexCoordPointer(2, GL_INT, sizeof(VertexData), (GLvoid*)offsetof(VertexData, s));
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

И ничья.

РЕДАКТИРОВАТЬ: Реализовано смещение с помощью offsetof (), как предложил Bahbar.

0 голосов
/ 01 июня 2010

Вы загружаете данные дважды в VBO. Второй вызов glBufferData заменяет первый. Тогда оба вызова gl * Pointer фактически используют одни и те же данные при вызове draw.

...