00001 #include "gui_gl_rendertarget.hpp"
00002 #include "gui_gl_manager.hpp"
00003
00004 #include <GL/glew.h>
00005 #include <GL/gl.h>
00006
00007 #include <iostream>
00008
00009 namespace gui {
00010 namespace gl
00011 {
00012 render_target::render_target(uint uiWidth, uint uiHeight) :
00013 uiFBOHandle_(0), bUpdateViewMatrix_(true)
00014 {
00015 pTexture_ = utils::refptr<gl::material>(new gl::material(
00016 uiWidth, uiHeight, gl::material::REPEAT, gl::material::NONE, true
00017 ));
00018
00019 glGenFramebuffers(1, &uiFBOHandle_);
00020 glBindFramebuffer(GL_FRAMEBUFFER, uiFBOHandle_);
00021 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pTexture_->get_handle_(), 0);
00022
00023 if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)
00024 {
00025 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
00026 throw gui::exception("render_target", "Failed creating render target.");
00027 }
00028
00029 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
00030 }
00031
00032 render_target::~render_target()
00033 {
00034 if (uiFBOHandle_ != 0)
00035 glDeleteFramebuffers(1, &uiFBOHandle_);
00036 }
00037
00038 void render_target::begin()
00039 {
00040 if (bUpdateViewMatrix_)
00041 update_view_matrix_();
00042
00043 glBindFramebuffer(GL_FRAMEBUFFER, uiFBOHandle_);
00044
00045 glViewport(0.0f, 0.0f, pTexture_->get_real_width(), pTexture_->get_real_height());
00046 glDisable(GL_DEPTH_TEST);
00047 glEnable(GL_BLEND);
00048 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
00049 glDisable(GL_LIGHTING);
00050 glDisable(GL_ALPHA_TEST);
00051 glDisable(GL_CULL_FACE);
00052
00053 glMatrixMode(GL_PROJECTION);
00054 glLoadMatrixf(reinterpret_cast<float*>(&mViewMatrix_));
00055
00056 glMatrixMode(GL_MODELVIEW);
00057 glLoadIdentity();
00058 }
00059
00060 void render_target::update_view_matrix_() const
00061 {
00062 float fWidth = pTexture_->get_real_width();
00063 float fHeight = pTexture_->get_real_height();
00064
00065 mViewMatrix_ = {
00066 2.0f/fWidth, 0.0f, -1.0f, -1.0f,
00067 0.0f, 2.0f/fHeight, -1.0f, -1.0f,
00068 0.0f, 0.0f, 1.0f, 0.0f,
00069 0.0f, 0.0f, 0.0f, 1.0f
00070 };
00071
00072 bUpdateViewMatrix_ = false;
00073 }
00074
00075 void render_target::end()
00076 {
00077 glBindFramebuffer(GL_FRAMEBUFFER, 0);
00078 }
00079
00080 void render_target::clear(const color& mColor)
00081 {
00082 glClearColor(mColor.r, mColor.g, mColor.b, mColor.a);
00083 glClear(GL_COLOR_BUFFER_BIT);
00084 }
00085
00086 uint render_target::get_width() const
00087 {
00088 return pTexture_->get_width();
00089 }
00090
00091 uint render_target::get_height() const
00092 {
00093 return pTexture_->get_height();
00094 }
00095
00096 uint render_target::get_real_width() const
00097 {
00098 return pTexture_->get_real_width();
00099 }
00100
00101 uint render_target::get_real_height() const
00102 {
00103 return pTexture_->get_real_height();
00104 }
00105
00106 bool render_target::set_dimensions(uint uiWidth, uint uiHeight)
00107 {
00108 bUpdateViewMatrix_ = true;
00109
00110 if (pTexture_->set_dimensions(uiWidth, uiHeight))
00111 {
00112 glBindFramebuffer(GL_FRAMEBUFFER, uiFBOHandle_);
00113 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pTexture_->get_handle_(), 0);
00114
00115 if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)
00116 {
00117 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
00118 throw gui::exception("render_target", "Failed resizing render target.");
00119 }
00120
00121 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
00122
00123 return true;
00124 }
00125
00126 return false;
00127 }
00128
00129 utils::wptr<gl::material> render_target::get_material()
00130 {
00131 return pTexture_;
00132 }
00133
00134 void render_target::check_availability()
00135 {
00136 if (!manager::is_gl_extension_supported("GL_EXT_framebuffer_object"))
00137 {
00138 throw gui::exception("render_target", "OpenGL extenion "
00139 "'GL_EXT_framebuffer_object' is not supported by your hardware.");
00140 }
00141 }
00142 }
00143 }