Рендер 2D изображения в текстуру OpenGL

328
27 июня 2017, 23:59

Имеется Framebuffer object с прикреплённой текстурой и буффером глубины. Сначала происходит отрисовка в буффер, а потом этот буффер выводится на экран. Проблема в том, что, похоже, в буффер ничего не рисуется (а должны появится 2 квадрата).

Вопрос, как рендерить 2D изображение с помощью ортогональной проекции в текстуру?

Это функция создания буффера.

struct FrameBufferObject tempFBO;
tempFBO.buffer_width = Width;
tempFBO.buffer_height = Height;
//Render Buffer
glGenRenderbuffersEXT(1, &tempFBO.FrameBufferDepthBuffer);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, tempFBO.FrameBufferDepthBuffer);
    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, tempFBO.buffer_width, tempFBO.buffer_height);
    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, tempFBO.FrameBufferDepthBuffer);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
//Texture Buffer
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &tempFBO.FrameBufferTexture);
glBindTexture(GL_TEXTURE_2D, tempFBO.FrameBufferTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tempFBO.buffer_width, tempFBO.buffer_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
//Frame Buffer
glGenFramebuffersEXT(1, &tempFBO.FrameBuffer);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, tempFBO.FrameBuffer);
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tempFBO.FrameBufferTexture, 0);
    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, tempFBO.FrameBufferDepthBuffer);
    int FBOStatus = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
    if(FBOStatus == GL_FRAMEBUFFER_COMPLETE_EXT)
    {
        std::cout << "FrameBuffer creation succeed. glCheckFramebufferStatusEXT: " << FBOStatus << std::endl;
        tempFBO.buffer_status = true;
    } else
    {
        std::cerr << "FrameBuffer creation failed. glCheckFramebufferStatusEXT: " << FBOStatus << std::endl;
        tempFBO.buffer_status = false;
    }
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
return tempFBO;

А вот код отрисовки изображения

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBO.FrameBuffer);  //Биндим наш буффер
glPushAttrib(GL_VIEWPORT_BIT);  //Сохраняем параметры Viewport'a
glViewport(0, 0, FBO.buffer_width, FBO.buffer_height);  //Устанавливаем размеры для рисования в буффер
Clear();    //Очистка буффера, ничего важного
for(int i = 0; i < Game.get_EntityCount(); i++){
    DrawSquare(Game.GameEntities[i].get_X(), Game.GameEntities[i].get_Y(), 40, 40); //Рисуются 2 квадрата с координатами (100; 100) и (100; 200)
}
glPopAttrib();  //Восстанавливаем параметры
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);    //Переходим к основному кадру
Clear();    
DrawSquareT(0, 0, window_width, window_height, FBO.FrameBufferTexture); //Рисуем текстуру буффера
glutSwapBuffers();  //Выводим всё на экран

Содержимое DrawSquare

glBegin(GL_QUADS);
    glVertex3f(X - Width/2, Y + Height/2, 0.0f);
    glVertex3f(X + Width/2, Y + Height/2, 0.0f);
    glVertex3f(X + Width/2, Y - Height/2, 0.0f);
    glVertex3f(X - Width/2, Y - Height/2, 0.0f);
glEnd();

Содержимое DrawSquareT

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, Texture);
glBegin(GL_QUADS);
    glTexCoord2i(0, 0); glVertex3f(X,         Y + Height, 0.0f);
    glTexCoord2i(0, 1); glVertex3f(X + Width, Y,          0.0f);
    glTexCoord2i(1, 1); glVertex3f(X + Width, Y + Height, 0.0f);
    glTexCoord2i(1, 0); glVertex3f(X        , Y,          0.0f);
glEnd;
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);

Инициализация OpenGL и ортогональной проекции

glViewport(0, 0, window_width, window_height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, window_width, window_height, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glShadeModel(GL_SMOOTH);

Если рендерить без использования буффера, то всё отлично рисуется (2 квадрата).

READ ALSO
Как использовать общую память для двух процессов С линукс

Как использовать общую память для двух процессов С линукс

Нужно сделать общим для нескольких процессов массив структурРешил сделать так: один из процессов выделяет общий блок памяти с помощью shmget,...

267
Можно ли в Qt из pro файла выдрать VERSION?

Можно ли в Qt из pro файла выдрать VERSION?

Можно ли в Qt из pro файла выдрать VERSION? И потом использовать его как константу например

266
Почему не срабатывает find

Почему не срабатывает find

При работе с SVG столкнулся с проблемой: не находится элемент tspan в строке

314
jQuery &gt;как скрыть первый элемент с динамически формирующимеся последующими

jQuery >как скрыть первый элемент с динамически формирующимеся последующими

Принцип работы: используется компонент Fabrik на Joomla, в форме есть кнопки + / - для добавления точно такой же формыТребуется чтоб изначально был...

307