Не удается выполнить рендеринг в объект кадрового буфера

Я пытаюсь отрендерить маленький четырехугольник на большом четырехугольнике, но, похоже, это не работает. Он отображает оба четырехугольника в виде маленького пурпурного четырехугольника и большого белого четырехугольника с линией на нем, расположенных рядом друг с другом, а не один поверх другого.

glEnable( GL_TEXTURE );
glEnable( GL_TEXTURE_2D );

float *data = new float[ 756 * 756 * 3 ];

for( int i = 0 ; i < 756 ; i++ )
    for( int j = 0 ; j < 756 ; j++ )
        if( i == j )
            for( int k = 0; k < 3 ; k++ )
                data[i * 756 * 3 + j * 3 + k] = 0.0f;
        else
            for( int k = 0; k < 3 ; k++ )
                data[ i * 756 * 3 + j * 3 + k ] = 1.0f;

GLuint Texture;
GLuint FrameBufferObject;

glGenTextures( 1 , &Texture );
glBindTexture( GL_TEXTURE_2D , Texture );
glTexImage2D( GL_TEXTURE_2D , 0 , 3 , 756 , 756 , 0 , GL_RGB , GL_FLOAT , data );

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glBindTexture( GL_TEXTURE_2D , 0 );

glewInit();

glGenFramebuffers( 1 , &FrameBufferObject );
glBindFramebuffer( GL_DRAW_FRAMEBUFFER , FrameBufferObject );
glBindTexture( GL_TEXTURE_2D , Texture );

glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Texture, 0);

//GLuint atchements[] = { GL_COLOR_ATTACHMENT0 };
//glDrawBuffers( 1 , atchements );

GLenum e = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
    if (e != GL_FRAMEBUFFER_COMPLETE)
        cout << " MASIVE ERROR, ABORT ! " << endl;

glBindFramebuffer( GL_DRAW_FRAMEBUFFER , 0 );

/* program main loop */
while (!bQuit)
{
    /* check for messages */
    if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        /* handle or dispatch messages */
        if (msg.message == WM_QUIT)
        {
            bQuit = TRUE;
        }
        else
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    else
    {
        /* OpenGL animation code goes here */

        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        glLoadIdentity();

        glPushMatrix();
        glRotatef(theta, 0.0f, 0.0f, 1.0f);

        glBindTexture( GL_TEXTURE_2D , 0 );

        glBindFramebuffer( GL_DRAW_BUFFER , FrameBufferObject );

        //GLuint atchements[] = { GL_COLOR_ATTACHMENT0 };
        //glDrawBuffers( 1 , atchements );

        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        glBindTexture( GL_TEXTURE_2D , 0 );
        glBegin(GL_QUADS);
            glColor3f( 1 , 0 , 1 );

            glVertex2f( 0 , 0 );
            glVertex2f( 0 , .1 );
            glVertex2f( .1 , .1 );
            glVertex2f( .1 , 0 );

            glColor3f( 1 , 1 , 1 );
        glEnd();

        glBindFramebuffer( GL_DRAW_BUFFER , 0 );

        glScalef( 0.5 , .5 , .5 );
        glTranslatef( 0 , 0.3 , 0 );

        glBindTexture( GL_TEXTURE_2D , Texture );
        glBegin(GL_QUADS);

            glTexCoord2f( 0 , 0 );
            glVertex2f( 0 , 0 );

            glTexCoord2f( 0 , 1 );
            glVertex2f( 0 , 1 );

            glTexCoord2f( 1 , 1 );
            glVertex2f( 1 , 1 );

            glTexCoord2f( 1 , 0 );
            glVertex2f( 1 , 0 );

        glEnd();

        glPopMatrix();

        SwapBuffers(hDC);

        theta += 1.0f;
        Sleep (1);
    }
}

person Pangi    schedule 10.06.2014    source источник


Ответы (1)


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

