OpenGL: Проблемы с рендерингом в текстуру и объект фреймбуфера

Я хочу визуализировать сцену с изначально пустой текстурой. Для этого я использую объект Framebuffer, к которому прикрепляю пустую 2-мерную текстуру и буфер глубины. После настройки, что касается тестирования, Я рисую в сцене простой четырехугольник. Каждая вершина имеет свой цвет, поэтому я ожидаю, что в текстуре будет интерполированный по цвету квад. Затем я использую эту текстуру, содержащую четырехугольник, и накладываю ее на другой четырехугольник. Итак, у меня всегда есть четырехугольник в моем кадровом буфере по умолчанию, у которого есть текстура, содержащая цветной четырехугольник. Надеюсь, это не слишком сбивает с толку ...

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

Спасибо Уолтер


Вот код, который у меня есть: // создаем объект буфера кадра glGenFramebuffers (1, & frameBufferObject);

// create depth buffer
glGenRenderbuffers(1, &depthAttachment);

// create empty texture
int width = 512;
int height = 512;
int numberOfChannels = 3;
GLuint internalFormat = GL_RGB;
GLuint format = GL_RGB;

unsigned char* texels = new unsigned char[width * height * numberOfChannels];

glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, GL_UNSIGNED_BYTE, texels);

glGenerateMipmap(GL_TEXTURE_2D);

delete[] texels;
texels = NULL;

// activate & bind empty texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);

// attach empty texture to framebuffer object
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferObject);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);

// define render targets (empty texture is at GL_COLOR_ATTACHMENT0)
glDrawBuffers(1, GL_COLOR_ATTACHMENT0);

// attach depth buffer
glBindRenderbuffer(GL_RENDERBUFFER, depthAttachment);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthAttachment);

// use framebuffer object
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferObject);

// draw the colored quad into the initially empty texture
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);

// store attibutes
glPushAttrib(GL_VIEWPORT_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// reset viewport
glViewport(0, 0, width, height);

// make background yellow
glClearColor(1.0f, 1.0f, 0.0f, 1.0f);

// draw quad into texture attached to frame buffer object
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);
    glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glVertex2f(0.0f, 100.0f); // top left
    glColor4f(1.0f, 0.0f, 0.0f, 1.0f); glVertex2f(0.0f, 0.0f); // bottom left
    glColor4f(0.0f, 1.0f, 0.0f, 1.0f); glVertex2f(100.0f, 0.0f); // bottom right
    glColor4f(0.0f, 0.0f, 1.0f, 1.0f); glVertex2f(100.0f, 100.0f); // top right
glEnd();

// restore attributes
glPopAttrib();

glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);

// use default framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);

// clear default framebuffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// draw the scene
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();

glColor4f(1.0, 1.0, 1.0, 1.0);

// begin texture mapping
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

glBegin(GL_QUADS);
    glNormal3d(0.0f, 0.0f, 1.0f);
    glTexCoord2f(0.0f, 0.0f); glVertex3f(0.0f, 50.0f, -100.0f);    // top left
    glTexCoord2f(0.0f, 1.0f); glVertex3f(0.0f, 0.0f, -100.0f);     // bottom left
    glTexCoord2f(1.0f, 1.0f); glVertex3f(50.0f, 0.0f, -100.0f);    // bottom right
    glTexCoord2f(1.0f, 0.0f); glVertex3f(50.0f, 50.0f, -100.0f);   // top right
glEnd();

glDisable(GL_TEXTURE_2D);

glPopMatrix();

// swap buffers (I forgot to mention that I use SDL)
SDL_GL_SwapBuffers();

Ожидаемый результат:

  • Текстура с цветным четырехугольником на желтом фоне
  • Эта текстура отображается на другом четырехугольнике

Фактический результат:

  • Серая текстура
  • Текстура может быть успешно отображена на другом квадроцикле

РЕДАКТИРОВАТЬ: Я не упомянул обработку ошибок. Вот как я проверяю ошибки. Он включает дополнительные случаи, предложенные Полом С. Спасибо за это.

GLuint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
switch(status) {
    case GL_FRAMEBUFFER_COMPLETE:
        return;
        break;

case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
    throw FramebufferIncompleteException("An attachment could not be bound to frame buffer object!");
    break;

case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
    throw FramebufferIncompleteException("Attachments are missing! At least one image (texture) must be bound to the frame buffer object!");
    break;

case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
    throw FramebufferIncompleteException("The dimensions of the buffers attached to the currently used frame buffer object do not match!");
    break;

case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
    throw FramebufferIncompleteException("The formats of the currently used frame buffer object are not supported or do not fit together!");
    break;

case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
    throw FramebufferIncompleteException("A Draw buffer is incomplete or undefinied. All draw buffers must specify attachment points that have images attached.");
    break;

case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
    throw FramebufferIncompleteException("A Read buffer is incomplete or undefinied. All read buffers must specify attachment points that have images attached.");
    break;

case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
    throw FramebufferIncompleteException("All images must have the same number of multisample samples.");
    break;

case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS :
    throw FramebufferIncompleteException("If a layered image is attached to one attachment, then all attachments must be layered attachments. The attached layers do not have to have the same number of layers, nor do the layers have to come from the same kind of texture.");
    break;

case GL_FRAMEBUFFER_UNSUPPORTED:
    throw FramebufferIncompleteException("Attempt to use an unsupported format combinaton!");
    break;

default:
    throw FramebufferIncompleteException("Unknown error while attempting to create frame buffer object!");
    break;
}

РЕДАКТИРОВАТЬ 2: Это метод, который я использую для проверки GL-ошибок

checkForGLErrors(string sourceFile, int line)
    GLenum error = glGetError();
    ostringstream o;

    switch(error) {
        case GL_NO_ERROR:
            return;
            break;

        case GL_INVALID_ENUM:
            o<<"OpenGL Error in "<

15
задан Walter 25 November 2010 в 07:01
поделиться