Рендерится с текстурами - PullRequest
3 голосов
/ 05 января 2012

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

    target->enable();

    glBegin(GL_QUADS);

    glColor4f(1.f, 0.f, 0.f, 1.f);
    glVertex3f(0.f, 0.f, 0.f);

    glColor4f(0.f, 1.f, 0.f, 1.f);
    glVertex3f(16.f, 0.f, 0.f);

    glColor4f(0.f, 0.f, 1.f, 1.f);
    glVertex3f(0.f, 16.f, 0.f);

    glColor4f(1.f, 1.f, 0.f, 1.f);
    glVertex3f(16.f, 16.f, 0.f);

    glEnd();

    target->disable();

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

RenderTarget::RenderTarget(GraphicsDevice *graphics, GLuint width, GLuint height) {

    mWidth = width;
    mHeight = height;

    // First create the depth buffer
    glGenRenderbuffers(1, &mDepth);
    glBindRenderbuffer(GL_RENDERBUFFER_EXT, mDepth);

    // Tell OpenGL that this renderbuffer is going to be a depth buffer
    glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, mWidth, mHeight);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth);

    glBindRenderbuffer(GL_RENDERBUFFER_EXT, 0);

    // Create the frame buffer texture
    glGenTextures(1, &mTexture);
    glBindTexture(GL_TEXTURE_2D, mTexture);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mWidth, mHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    glBindTexture(GL_TEXTURE_2D, 0);

    // Create the frame buffer
    glGenFramebuffers(1, &mFbo);
    glBindFramebuffer(GL_FRAMEBUFFER_EXT, mFbo);

    // Attach the texture
    glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, mTexture, 0);

    //Attach the depth buffer
    glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mFbo);

    glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);


}

RenderTarget::~RenderTarget() {
    glDeleteBuffers(1, &mFbo);
    glDeleteBuffers(1, &mDepth);
    glDeleteTextures(1, &mTexture);
    mFbo = 0;
    mDepth = 0;
    mTexture = 0;
}

void RenderTarget::enable() {
    // Bind the frame buffer
    glBindFramebuffer(GL_FRAMEBUFFER_EXT, mFbo);
    // store the glViewport and glEnable states
    //glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT);

    glClearColor(1.f, 0.f, 0.f, 1.f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(0.f, 0.f, 0.f, 0.f);

    glLoadIdentity();
}

void RenderTarget::disable() {
    // Restore glViewport and glEnable states
    glPopAttrib();
    glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
}

Ответы [ 3 ]

3 голосов
/ 05 января 2012

Ваше разрешение сбрасывает текущую матрицу (наиболее вероятный вид модели) с glLoadIdentity.Это объясняет, почему ваш квадрат перемещается в угол экрана.

Вы закомментировали вызов glPushAttrib, но не соответствующий вызов glPopAttrib.Если вы не используете glPushAttrib где-либо еще, это должно установить флаг ошибки и оставить состояние GL в покое, но я не знаю, так ли это, и возникает проблема с предположением, что стек атрибутов всегда есть и будет пустым.

Эта документация для glBindFrameBuffer предполагает, что вы должны использовать GL_FRAMEBUFFER или GL_DRAW_FRAMEBUFFER в качестве первого аргумента:

target должен быть либо GL_DRAW_FRAMEBUFFER, GL_READ_FRAMEBUFFER или GL_FRAMEBUFFER.Если объект кадрового буфера привязан к GL_DRAW_FRAMEBUFFER или GL_READ_FRAMEBUFFER, он становится целью операций рендеринга или чтения, соответственно, до тех пор, пока он не будет удален или другой кадровый буфер не будет привязан к соответствующей точке привязки.Вызов glBindFramebuffer с целью, установленной в GL_FRAMEBUFFER, связывает framebuffer с целями чтения и рисования кадрового буфера.

Перечисления с суффиксом _EXT в вашем коде, вероятно, относятся к версии OpenGL, предшествующей версиизадокументировано там.В учебных руководствах допускается устаревание таких деталей, как эта.

Проверьте свою среду и полагайтесь на документацию, соответствующую вашей версии OpenGL.Если по какой-то причине вы не можете легко определить свою версию OpenGL, проверьте наличие ошибки GL_INVALID_ENUM после вызова glBindFrameBuffer.

2 голосов
/ 05 января 2012

Код кажется неправильным:

//Attach the depth buffer
glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mFbo);

Что вы делаете здесь, так это то, что вы пытаетесь присоединить mFbo в качестве буфера рендеринга к mFbo. Однако ваш буфер рендеринга уже подключен правильно (что делается при первом вызове glFramebufferRenderbuffer ()). Я думаю, что удаление этого кода должно решить вашу проблему.

1 голос
/ 05 января 2012

Как я и подозревал, моей проблемой была правильная настройка glViewport и glOrtho при рендеринге FBO.Этот код нужно очистить, но вот как я это исправил.

void RenderTarget::enable() {
    // Bind the frame buffer

    glBindFramebuffer(GL_FRAMEBUFFER_EXT, mFbo);
    // store the glViewport and glEnable states
    //glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT);

    glViewport(0, 0, mWidth, mHeight);
    // projection matrix
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    // orthographic projection
    glOrtho(0, mWidth, 0, mHeight, -1, 1);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glClearColor(1.f, 0.f, 0.f, 1.f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(0.f, 0.f, 0.f, 0.f);

    glLoadIdentity();
}

void RenderTarget::disable() {
    // Restore glViewport and glEnable states
    //glPopAttrib();
    glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
    glViewport(0, 0, 1024, 768);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    // orthographic projection
    glOrtho(0, 1024, 768, 0, -1, 1);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}
...