OpenGL VBO (со смешанным индексом, массив координат tex) не работает, помогите пожалуйста - PullRequest
0 голосов
/ 02 февраля 2011

Я пытаюсь улучшить производительность моего рисунка. Что я на самом деле делаю, так это рисую сетку в 2D с высотой в качестве цвета. У меня есть матрица mesh_xy для координаты x-y и mesh_z для матрицы высоты, и я строю матрицу индекса для элементов построения. Сначала я попытался использовать массив на стороне клиента, и он отлично работает. Затем я внес минимальное изменение, поместив mesh_xy на стороне сервера как VBO. Ничего не отображается. Кто-нибудь может мне помочь?

Соответствующий код вставлен ниже. draw_bmfm5 () - это функция, использующая массив на стороне клиента, которая прекрасно работает. draw_bmfm6 () - это VBO (только mesh_xy находится на стороне сервера). Я должен упомянуть одну вещь: моя видеокарта поддерживает VBO, который я тестировал с помощью другой программы.

    void draw_bmfm5(float scale)
{
    glPushMatrix();
    glScalef(scale,scale,1.0f);

    glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
    glShadeModel(GL_SMOOTH);
    glEnable(GL_TEXTURE_1D);
    glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);//which is not default
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);//use texture coordinate
    glEnableClientState(GL_INDEX_ARRAY);
    glVertexPointer(2,GL_FLOAT,0,mesh_xy);//all 1d array, make it 2D and less data is transferred
    glTexCoordPointer(1,GL_FLOAT,0,mesh_z);
    for(i=0;i<n-1;i++)
    {
        glDrawElements(GL_TRIANGLE_STRIP,2*HEIGHT,GL_UNSIGNED_INT,index_xy[i]);
    }
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_INDEX_ARRAY);

    glDisable(GL_TEXTURE_1D);
    glPopMatrix();

}

//the only difference between 5 and 6 is:
//we are going to store the mesh_xy into the server side
GLuint vbo_vertex,vbo_tex,vbo_indx;
PFNGLGENBUFFERSARBPROC pglGenBuffersARB = 0;                     // VBO Name Generation Procedure
PFNGLBINDBUFFERARBPROC pglBindBufferARB = 0;                     // VBO Bind Procedure
PFNGLBUFFERDATAARBPROC pglBufferDataARB = 0;                     // VBO Data Loading Procedure
#define glGenBuffersARB           pglGenBuffersARB
#define glBindBufferARB           pglBindBufferARB
#define glBufferDataARB           pglBufferDataARB

void create_vbo()
{


    glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)wglGetProcAddress("glGenBuffersARB");
    glBindBufferARB = (PFNGLBINDBUFFERARBPROC)wglGetProcAddress("glBindBufferARB");
    glBufferDataARB = (PFNGLBUFFERDATAARBPROC)wglGetProcAddress("glBufferDataARB");

    glGenBuffersARB(1,&vbo_vertex);
    glBindBufferARB(GL_ARRAY_BUFFER,vbo_vertex);
    glBufferDataARB(GL_ARRAY_BUFFER,3000*141*2*sizeof(float),mesh_xy,GL_STATIC_DRAW);

    glGenBuffersARB(1,&vbo_tex);

    glGenBuffersARB(1,&vbo_indx);
    glBindBufferARB(GL_ARRAY_BUFFER,vbo_tex);
    glBufferDataARB(GL_ARRAY_BUFFER,3000*141*sizeof(float),mesh_z,GL_DYNAMIC_DRAW);

    glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER,vbo_indx);
    glBufferDataARB(GL_ARRAY_BUFFER,HEIGHT*WIDTH*2*sizeof(int),index_xy,GL_DYNAMIC_DRAW);


}
void draw_bmfm6(float scale)
{
    glPushMatrix();
    glScalef(scale,scale,1.0f);

    glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
    glShadeModel(GL_SMOOTH);
    glEnable(GL_TEXTURE_1D);
    glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);//which is not default
    glDisableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);//use texture coordinate
    glEnableClientState(GL_INDEX_ARRAY);
    //glVertexPointer(2,GL_FLOAT,0,mesh_xy);//all 1d array, make it 2D and less data is transferred
    glBindBufferARB(GL_ARRAY_BUFFER,vbo_vertex);
    glVertexPointer(2,GL_FLOAT,0,0);

    glTexCoordPointer(1,GL_FLOAT,0,mesh_z);
    for(i=0;i<n-1;i++)
    {
        glDrawElements(GL_TRIANGLE_STRIP,2*HEIGHT,GL_UNSIGNED_INT,index_xy[i]);
    }
    glDisableClientState(GL_VERTEX_ARRAY);

    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_INDEX_ARRAY);

    glDisable(GL_TEXTURE_1D);
    glPopMatrix();

}

