00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00027 #include "renderstack/render_target.hpp"
00028 #include "renderstack/window.hpp"
00029 #include "renderstack/rs_gl.h"
00030 #include "renderstack/rs_log.h"
00031
00032 namespace renderstack {
00033
00034 render_target::render_target()
00035 : m_width(0)
00036 , m_height(0)
00037 , m_gl_framebuffer_object((unsigned int)(~0))
00038 {
00039 }
00040
00041 render_target::render_target(
00042 int width,
00043 int height,
00044 int gl_framebuffer_object
00045 )
00046 : m_width(width)
00047 , m_height(height)
00048 , m_gl_framebuffer_object(gl_framebuffer_object)
00049 {
00050 m_gl_framebuffer_object = 0;
00051
00052 framebuffer_attachment attachment(GL_BACK_LEFT, attachment_renderbuffer);
00053
00054 attachment.renderbuffer().set(0);
00055 }
00056
00057 render_target::render_target(
00058 int width,
00059 int height
00060 )
00061 : m_width(width)
00062 , m_height(height)
00063 , m_gl_framebuffer_object((unsigned int)(~0))
00064 {
00065 ::GLboolean res = ::rs_gl_is_framebuffer(m_gl_framebuffer_object);
00066 if(res != GL_FALSE)
00067 {
00068 ::rs_gl_delete_framebuffers(1, &m_gl_framebuffer_object);
00069 }
00070 ::rs_gl_gen_framebuffers(1, &m_gl_framebuffer_object);
00071
00072 ::rs_gl_bind_framebuffer(
00073 GL_FRAMEBUFFER,
00074 m_gl_framebuffer_object
00075 );
00076 }
00077
00078 default_render_target::default_render_target(int width, int height)
00079 : render_target(width, height, 0)
00080 {
00081 }
00082
00083 default_render_target::default_render_target(class window const &window)
00084 : render_target(
00085 window.client_area().width(),
00086 window.client_area().height(),
00087 0
00088 )
00089 {
00090 }
00091
00092 void render_target::check() const
00093 {
00094 ::GLenum status = ::rs_gl_check_framebuffer_status(GL_FRAMEBUFFER);
00095
00096 if(status == GL_FRAMEBUFFER_COMPLETE)
00097 {
00098 return;
00099 }
00100
00101 ::rs_log("framebuffer not complete: %s\n", ::rs_gl_enum_string(status));
00102 }
00103
00104 framebuffer_attachment &render_target::attach_texture(int gl_attachment, int gl_format)
00105 {
00106 framebuffer_attachment attachment(gl_attachment, attachment_texture);
00107 attachment.texture().set(
00108 m_width,
00109 m_height,
00110 GL_TEXTURE_2D,
00111 GL_TEXTURE_2D,
00112 GL_NEAREST,
00113 GL_NEAREST,
00114 GL_CLAMP_TO_EDGE,
00115 gl_format
00116 );
00117
00118 attachment.texture().update();
00119
00120 rs_gl_bind_framebuffer(
00121 GL_FRAMEBUFFER,
00122 m_gl_framebuffer_object
00123 );
00124
00125 rs_gl_framebuffer_texture_2d(
00126 GL_FRAMEBUFFER,
00127 attachment.gl_attachment_point(),
00128 attachment.texture().gl_teximage_target(),
00129 attachment.texture().gl_texture_object(),
00130 0
00131 );
00132
00133 m_attachments.push_back(attachment);
00134
00135 return m_attachments.back();
00136 }
00137
00138 framebuffer_attachment &render_target::attach_renderbuffer(
00139 int gl_attachment,
00140 int gl_format,
00141 int sample_count
00142 )
00143 {
00144 framebuffer_attachment attachment(gl_attachment, attachment_renderbuffer);
00145
00146 attachment.renderbuffer().set(m_width, m_height, gl_format, sample_count);
00147
00148 ::rs_gl_bind_framebuffer(
00149 GL_FRAMEBUFFER,
00150 m_gl_framebuffer_object
00151 );
00152
00153 ::rs_gl_framebuffer_renderbuffer(
00154 GL_FRAMEBUFFER,
00155 attachment.gl_attachment_point(),
00156 GL_RENDERBUFFER,
00157 attachment.renderbuffer().gl_renderbuffer_object()
00158 );
00159
00160 m_attachments.push_back(attachment);
00161
00162 check();
00163
00164 return m_attachments.back();
00165 }
00166
00167
00168 void render_target::resize(int width, int height)
00169 {
00170 m_width = width;
00171 m_height = height;
00172 }
00173
00174
00175 void render_target::begin() const
00176 {
00177 ::rs_gl_bind_framebuffer(
00178 GL_FRAMEBUFFER,
00179 m_gl_framebuffer_object
00180 );
00181 }
00182
00183 void render_target::end() const
00184 {
00185 ::rs_gl_bind_framebuffer(GL_FRAMEBUFFER, 0);
00186 }
00187
00188 void render_target::blit(render_target const &dst) const
00189 {
00190 ::rs_gl_bind_framebuffer(GL_READ_FRAMEBUFFER, gl_framebuffer_object());
00191 ::rs_gl_bind_framebuffer(GL_DRAW_FRAMEBUFFER, dst.gl_framebuffer_object());
00192
00193 ::rs_gl_blit_framebuffer(
00194 0,
00195 0,
00196 width(),
00197 height(),
00198 0,
00199 0,
00200 dst.width(),
00201 dst.height(),
00202 GL_COLOR_BUFFER_BIT,
00203 GL_NEAREST
00204 );
00205 }
00206
00207 void render_target::debug() const
00208 {
00209 int framebuffer = GL_DRAW_FRAMEBUFFER;
00210 int color_attachment = GL_COLOR_ATTACHMENT0;
00211 int depth_attachment = GL_DEPTH_ATTACHMENT;
00212 int stencil_attachment = GL_STENCIL_ATTACHMENT;
00213
00214 {
00215 int params[4];
00216
00217 ::rs_gl_get_framebuffer_attachment_parameter_iv(
00218 framebuffer,
00219 color_attachment,
00220 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
00221 ¶ms[0]
00222 );
00223 ::rs_log(
00224 "color attachment object type = %s\n",
00225 ::rs_gl_enum_string(params[0])
00226 );
00227
00228 ::rs_gl_get_framebuffer_attachment_parameter_iv(
00229 framebuffer,
00230 color_attachment,
00231 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
00232 ¶ms[0]
00233 );
00234 ::rs_log("color attachment object name = %d\n", params[0]);
00235
00236 ::rs_gl_get_framebuffer_attachment_parameter_iv(
00237 framebuffer,
00238 color_attachment,
00239 GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE,
00240 ¶ms[0]
00241 );
00242 ::rs_log(
00243 "color attachment component type = %s\n",
00244 ::rs_gl_enum_string(params[0])
00245 );
00246
00247 ::rs_gl_get_framebuffer_attachment_parameter_iv(
00248 framebuffer,
00249 color_attachment,
00250 GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING,
00251 ¶ms[0]
00252 );
00253 ::rs_log(
00254 "color attachment color encoding type = %s\n",
00255 ::rs_gl_enum_string(params[0])
00256 );
00257
00258 ::rs_gl_get_framebuffer_attachment_parameter_iv(
00259 framebuffer,
00260 color_attachment,
00261 GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE,
00262 ¶ms[0]
00263 );
00264 ::rs_log(
00265 "color attachment red size = %d\n",
00266 params[0]
00267 );
00268
00269 ::rs_gl_get_framebuffer_attachment_parameter_iv(
00270 framebuffer,
00271 color_attachment,
00272 GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE,
00273 ¶ms[0]
00274 );
00275 ::rs_log(
00276 "color attachment green size = %d\n",
00277 params[0]
00278 );
00279
00280 ::rs_gl_get_framebuffer_attachment_parameter_iv(
00281 framebuffer,
00282 color_attachment,
00283 GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE,
00284 ¶ms[0]
00285 );
00286 ::rs_log(
00287 "color attachment blue size = %d\n",
00288 params[0]
00289 );
00290
00291 ::rs_gl_get_framebuffer_attachment_parameter_iv(
00292 framebuffer,
00293 color_attachment,
00294 GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE,
00295 ¶ms[0]
00296 );
00297 ::rs_log(
00298 "color attachment alpha size = %d\n",
00299 params[0]
00300 );
00301
00302 ::rs_gl_get_framebuffer_attachment_parameter_iv(
00303 framebuffer,
00304 depth_attachment,
00305 GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE,
00306 ¶ms[0]
00307 );
00308 ::rs_log(
00309 "depth attachment depth size = %d\n",
00310 params[0]
00311 );
00312
00313 ::rs_gl_get_framebuffer_attachment_parameter_iv(
00314 framebuffer,
00315 stencil_attachment,
00316 GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE,
00317 ¶ms[0]
00318 );
00319 ::rs_log(
00320 "stencil attachment stencil size = %d\n",
00321 params[0]
00322 );
00323 }
00324 }
00325
00326 }
00327