2012-01-04 3 views
3

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

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); 
} 
+0

Является ли ваше FBO [полным] (http://www.opengl.org/wiki/Framebuffer_Object#Framebuffer_Completeness)? Кажется, вы не вызываете 'glCheckFramebufferStatus()'. – genpfault

+0

Да, вернулся с GL_FRAMEBUFFER_COMPLETE_EXT. – rcapote

ответ

3

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

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

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

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

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

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

2

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

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

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

1

Как я и предполагал, проблема заключалась в установке 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(); 
} 
+0

В коде, который я опубликовал выше, я возвращаю Матричный режим обратно к его нормальным настройкам вручную. Есть ли способ сделать это, нажав/нажав на стек? Я пробовал glPushMatrix/glPopMatrix, но это, похоже, не работало, как я ожидал бы. – rcapote

+2

'glPushAttrib' с' GL_TRANSFORM_BIT' сохранит матричный режим вместе с каким-то другим состоянием. Проверьте документацию для деталей. – 01d55

Смежные вопросы