Visualization Library 2.0.0

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
Framebuffer Objects Tutorial

This tutorial shows how to use framebuffer objects to perform offscreen rendering.

Visualization Library uses the following classes to implement framebuffer objects and framebuffer attachments:

[From App_Framebuffer_Object.cpp]

class App_Framebuffer_Object: public BaseDemo
{
static const int mFBO_Size = 1024;
public:
App_Framebuffer_Object(int test): mTestNum(test) {}
/*
This example demonstates the use of the render-to-texture (RTT) technique using framebuffer objects.
*/
void initTest_FBO_Render_To_Texture()
{
// Setup dual rendering
setRendering(render_tree.get());
mMainRendering = new vl::Rendering;
mRTT_Rendering = new vl::Rendering;
render_tree->subRenderings()->push_back(mRTT_Rendering.get());
render_tree->subRenderings()->push_back(mMainRendering.get());
mMainRendering->sceneManagers()->push_back(new vl::SceneManagerActorTree);
mRTT_Rendering->sceneManagers()->push_back(new vl::SceneManagerActorTree);
// RTT rendering
mRTT_Rendering->camera()->viewport()->setClearColor( vl::crimson );
mRTT_Rendering->camera()->viewport()->set(0, 0, mFBO_Size, mFBO_Size);
mRTT_Rendering->camera()->setProjectionPerspective();
vl::mat4 m = vl::mat4::getLookAt(vl::vec3(0,0,10.5f), vl::vec3(0,0,0), vl::vec3(0,1,0));
mRTT_Rendering->camera()->setViewMatrix(m);
/* use a framebuffer object as render target */
vl::ref<vl::FramebufferObject> framebuffer_object = openglContext()->createFramebufferObject(mFBO_Size, mFBO_Size);
mRTT_Rendering->renderer()->setFramebuffer( framebuffer_object.get() );
/* bind a depth buffer */
framebuffer_object->addDepthAttachment( fbo_depth_attachm.get() );
/* use texture as color buffer */
vl::ref<vl::Texture> texture = new vl::Texture(mFBO_Size, mFBO_Size, vl::TF_RGBA);
framebuffer_object->addTextureAttachment( vl::AP_COLOR_ATTACHMENT0, fbo_tex_attachm.get() );
framebuffer_object->setDrawBuffer( vl::RDB_COLOR_ATTACHMENT0 );
// Main rendering
/* setup camera */
mMainRendering->camera()->viewport()->setClearColor( vl::midnightblue );
mMainRendering->camera()->viewport()->set(0, 0, openglContext()->framebuffer()->width(), openglContext()->framebuffer()->height());
m = vl::mat4::getLookAt(vl::vec3(0,15,25), vl::vec3(0,0,0), vl::vec3(0,1,0));
mMainRendering->camera()->setViewMatrix(m);
/* use the opengl window as render target */
mMainRendering->renderer()->setFramebuffer( openglContext()->framebuffer() );
/* populate the scene */
addRings(NULL);
addCube(texture.get(), NULL);
}
/*
This example demonstates the use of the multiple-render-target tecnique to render on two textures simultaneously.
*/
void initTest_FBO_Render_To_Texture_MRT()
{
{
vl::Log::error("This test requires GLSL!\n");
exit(1);
}
// Setup dual rendering
setRendering(render_tree.get());
mMainRendering = new vl::Rendering;
mRTT_Rendering = new vl::Rendering;
render_tree->subRenderings()->push_back(mRTT_Rendering.get());
render_tree->subRenderings()->push_back(mMainRendering.get());
mMainRendering->sceneManagers()->push_back(new vl::SceneManagerActorTree);
mRTT_Rendering->sceneManagers()->push_back(new vl::SceneManagerActorTree);
// RTT rendering
mRTT_Rendering->camera()->viewport()->setClearColor( vl::crimson );
mRTT_Rendering->camera()->viewport()->set(0, 0, mFBO_Size, mFBO_Size);
mRTT_Rendering->camera()->setProjectionPerspective();
vl::mat4 m = vl::mat4::getLookAt(vl::vec3(0,0,10.5f), vl::vec3(0,0,0), vl::vec3(0,1,0));
mRTT_Rendering->camera()->setViewMatrix(m);
/* use a framebuffer object as render target */
vl::ref<vl::FramebufferObject> framebuffer_object = openglContext()->createFramebufferObject(mFBO_Size, mFBO_Size);
mRTT_Rendering->renderer()->setFramebuffer( framebuffer_object.get() );
/* bind a depth buffer */
framebuffer_object->addDepthAttachment( fbo_depth_attachm.get() );
/* use a per-pixel-light GLSL shader which renders on two color attachments at the same time */
glsl->attachShader( new vl::GLSLVertexShader("/glsl/perpixellight.vs") );
if (vl::Has_GL_EXT_gpu_shader4||vl::Has_GL_Version_3_0||vl::Has_GL_Version_4_0)
{
vl::Log::notify("using glBindFragDataLocation()\n");
// see fragment shader sources for the details
glsl->attachShader( new vl::GLSLFragmentShader("/glsl/perpixellight_cartoon_mrt2.fs") );
glsl->bindFragDataLocation(0, "FragDataOutputA"); // out varying variable writing on color attachment #0
glsl->bindFragDataLocation(1, "FragDataOutputB"); // out varying variable writing on color attachment #1
}
else
{
vl::Log::notify("glBindFragDataLocation() not supported.\n");
// see fragment shader sources for the details
glsl->attachShader( new vl::GLSLFragmentShader("/glsl/perpixellight_cartoon_mrt.fs") );
}
/* use two textures as color attachment #0 and #1 */
vl::ref<vl::Texture> texture1 = new vl::Texture(mFBO_Size, mFBO_Size, vl::TF_RGBA);
vl::ref<vl::Texture> texture2 = new vl::Texture(mFBO_Size, mFBO_Size, vl::TF_RGBA);
framebuffer_object->addTextureAttachment( vl::AP_COLOR_ATTACHMENT0, fbo_tex_attachm1.get() );
framebuffer_object->addTextureAttachment( vl::AP_COLOR_ATTACHMENT1, fbo_tex_attachm2.get() );
/* draw on colorbuffers #0 and #1 */
mRTT_Rendering->renderer()->framebuffer()->setDrawBuffers(vl::RDB_COLOR_ATTACHMENT0, vl::RDB_COLOR_ATTACHMENT1);
/* screen shot grabbing on color attachment #0 */
read_pixels_0->setup( 0, 0, mFBO_Size, mFBO_Size, vl::RDB_COLOR_ATTACHMENT0, false );
mRTT_Rendering->onFinishedCallbacks()->push_back(read_pixels_0.get());
read_pixels_0->setRemoveAfterCall(true);
read_pixels_0->setSavePath("MRT-COLOR_ATTACHMENT0.tif");
/* screen shot grabbing on color attachment #1 */
read_pixels_1->setup( 0, 0, mFBO_Size, mFBO_Size, vl::RDB_COLOR_ATTACHMENT1, false );
mRTT_Rendering->onFinishedCallbacks()->push_back(read_pixels_1.get());
read_pixels_1->setRemoveAfterCall(true);
read_pixels_1->setSavePath("MRT-COLOR_ATTACHMENT1.tif");
// Main rendering
/* setup camera */
mMainRendering->camera()->viewport()->setClearColor( vl::midnightblue );
mMainRendering->camera()->viewport()->set(0, 0, openglContext()->framebuffer()->width(), openglContext()->framebuffer()->height());
m = vl::mat4::getLookAt(vl::vec3(0,15,25), vl::vec3(0,0,0), vl::vec3(0,1,0));
mMainRendering->camera()->setViewMatrix(m);
/* use the opengl window as render target */
mMainRendering->renderer()->setFramebuffer( openglContext()->framebuffer() );
/* populate the scene */
addRings(glsl.get());
addCube(texture1.get(), texture2.get() );
}
/*
This example shows how to perform off-screen rendering on a color buffer.
The content of the colorbuffer is then copied to a texture using CopyTexSubImage2D.
*/
void initTest_FBO_Render_To_Color_Buffer_And_Copy_To_Texture()
{
// Setup dual rendering
setRendering(render_tree.get());
mMainRendering = new vl::Rendering;
mRTT_Rendering = new vl::Rendering;
render_tree->subRenderings()->push_back(mRTT_Rendering.get());
render_tree->subRenderings()->push_back(mMainRendering.get());
mMainRendering->sceneManagers()->push_back(new vl::SceneManagerActorTree);
mRTT_Rendering->sceneManagers()->push_back(new vl::SceneManagerActorTree);
// RTT rendering
mRTT_Rendering->camera()->viewport()->setClearColor( vl::crimson );
mRTT_Rendering->camera()->viewport()->set(0, 0, mFBO_Size, mFBO_Size);
mRTT_Rendering->camera()->setProjectionPerspective();
vl::mat4 m = vl::mat4::getLookAt(vl::vec3(0,0,10.5f), vl::vec3(0,0,0), vl::vec3(0,1,0));
mRTT_Rendering->camera()->setViewMatrix(m);
/* use a framebuffer object as render target */
vl::ref<vl::FramebufferObject> framebuffer_object = openglContext()->createFramebufferObject(mFBO_Size, mFBO_Size);
mRTT_Rendering->renderer()->setFramebuffer( framebuffer_object.get() );
/* bind a depth buffer */
framebuffer_object->addDepthAttachment( fbo_depth_attachm.get() );
/* bind a normal color buffer as color attachment #0 */
framebuffer_object->addColorAttachment( vl::AP_COLOR_ATTACHMENT0, fbo_col_buf_attachm.get() );
mRTT_Rendering->renderer()->framebuffer()->setDrawBuffer(vl::RDB_COLOR_ATTACHMENT0);
/* at the end of the rendering copy the color attachment pixels into the texture */
vl::ref<vl::Texture> texture = new vl::Texture(mFBO_Size, mFBO_Size, vl::TF_RGBA, false); // note that mipmapping is off
vl::ref<vl::CopyTexSubImage2D> copytex = new vl::CopyTexSubImage2D(0, 0,0, 0,0, mFBO_Size,mFBO_Size, texture.get(), vl::T2DT_TEXTURE_2D, vl::RDB_COLOR_ATTACHMENT0);
mRTT_Rendering->onFinishedCallbacks()->push_back(copytex.get());
// Main rendering
/* setup camera */
mMainRendering->camera()->viewport()->setClearColor( vl::midnightblue );
mMainRendering->camera()->viewport()->set(0, 0, openglContext()->framebuffer()->width(), openglContext()->framebuffer()->height());
m = vl::mat4::getLookAt(vl::vec3(0,15,25), vl::vec3(0,0,0), vl::vec3(0,1,0));
mMainRendering->camera()->setViewMatrix(m);
/* use the opengl window as render target */
mMainRendering->renderer()->setFramebuffer( openglContext()->framebuffer() );
/* populate the scene */
addRings(NULL);
addCube(texture.get(), NULL);
}
/*
This example shows how to perform off-screen rendering on a multisampled color buffer and then copy
the content of such buffer to a non-multisampled texture using the vl:BlitFramebuffer callback object.
*/
void initTest_FBO_Framebuffer_Blit_Multisample()
{
if (!(vl::Has_GL_EXT_framebuffer_multisample||vl::Has_GL_EXT_framebuffer_blit||vl::Has_GL_Version_3_0||vl::Has_GL_Version_4_0))
{
vl::Log::error("Framebuffer multisample blitting not supported.\n");
exit(1);
}
const int samples = 4;
// Setup dual rendering
setRendering(render_tree.get());
mMainRendering = new vl::Rendering;
mRTT_Rendering = new vl::Rendering;
render_tree->subRenderings()->push_back(mRTT_Rendering.get());
render_tree->subRenderings()->push_back(mMainRendering.get());
mMainRendering->sceneManagers()->push_back(new vl::SceneManagerActorTree);
mRTT_Rendering->sceneManagers()->push_back(new vl::SceneManagerActorTree);
// RTT rendering
mRTT_Rendering->camera()->viewport()->setClearColor( vl::crimson );
mRTT_Rendering->camera()->viewport()->set(0, 0, mFBO_Size, mFBO_Size);
mRTT_Rendering->camera()->setProjectionPerspective();
vl::mat4 m = vl::mat4::getLookAt(vl::vec3(0,0,10.5f), vl::vec3(0,0,0), vl::vec3(0,1,0));
mRTT_Rendering->camera()->setViewMatrix(m);
/* use a framebuffer object as render target */
vl::ref<vl::FramebufferObject> framebuffer_object = openglContext()->createFramebufferObject(mFBO_Size, mFBO_Size);
mRTT_Rendering->renderer()->setFramebuffer( framebuffer_object.get() );
/* bind a multisampled depth buffer */
fbo_depth_attachm->setSamples(samples);
framebuffer_object->addDepthAttachment( fbo_depth_attachm.get() );
/* bind a multisampled color buffer */
fbo_col_buf_attachm->setSamples(samples);
framebuffer_object->addColorAttachment( vl::AP_COLOR_ATTACHMENT0, fbo_col_buf_attachm.get() );
mRTT_Rendering->renderer()->framebuffer()->setDrawBuffer(vl::RDB_COLOR_ATTACHMENT0);
/* create a new FBO with 'texture' as its color attachment */
vl::ref<vl::FramebufferObject> fbo_rt_texture = openglContext()->createFramebufferObject(mFBO_Size, mFBO_Size);
vl::ref<vl::Texture> texture = new vl::Texture(mFBO_Size, mFBO_Size, vl::TF_RGBA);
fbo_rt_texture->addTextureAttachment( vl::AP_COLOR_ATTACHMENT0, fbo_tex_attachm.get() );
/* setup vl::BlitFramebuffer: blits the content of the multisampled color buffer into a non-multisampled texture */
mRTT_Rendering->onFinishedCallbacks()->push_back(blit_fbo.get());
blit_fbo->setLinearFilteringEnabled(false);
//the commented part does not work with multisampling enabled (samples > 0)
//int center = mFBO_Size / 2;
//int side = mFBO_Size / 4;
//blit_fbo->setSrcRect( center-side, center-side, center+side, center+side );
blit_fbo->setSrcRect( 0, 0, mFBO_Size, mFBO_Size );
blit_fbo->setDstRect( 0, 0, mFBO_Size, mFBO_Size );
blit_fbo->setReadFramebuffer( framebuffer_object.get() );
blit_fbo->setDrawFramebuffer( fbo_rt_texture.get() );
// Main rendering
/* setup camera */
mMainRendering->camera()->viewport()->setClearColor( vl::midnightblue );
mMainRendering->camera()->viewport()->set(0, 0, openglContext()->framebuffer()->width(), openglContext()->framebuffer()->height());
m = vl::mat4::getLookAt(vl::vec3(0,15,25), vl::vec3(0,0,0), vl::vec3(0,1,0));
mMainRendering->camera()->setViewMatrix(m);
/* use the opengl window as render target */
mMainRendering->renderer()->setFramebuffer( openglContext()->framebuffer() );
/* populate the scene */
addRings(NULL);
addCube(texture.get(), NULL);
}
/*
This example shows how to perform off-screen rendering directly on a multisample texture.
*/
void initTest_FBO_Multisample_Texture()
{
if (!(vl::Has_GL_ARB_texture_multisample||vl::Has_GL_Version_3_2||vl::Has_GL_Version_4_0))
{
vl::Log::error("Multisample texture not supported.\n");
exit(1);
}
const int samples = 4; // keep updated with tex_multisample.fs
// Setup dual rendering
setRendering(render_tree.get());
mMainRendering = new vl::Rendering;
mRTT_Rendering = new vl::Rendering;
render_tree->subRenderings()->push_back(mRTT_Rendering.get());
render_tree->subRenderings()->push_back(mMainRendering.get());
mMainRendering->sceneManagers()->push_back(new vl::SceneManagerActorTree);
mRTT_Rendering->sceneManagers()->push_back(new vl::SceneManagerActorTree);
// RTT rendering
mRTT_Rendering->camera()->viewport()->setClearColor( vl::crimson );
mRTT_Rendering->camera()->viewport()->set(0, 0, mFBO_Size, mFBO_Size);
mRTT_Rendering->camera()->setProjectionPerspective();
vl::mat4 m = vl::mat4::getLookAt(vl::vec3(0,0,10.5f), vl::vec3(0,0,0), vl::vec3(0,1,0));
mRTT_Rendering->camera()->setViewMatrix(m);
/* use a framebuffer object as render target */
vl::ref<vl::FramebufferObject> framebuffer_object = openglContext()->createFramebufferObject(mFBO_Size, mFBO_Size);
mRTT_Rendering->renderer()->setFramebuffer( framebuffer_object.get() );
/* bind a multisampled depth buffer */
fbo_depth_attachm->setSamples(samples);
framebuffer_object->addDepthAttachment( fbo_depth_attachm.get() );
/* use multisample texture as color buffer */
texture->prepareTexture2DMultisample(mFBO_Size, mFBO_Size, vl::TF_RGBA, samples, true);
texture->createTexture();
framebuffer_object->addTextureAttachment( vl::AP_COLOR_ATTACHMENT0, fbo_tex_attachm.get() );
mRTT_Rendering->renderer()->framebuffer()->setDrawBuffer( vl::RDB_COLOR_ATTACHMENT0 );
// Main rendering
/* setup camera */
mMainRendering->camera()->viewport()->setClearColor( vl::midnightblue );
mMainRendering->camera()->viewport()->set(0, 0, openglContext()->framebuffer()->width(), openglContext()->framebuffer()->height());
m = vl::mat4::getLookAt(vl::vec3(0,15,25), vl::vec3(0,0,0), vl::vec3(0,1,0));
mMainRendering->camera()->setViewMatrix(m);
/* use the opengl window as render target */
mMainRendering->renderer()->setFramebuffer( openglContext()->framebuffer() );
/* populate the scene */
addRings(NULL);
addCube(texture.get(), NULL); // here we use he /glsl/tex_multisample.fs to perform the texel fetch.
}
/*
This example demonstrates how to perform render-to-texture without using framebuffer objects.
First the scene with the ring is rendered normally on the screen. The pixels on the screen are then copied to
a texture using the vl::CopyTexSubImage2D callback object. Finally the scene with the cube can be rendered
using the previously generated texture.
*/
void initTest_RTT_Legacy()
{
// Setup dual rendering
setRendering(render_tree.get());
mMainRendering = new vl::Rendering;
mRTT_Rendering = new vl::Rendering;
render_tree->subRenderings()->push_back(mRTT_Rendering.get());
render_tree->subRenderings()->push_back(mMainRendering.get());
mMainRendering->sceneManagers()->push_back(new vl::SceneManagerActorTree);
mRTT_Rendering->sceneManagers()->push_back(new vl::SceneManagerActorTree);
/* both render to the screen */
mMainRendering->renderer()->setFramebuffer( openglContext()->framebuffer() );
mRTT_Rendering->renderer()->setFramebuffer( openglContext()->framebuffer() );
// Render to texture rendering
/* setup render-to-texture rendering: render to screen then copies to texture. */
mRTT_Rendering->camera()->viewport()->setClearColor( vl::crimson );
mRTT_Rendering->camera()->viewport()->set(0,0,512,512);
mRTT_Rendering->camera()->setProjectionPerspective();
vl::mat4 m = vl::mat4::getLookAt( vl::vec3(0,0,10.5f), vl::vec3(0,0,0), vl::vec3(0,1,0) );
mRTT_Rendering->camera()->setViewMatrix( m );
/* install copy to texture callback */
vl::ref<vl::Texture> texture = new vl::Texture( 512, 512, vl::TF_RGBA, false );
vl::ref<vl::CopyTexSubImage2D> copytex = new vl::CopyTexSubImage2D( 0, 0,0, 0,0, 512,512, texture.get() );
mRTT_Rendering->onFinishedCallbacks()->push_back( copytex.get() );
// Main rendering
/* setup main rendering */
mMainRendering->camera()->viewport()->setClearColor( vl::midnightblue );
mMainRendering->camera()->viewport()->set(0,0,512,512);
mMainRendering->camera()->setProjectionPerspective();
m = vl::mat4::getLookAt(vl::vec3(0,15,25), vl::vec3(0,0,0), vl::vec3(0,1,0));
mMainRendering->camera()->setViewMatrix( m );
/* populate the scene */
addCube(texture.get(), NULL);
addRings(NULL);
}
void addCube(vl::Texture* texture1, vl::Texture* texture2)
{
light->setAmbient( vl::fvec4( .1f, .1f, .1f, 1.0f) );
light->setSpecular( vl::fvec4( .1f, .1f, .1f, 1.0f) );
effect1->shader()->setRenderState( light.get(), 0 );
effect1->shader()->gocLightModel()->setTwoSide(true);
effect1->shader()->gocTextureSampler(0)->setTexture( texture1 );
// TD_TEXTURE_2D_MULTISAMPLE requires a special fragment shader
{
effect1->shader()->gocGLSLProgram()->attachShader( new vl::GLSLFragmentShader("/glsl/tex_multisample.fs") );
effect1->shader()->gocGLSLProgram()->gocUniform("ms_texture")->setUniformI(0);
}
// ground plane
const vl::real size = 50;
vl::ref<vl::Geometry> ground = vl::makeGrid( vl::vec3(0,0,0), size, size, 2, 2, true, vl::fvec2(0,0), vl::fvec2(1,1) );
ground->computeNormals();
mMainRendering->sceneManagers()->at(0)->as<vl::SceneManagerActorTree>()->tree()->addActor( ground.get(), effect1.get() );
if (texture2)
{
// box #1
vl::ref<vl::Geometry> box1 = vl::makeBox( vl::vec3(-7,5,0), 10,10,10);
box1->computeNormals();
mMainRendering->sceneManagers()->at(0)->as<vl::SceneManagerActorTree>()->tree()->addActor( box1.get(), effect1.get() );
// box #2
effect2->shader()->shallowCopyFrom(*effect1->shader());
texture_sampler->setTexture(texture2);
effect2->shader()->setRenderState(texture_sampler.get(), 0);
vl::ref<vl::Geometry> box2 = vl::makeBox( vl::vec3(+7,5,0), 10,10,10);
box2->computeNormals();
mMainRendering->sceneManagers()->at(0)->as<vl::SceneManagerActorTree>()->tree()->addActor( box2.get(), effect2.get() );
}
else
{
// box #1
vl::ref<vl::Geometry> box1 = vl::makeBox( vl::vec3(0,5,0), 10,10,10);
box1->computeNormals();
mMainRendering->sceneManagers()->at(0)->as<vl::SceneManagerActorTree>()->tree()->addActor( box1.get(), effect1.get() );
}
}
// helper function
vl::Actor* addActor(vl::Rendering* rendering, vl::Renderable* renderable, vl::Effect* eff, vl::Transform* tr)
{
return rendering->sceneManagers()->at(0)->as<vl::SceneManagerActorTree>()->tree()->addActor(renderable, eff, tr);
}
// populates ring scene on mRTT_Rendering
void addRings(vl::GLSLProgram* glsl)
{
effect->shader()->setRenderState(glsl);
light->setAmbient( vl::fvec4( .1f, .1f, .1f, 1.0f) );
light->setSpecular( vl::fvec4( .9f, .9f, .9f, 1.0f) );
effect->shader()->setRenderState( light.get(), 0 );
effect->shader()->gocMaterial()->setDiffuse( vl::yellow );
mTransfRing1 = new vl::Transform;
ring1 = vl::makeTorus( vl::vec3(0,0,0), 10,0.5, 20,100);
addActor(mRTT_Rendering.get(), ring1.get(), effect.get(), mTransfRing1.get());
mTransfRing2 = new vl::Transform;
ring2= vl::makeTorus( vl::vec3(0,0,0), 9,0.5, 20,100);
addActor(mRTT_Rendering.get(), ring2.get(), effect.get(), mTransfRing2.get());
mTransfRing3 = new vl::Transform;
ring3= vl::makeTorus( vl::vec3(0,0,0), 8,0.5, 20,100);
addActor(mRTT_Rendering.get(), ring3.get(), effect.get(), mTransfRing3.get());
mTransfRing4 = new vl::Transform;
ring4= vl::makeTorus( vl::vec3(0,0,0), 7,0.5, 20,100);
addActor(mRTT_Rendering.get(), ring4.get(), effect.get(), mTransfRing4.get());
mTransfRing5 = new vl::Transform;
ring5= vl::makeTorus( vl::vec3(0,0,0), 6,0.5, 20,100);
addActor(mRTT_Rendering.get(), ring5.get(), effect.get(), mTransfRing5.get());
// update transform hierarchy every frame
mRTT_Rendering->transform()->addChild(mTransfRing1.get());
mTransfRing1->addChild(mTransfRing2.get());
mTransfRing2->addChild(mTransfRing3.get());
mTransfRing3->addChild(mTransfRing4.get());
mTransfRing4->addChild(mTransfRing5.get());
}
virtual void initEvent()
{
vl::Log::notify(appletInfo());
{
vl::Log::error("GL_ARB_framebuffer_object not supported.\n");
exit(1);
}
switch(mTestNum)
{
case 0: initTest_FBO_Render_To_Texture();
break;
case 1: initTest_FBO_Render_To_Texture_MRT();
break;
case 2: initTest_FBO_Render_To_Color_Buffer_And_Copy_To_Texture();
break;
case 3: initTest_FBO_Framebuffer_Blit_Multisample();
break;
case 4: initTest_FBO_Multisample_Texture();
break;
case 5: initTest_RTT_Legacy();
break;
default:
break;
}
bindManipulators( mMainRendering->camera() );
}
void resizeEvent(int w, int h)
{
mMainRendering->camera()->viewport()->setWidth ( w );
mMainRendering->camera()->viewport()->setHeight( h );
mMainRendering->camera()->setProjectionPerspective();
}
virtual void updateScene()
{
mX = vl::Time::currentTime() * 45*2;
mY = vl::Time::currentTime() * 45*2.1f;
mX2 = vl::Time::currentTime() * 45*2.2f;
mY2 = vl::Time::currentTime() * 45*2.3f;
mX3 = vl::Time::currentTime() * 45*2.4f;
mTransfRing1->setLocalMatrix( vl::mat4::getRotation(mX, 1,0,0) );
mTransfRing2->setLocalMatrix( vl::mat4::getRotation(mY, 0,1,0) );
mTransfRing3->setLocalMatrix( vl::mat4::getRotation(mX2, 1,0,0) );
mTransfRing4->setLocalMatrix( vl::mat4::getRotation(mY2, 0,1,0) );
mTransfRing5->setLocalMatrix( vl::mat4::getRotation(mX3, 1,0,0) );
}
virtual void destroyEvent()
{
BaseDemo::destroyEvent();
// release all OpenGL resources
setRendering(NULL);
mMainRendering = NULL;
mRTT_Rendering = NULL;
}
protected:
int mTestNum;
vl::real mX, mY, mX2, mY2, mX3;
vl::ref<vl::Transform> mTransfRing1;
vl::ref<vl::Transform> mTransfRing2;
vl::ref<vl::Transform> mTransfRing3;
vl::ref<vl::Transform> mTransfRing4;
vl::ref<vl::Transform> mTransfRing5;
vl::ref<vl::Rendering> mMainRendering;
vl::ref<vl::Rendering> mRTT_Rendering;
};
// Have fun!