1 Ответ

2 голосов
/ 03 февраля 2011

GL_INDEX_ARRAY не означает, что вы думаете, что это значит.Он предназначен для управления селектором цвета из цветовой палитры, которая используется в GL при рендеринге в палитрированные кадровые буферы.Тот факт, что вы вызываете glDrawElements, означает, что вы используете индексы вершин.Нет никакого массива на стороне клиента для включения.

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

glBindBufferARB(GL_ARRAY_BUFFER,vbo_tex);
glBufferDataARB(GL_ARRAY_BUFFER,3000*141*sizeof(float),mesh_z,GL_DYNAMIC_DRAW);

glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER,vbo_indx);
glBufferDataARB(GL_ARRAY_BUFFER,HEIGHT*WIDTH*2*sizeof(int),index_xy,GL_DYNAMIC_DRAW);

Последний вызов фактически используетбуфер связан с ARRAY_BUFFER, то есть vbo_tex.Итак, вы загружаете свои индексы в vbo_tex и ничего не помещаете в vbo_indx

Далее, при привязке VBO, вы не выбираете правильное vbo для каждого вызова Pointer.

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

Соединение всего этого дает:

void create_vbo()
{
    glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)wglGetProcAddress("glGenBuffersARB");
    glBindBufferARB = (PFNGLBINDBUFFERARBPROC)wglGetProcAddress("glBindBufferARB");
    glBufferDataARB = (PFNGLBUFFERDATAARBPROC)wglGetProcAddress("glBufferDataARB");

    glGenBuffersARB(1,&vbo_vertex);
    glBindBufferARB(GL_ARRAY_BUFFER,vbo_vertex);
    glBufferDataARB(GL_ARRAY_BUFFER,3000*141*2*sizeof(float),mesh_xy,GL_STATIC_DRAW);

    glGenBuffersARB(1,&vbo_tex);
    glBindBufferARB(GL_ARRAY_BUFFER,vbo_tex);
    glBufferDataARB(GL_ARRAY_BUFFER,3000*141*sizeof(float),mesh_z,GL_DYNAMIC_DRAW);

}
void draw_bmfm6(float scale)
{
    glPushMatrix();
    glScalef(scale,scale,1.0f);

    glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
    glShadeModel(GL_SMOOTH);
    glEnable(GL_TEXTURE_1D);
    glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);//which is not default
    glEnableClientState(GL_VERTEX_ARRAY); // Why was this Disable ?
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);//use texture coordinate
    //glEnableClientState(GL_INDEX_ARRAY); // removed
    glBindBufferARB(GL_ARRAY_BUFFER,vbo_vertex);
    glVertexPointer(2,GL_FLOAT,0,0);

    glBindBufferARB(GL_ARRAY_BUFFER,vbo_tex); // Binding the texcoord buffer
    glTexCoordPointer(1,GL_FLOAT,0,0); // 0 as offset
    for(i=0;i<n-1;i++)
    {
        glDrawElements(GL_TRIANGLE_STRIP,2*HEIGHT,GL_UNSIGNED_INT,index_xy[i]);
    }
    glDisableClientState(GL_VERTEX_ARRAY);

    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    // glDisableClientState(GL_INDEX_ARRAY); // not needed

    glDisable(GL_TEXTURE_1D);
    glPopMatrix();

}

Примечание. Я не тестировал этот код, но исправил ряд проблем.Могут быть и другие.

Наконец, для отправки данных массива индекса в VBO потребуется привязка и помещение данных в ELEMENT_ARRAY_BUFFER, а также передача смещений в буфер из вызова glDrawElements.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...