Что вы сейчас делаете в основном цикле:

  1. установите FBO как кадровый буфер отрисовки, поэтому рендеринг на Texture
  2. очистить это
  3. нарисуйте четырехугольник с пурпурным цветом, текстурирование все еще включено, но объект текстуры 0 привязан
  4. по-прежнему оставлять FBO привязанным к отрисовке кадрового буфера
  5. вы также привязываете FBO как чтение фреймбуфера, что здесь бесполезно
  6. визуализировать белый квадрат с текстурой, которую вы визуализировали в 2 и 3

Комбинация шагов 4 и 6 создает недопустимый цикл обратной связи, поскольку на этом этапе вы все еще выполняете рендеринг в Texture. Вы никогда не визуализируете на экране, поэтому вы вообще ничего не должны видеть. Тот факт, что вы действительно видите что-то помимо черного экрана, означает, что я проглядел какую-то другую ошибку, потому что вы не должны. (EDIT: ОП заметил, что изначально он написал glBindFramebuffer(GL_DRAW_BUFFER,...) вместо GL_DRAW_FRAMEBUFFER, что теперь полностью объясняет наблюдаемое поведение.)

Вы, вероятно, хотите, чтобы glBindFramebuffer(GL_DRAW_FRAMEBUFFER,0) вместо шагов 4 и 5 снова отображался в буфер кадра по умолчанию.

Некоторые другие проблемы:

  • вы никогда не настраиваете размер окна просмотра, чтобы он соответствовал размеру используемого вами фреймбуфера
  • вы неоднократно повторно прикрепляете текстуру к FBO
  • вы используете массив чисел с плавающей запятой для указания исходной текстуры, хотя ваш внутренний формат представляет собой всего лишь 8-битный нормализованный формат uint на канал
person derhass    schedule 10.06.2014
comment
Итак, вы правы насчет ошибок, я их не видел, но после того, как я их исправил, программа ведет себя так же. Я не исправил окно просмотра, есть ли причина, по которой это должно быть проблемой? Также я не понимаю, почему вы говорите, что мой формат 8 бит на канал, здесь нет места, где я его установил: glTexImage2D (GL_TEXTURE_2D, 0, 3, 756, 756, 0, GL_RGB, GL_FLOAT, данные) ;? - person Pangi; 10.06.2014
comment
Как вы сказали, я не должен видеть фиолетовый квадрат, если не всю сцену. Но похоже, что он полностью игнорирует тот факт, что я рисую на фбо. - person Pangi; 10.06.2014
comment
@ user3727118: это просто формат, в котором ваши данные организованы в памяти клиента. Графический процессор будет использовать то, что вы установили как internalFormat. Вы просто помещаете туда 3, что является старым, устаревшим ярлыком для указания GL_RGB, который является просто стандартным целым числом 8 бит на канал. Если вам действительно нужен формат с плавающей запятой, вы должны использовать что-то вроде GL_RGB32F. - person derhass; 10.06.2014
comment
о, тогда я не понимаю, почему я получаю идеальную диагональ на моем белом прямоугольнике, но я не думаю, что это то место, откуда возникает проблема. - person Pangi; 10.06.2014
comment
@user3727118 user3727118: данные преобразуются из формата клиента во внутренний формат, поэтому сама текстура выглядит правильно, у вас просто есть бессмысленное преобразование данных между ними. Но да, это не главная ваша проблема. И я до сих пор не знаю, почему он ведет себя так, как вы описываете. Является ли FBO полным кадровым буфером? Выявляет ли что-то проверка ошибок GL? - person derhass; 10.06.2014
comment
нашел, это был GL_DRAW_FRAMEBUFFER, а не GL_DRAW_BUFFER - person Pangi; 11.06.2014
comment
@ user3727118: хм, кажется, я слишком быстро просмотрел ваш код и недостаточно внимательно прочитал. Я обновил свой ответ соответственно. - person derhass; 11.06.2014