18bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling#include "FrameBuffer.h"
28bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling
38bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha HaeberlingFrameBuffer::FrameBuffer()
48bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling{
58bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    Reset();
68bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling}
78bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling
88bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha HaeberlingFrameBuffer::~FrameBuffer() {
98bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling}
108bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling
118bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberlingvoid FrameBuffer::Reset() {
128bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    mFrameBufferName = -1;
138bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    mTextureName = -1;
148bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    mWidth = 0;
158bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    mHeight = 0;
168bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    mFormat = -1;
178bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling}
188bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling
198bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberlingbool FrameBuffer::InitializeGLContext() {
208bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    Reset();
218bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    return CreateBuffers();
228bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling}
238bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling
248bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberlingbool FrameBuffer::Init(int width, int height, GLenum format) {
258bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    if (mFrameBufferName == (GLuint)-1) {
268bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling        if (!CreateBuffers()) {
278bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling            return false;
288bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling        }
298bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    }
308bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferName);
318bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    glBindTexture(GL_TEXTURE_2D, mTextureName);
328bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling
338bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    glTexImage2D(GL_TEXTURE_2D,
348bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling                 0,
358bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling                 format,
368bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling                 width,
378bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling                 height,
388bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling                 0,
398bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling                 format,
408bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling                 GL_UNSIGNED_BYTE,
418bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling                 NULL);
428bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    if (!checkGlError("bind/teximage")) {
438bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling        return false;
448bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    }
458bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
468bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
478bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    // This is necessary to work with user-generated frame buffers with
488bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    // dimensions that are NOT powers of 2.
498bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
508bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
518bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling
528bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    // Attach texture to frame buffer.
538bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    glFramebufferTexture2D(GL_FRAMEBUFFER,
548bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling                           GL_COLOR_ATTACHMENT0,
558bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling                           GL_TEXTURE_2D,
568bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling                           mTextureName,
578bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling                           0);
588bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    checkFramebufferStatus("FrameBuffer.cpp");
598bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    checkGlError("framebuffertexture2d");
608bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling
618bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    if (!checkGlError("texture setup")) {
628bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling        return false;
638bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    }
648bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    mWidth = width;
658bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    mHeight = height;
668bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    mFormat = format;
678bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    glBindFramebuffer(GL_FRAMEBUFFER, 0);
688bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    return true;
698bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling}
708bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling
718bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberlingbool FrameBuffer::CreateBuffers() {
728bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    glGenFramebuffers(1, &mFrameBufferName);
738bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    glGenTextures(1, &mTextureName);
748bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    if (!checkGlError("texture generation")) {
758bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling        return false;
768bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    }
778bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    return true;
788bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling}
798bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling
808bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha HaeberlingGLuint FrameBuffer::GetTextureName() const {
818bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    return mTextureName;
828bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling}
838bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling
848bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha HaeberlingGLuint FrameBuffer::GetFrameBufferName() const {
858bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    return mFrameBufferName;
868bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling}
878bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling
888bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha HaeberlingGLenum FrameBuffer::GetFormat() const {
898bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    return mFormat;
908bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling}
918bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling
928bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberlingint FrameBuffer::GetWidth() const {
938bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    return mWidth;
948bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling}
958bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling
968bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberlingint FrameBuffer::GetHeight() const {
978bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling    return mHeight;
988bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling}
99