Попытка рендеринга в текстуру с использованием кадрового буфера всегда приводит к белой текстуре - PullRequest
3 голосов
/ 23 декабря 2009

Используя пару постов здесь, в StackOverflow, я создал то, что должно быть простым рендерингом в текстуру с использованием кадрового буфера.

Проблема в том, что он не работает. Что-то сломано в миксе, так как моя последняя текстура - просто белый квадрат. Я не получаю никаких ошибок GL вообще. Вот мой код.

Объявление переменных экземпляра.

GLuint texture;
GLuint textureFrameBuffer;

Создание текстуры и кадрового буфера.

    glGetError();

    //Generate the texture that we will draw to (saves us a lot of processor).
    glEnable(GL_TEXTURE_2D);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    // Use OpenGL ES to generate a name for the texture.
    // Pass by reference so that our texture variable gets set.
    glGenTextures(1, &texture);

    // Bind the texture name. 
    glBindTexture(GL_TEXTURE_2D, texture);

    // Specify a 2D texture image, providing a pointer to the image data in memory.
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

    //Create a frame buffer to draw to. This will allow us to directly edit the texture.
    GLint oldFBO;
    glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &oldFBO);
    glGenFramebuffersOES(1, &textureFrameBuffer);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, textureFrameBuffer);
    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, texture, 0);

    glBindFramebufferOES(GL_FRAMEBUFFER_OES, oldFBO);

    GLenum err = glGetError();
    if (err != GL_NO_ERROR)
    {
        NSLog(@"Error on framebuffer init. glError: 0x%04X", err);
    }

Нарисуйте большую строку в буфере кадров.

glGetError();

GLint oldFBO;
glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &oldFBO);

//Bind our frame buffer.
glBindFramebufferOES(GL_FRAMEBUFFER_OES, textureFrameBuffer);

//Clear out the texture.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

//Draw the letters to the frame buffer. (calls glDrawArrays a bunch of times, binds various textures, etc.) Does everything in 2D.
[self renderDialog:displayString withSprite:displaySprite withName:displaySpriteName];

//Unbind the frame buffer.
glBindFramebufferOES(GL_FRAMEBUFFER_OES, oldFBO);

GLenum err = glGetError();
if (err != GL_NO_ERROR)
{
    NSLog(@"Error on string creation. glError: 0x%04X", err);
}

Нарисуй.

    glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

    glGetError();

    //Draw the text.
    [EAGLView enable2D];

    //Push the matrix so we can keep it as it was previously.
    glPushMatrix();

    //Store the coordinates/dimensions from the rectangle.
    float x = 0;
    float y = [Globals getPlayableHeight] - dialogRect.size.height;
    float w = [Globals getPlayableWidth];
    float h = dialogRect.size.height;

    // Set up an array of values to use as the sprite vertices.
    GLfloat vertices[] =
    {
        x,      y,
        x,      y+h,
        x+w,    y+h,
        x+w,    y
    };

    // Set up an array of values for the texture coordinates.
    GLfloat texcoords[] =
    {
        0,          0,
        0,          h / 128,
        w / 512,    h / 128,
        w / 512,    0
    };

    //Render the vertices by pointing to the arrays.
    glVertexPointer(2, GL_FLOAT, 0, vertices);
    glTexCoordPointer(2, GL_FLOAT, 0, texcoords);

    // Set the texture parameters to use a linear filter when minifying.
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    //Allow transparency and blending.
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    //Enable 2D textures.
    glEnable(GL_TEXTURE_2D);

    //Bind this texture.
    [EAGLView bindTexture:texture];

    //Finally draw the arrays.
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

    //Restore the model view matrix to prevent contamination.
    glPopMatrix();

    GLenum err = glGetError();
    if (err != GL_NO_ERROR)
    {
        NSLog(@"Error on draw. glError: 0x%04X", err);
    }

Любые внешние вещи, которые я назвал, прекрасно работают в других контекстах. Есть идеи? Я почти ничего не знаю о кадровых буферах, поэтому любая помощь в устранении неполадок была бы полезна.

1 Ответ

4 голосов
/ 23 декабря 2009

Параметры текстуры устанавливаются для каждой текстуры. Код, который вы разместили, кажется, устанавливает GL_TEXTURE_MIN_FILTER до того, как текстура, на которую вы рендерится, будет создана или привязана. Если вы не устанавливаете фильтр где-либо еще и не указали текстурные изображения для оставшихся уровней, скорее всего, ваша текстура неполная, поэтому вы получаете белый цвет.

Для дальнейшего использования отсутствие ошибок GL после настройки кадрового буфера не означает, что кадровый буфер можно использовать для рендеринга. Вы также должны проверить, что кадровый буфер завершен, вызвав glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) и проверив, что GL_FRAMEBUFFER_COMPLETE_OES возвращено.

...