1eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#include "FrameBuffer.h"
2eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
3eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalFrameBuffer::FrameBuffer()
4eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{
5eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    Reset();
6eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}
7eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
8eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalFrameBuffer::~FrameBuffer() {
9eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}
10eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
11eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalvoid FrameBuffer::Reset() {
12eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    mFrameBufferName = -1;
13eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    mTextureName = -1;
14eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    mWidth = 0;
15eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    mHeight = 0;
16eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    mFormat = -1;
17eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}
18eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
19eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalbool FrameBuffer::InitializeGLContext() {
20eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    Reset();
21eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    return CreateBuffers();
22eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}
23eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
24eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalbool FrameBuffer::Init(int width, int height, GLenum format) {
25eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    if (mFrameBufferName == (GLuint)-1) {
26eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        if (!CreateBuffers()) {
27eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            return false;
28eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        }
29eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    }
30eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferName);
31eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    glBindTexture(GL_TEXTURE_2D, mTextureName);
32eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
33eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    glTexImage2D(GL_TEXTURE_2D,
34eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                 0,
35eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                 format,
36eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                 width,
37eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                 height,
38eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                 0,
39eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                 format,
40eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                 GL_UNSIGNED_BYTE,
41eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                 NULL);
42eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    if (!checkGlError("bind/teximage")) {
43eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        return false;
44eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    }
45eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
46eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
47eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    // This is necessary to work with user-generated frame buffers with
48eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    // dimensions that are NOT powers of 2.
49eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
50eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
51eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
52eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    // Attach texture to frame buffer.
53eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    glFramebufferTexture2D(GL_FRAMEBUFFER,
54eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                           GL_COLOR_ATTACHMENT0,
55eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                           GL_TEXTURE_2D,
56eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                           mTextureName,
57eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal                           0);
584fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong    checkFramebufferStatus("FrameBuffer.cpp");
594fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong    checkGlError("framebuffertexture2d");
60eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
61eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    if (!checkGlError("texture setup")) {
62eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        return false;
63eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    }
64eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    mWidth = width;
65eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    mHeight = height;
66eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    mFormat = format;
67eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    glBindFramebuffer(GL_FRAMEBUFFER, 0);
68eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    return true;
69eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}
70eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
71eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalbool FrameBuffer::CreateBuffers() {
72eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    glGenFramebuffers(1, &mFrameBufferName);
73eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    glGenTextures(1, &mTextureName);
74eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    if (!checkGlError("texture generation")) {
75eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        return false;
76eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    }
77eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    return true;
78eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}
79eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
80eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalGLuint FrameBuffer::GetTextureName() const {
81eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    return mTextureName;
82eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}
83eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
84eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalGLuint FrameBuffer::GetFrameBufferName() const {
85eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    return mFrameBufferName;
86eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}
87eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
88eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalGLenum FrameBuffer::GetFormat() const {
89eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    return mFormat;
90eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}
91eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
92eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalint FrameBuffer::GetWidth() const {
93eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    return mWidth;
94eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}
95eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
96eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalint FrameBuffer::GetHeight() const {
97eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    return mHeight;
98eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}
99