2010-06-01 3 views
1

Код объекта Vertex Buffer Object предназначен для рендеринга текстур красиво, но вместо этого текстуры визуализируются странно с помощью некоторых треугольных фигур.OpenGL Vertex Buffer Код объекта, дающий плохой результат

Что происходит - 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; 
} 

Вот некоторые relavant код из другая функция, которая должна нарисовать текстуры с 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); 

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

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

спасибо.

ответ

1

Если вы хотите использовать один 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); 

И рисовать.

EDIT: Выполнено смещение с offsetof(), как предлагал Bahbar.

+1

Настоящий nitpicking, но вам лучше использовать некоторую форму offsetof, чтобы найти смещение для координат текстуры. Здесь, вероятно, нет отступов между y и s, но, скажем, у вас было 3 шорта для позиции, тогда история была бы совсем другой (3 * sizeof (GLshort) будет неправильным смещением, так как смещение, вероятно, будет 8 байтов, а не 6). – Bahbar

+0

Большое спасибо за это. Я сейчас изучу его. –

+0

Использование GLdouble для координат текстуры, а также вершин, конечно, я могу просто использовать многомерный массив? Мне нужно будет использовать двойники для координат текстуры для моих закругленных текстур. –

0

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

+0

Благодарим вас за ответ. Я читал, что это можно сделать таким образом. Это было по теме, и человек, который хотел решения, сказал, что это сработало. Если я поместил координаты текстуры после вершин, что мне помещать внутри «glTexCoordPointer»? Я не понимаю, как заставить его указывать на девятый элемент массива, где начнутся координаты текстуры. Могу ли я поместить эти точечные функции в функцию create_box_vbo и использовать их только один раз? Еще раз спасибо. –

+0

Ну, я просто попытался переместить функции, и это усугубило меня, поэтому я не могу этого сделать. –

+0

Я просто подумал, что координаты текстуры будут одинаковыми для каждой текстуры, поэтому почему бы просто не использовать один VBO для координат текстуры. Глупо не делать этого. –