inline std::string getOpenGLExtensions()
  {
    std::string ext;
    if (Has_GL_Version_3_0||Has_GL_Version_4_0)
    {
      int count = 0;
      glGetIntegerv(GL_NUM_EXTENSIONS, &count);
      for( int i=0; i<count; ++i )
      {
        ext += std::string((char*)glGetStringi(GL_EXTENSIONS, i)) + " ";
        VL_CHECK_OGL();
      }
    }
    else
    {
      VL_CHECK(glGetString(GL_EXTENSIONS));
      ext = (const char*)glGetString(GL_EXTENSIONS);
      // make sure also the last extension ends with a space
      ext.push_back(' ');
    }

    return ext;
  }
 void setUniform4ui(int count, const unsigned int* value) { initData(count*4); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_UInt4; VL_CHECK(GLEW_EXT_gpu_shader4||GLEW_VERSION_3_0||GLEW_VERSION_4_0); }
 void setUniform3i(int count, const int* value) { initData(count*3); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Int3; VL_CHECK(GLEW_Has_Shading_Language_20); }
 Vector2<T_Scalar>& operator[](unsigned int i) { VL_CHECK(i<2); return mVec[i]; }
 /** Utility function, same as \p 'lod(lodi) = new ShaderPasses(shader1,shader2,shader3,shader4);' */
 void setLOD(int lodi, Shader* shader1, Shader* shader2=NULL, Shader* shader3=NULL, Shader* shader4=NULL) 
 { 
   VL_CHECK(lodi<VL_MAX_EFFECT_LOD)
   lod(lodi) = new ShaderPasses(shader1,shader2,shader3,shader4);
 }
  virtual void initEvent()
  {
    if ( !vl::canLoad("png") || !vl::canLoad("jpg") || !vl::canLoad("tga") || !vl::canLoad("tif") )
    {
      vl::Log::error("App_ImageFunctions test requires the following modules: VL_IO_2D_JPG, VL_IO_2D_PNG, VL_IO_2D_TIFF and VL_IO_2D_TGA.\n");
      vl::Time::sleep(2000);
      exit(1);
    }

    vl::Log::notify(appletInfo());

    bool use_mipmaps = true;

    vl::ref<vl::Image> img1 = vl::loadImage("/images/holebox.tif");
    // make sure it's in the right format
    img1 = img1->convertFormat(vl::IF_RGBA)->convertType(vl::IT_UNSIGNED_BYTE);
    vl::ref<vl::Image> img2;

    // check load/save routines
    vl::ref<vl::Image> img_a;
    vl::ref<vl::Image> img_b;
    vl::ref<vl::Image> img_c;
    vl::ref<vl::Image> img_d;

    vl::LoadWriterJPG* jpg_load_writer = vl::defLoadWriterManager()->loadWriter<vl::LoadWriterJPG>();
    if (jpg_load_writer)
    {
      jpg_load_writer->setQuality(90);
      vl::saveImage(img1.get(), "img_a.jpg");
      img_a = vl::loadImage("img_a.jpg");
    }

    vl::LoadWriterPNG* png_load_writer = vl::defLoadWriterManager()->loadWriter<vl::LoadWriterPNG>();
    if (png_load_writer)
    {
      png_load_writer->setCompression(9);
      vl::saveImage(img1.get(), "img_b.png");
      img_b = vl::loadImage("img_b.png");
    }

    vl::saveImage(img1.get(), "img_c.tga");
    img_c = vl::loadImage("img_c.tga");

    vl::saveImage(img1.get(), "img_d.tif");
    img_d = vl::loadImage("img_d.tif");

    VL_CHECK(img_a)
    VL_CHECK(img_b)
    VL_CHECK(img_c)
    VL_CHECK(img_d)

    // test image nearest sampling IF_RGBA/IT_UNSIGNED_BYTE
    vl::ref<vl::Image> img_x = new vl::Image;
    // copy image
    *img_x = *img1;
    // set it to black
    memset(img_x->pixels(), 0, img_x->requiredMemory());
    for(int x=0; x<img_x->width(); ++x)
    {
      for(int y=0; y<img_x->height(); ++y)
      {
        vl::fvec4 color = img1->sample(x,y);
        unsigned char* pixel = img_x->pixels() + img_x->pitch()*y + x*4;
        pixel[0] = (unsigned char)(color.r() * 255.0);
        pixel[1] = (unsigned char)(color.g() * 255.0);
        pixel[2] = (unsigned char)(color.b() * 255.0);
        pixel[3] = (unsigned char)(color.a() * 255.0);
      }
    }
    // test image linear sampling IF_RGBA/IT_UNSIGNED_BYTE
    vl::ref<vl::Image> img_y = new vl::Image;
    // copy image

    *img_y = *img1;
    // set it to black
    memset(img_y->pixels(), 0, img_y->requiredMemory());
    for(int x=0; x<img_y->width(); ++x)
    {
      for(int y=0; y<img_y->height(); ++y)
      {
        vl::fvec4 color = img1->sampleLinear((float)x,(float)y);
        unsigned char* pixel = img_y->pixels() + img_y->pitch()*y + x*4;
        pixel[0] = (unsigned char)(color.r() * 255.0);
        pixel[1] = (unsigned char)(color.g() * 255.0);
        pixel[2] = (unsigned char)(color.b() * 255.0);
        pixel[3] = (unsigned char)(color.a() * 255.0);
      }
    }

    // check image type conversion
    #if 1
      img2 = img1
      ->convertType(vl::IT_FLOAT)
      ->convertType(vl::IT_SHORT)
      ->convertType(vl::IT_INT)
      ->convertType(vl::IT_BYTE)
      ->convertType(vl::IT_UNSIGNED_BYTE)
      ->convertType(vl::IT_UNSIGNED_SHORT)
      ->convertType(vl::IT_UNSIGNED_INT)
     ;
    #endif

    // check image format conversion
    #if 1
      img2 = img1
        ->convertFormat(vl::IF_LUMINANCE_ALPHA)
        ->convertFormat(vl::IF_BGRA)
        ->convertFormat(vl::IF_RGBA)
        ->convertFormat(vl::IF_LUMINANCE_ALPHA)
     ;
    #endif

    // test image nearest sampling IF_LUMINANCE_ALPHA/IT_UNSIGNED_INT
    vl::ref<vl::Image> img_z = new vl::Image;
    // copy image
    *img_z = *img2;
    // set it to black
    memset(img_z->pixels(), 0, img_z->requiredMemory());
    for(int x=0; x<img_z->width(); ++x)
    {
      for(int y=0; y<img_z->height(); ++y)
      {
        vl::fvec4 color = img2->sample(x,y);
        unsigned char* pixel = img_z->pixels() + img_z->pitch()*y + x*2;
        pixel[0] = (unsigned char)(color.r() * 255.0);
        pixel[1] = (unsigned char)(color.a() * 255.0);
      }
    }

    // test image linear sampling IF_LUMINANCE_ALPHA/IT_UNSIGNED_INT
    vl::ref<vl::Image> img_w = new vl::Image;
    // copy image
    *img_w = *img2;
    // set it to black
    memset(img_w->pixels(), 0, img_w->requiredMemory());
    for(int x=0; x<img_w->width(); ++x)
    {
      for(int y=0; y<img_w->height(); ++y)
      {
        vl::fvec4 color = img2->sampleLinear((float)x,(float)y);
        unsigned char* pixel = img_w->pixels() + img_w->pitch()*y + x*2;
        pixel[0] = (unsigned char)(color.r() * 255.0);
        pixel[1] = (unsigned char)(color.a() * 255.0);
      }
    }

    vl::ref<vl::Geometry> quad = vl::makeGrid( vl::vec3(0,0,0), 10, 10, 2, 2, true, vl::fvec2(0,0), vl::fvec2(1,1) );
    quad->transform( vl::mat4::getRotation(-90, 1,0,0), false );

    // (1)
    // transform
    vl::ref<vl::Transform> tr_1 = new vl::Transform;
    rendering()->as<vl::Rendering>()->transform()->addChild(tr_1.get());
    tr_1->setLocalMatrix(vl::mat4::getTranslation(-5,0,0));
    // effect
    vl::ref<vl::Effect> fx_1 = new vl::Effect;
    fx_1->shader()->enable(vl::EN_BLEND);
    // setup texture
    vl::ref<vl::Texture> texture_1 = new vl::Texture( img1.get(), vl::TF_RGBA, use_mipmaps, false );
    fx_1->shader()->gocTextureSampler(0)->setTexture( texture_1.get() );
    fx_1->shader()->gocTextureSampler(0)->texture()->getTexParameter()->setMagFilter(vl::TPF_LINEAR);
    fx_1->shader()->gocTextureSampler(0)->texture()->getTexParameter()->setMinFilter(vl::TPF_LINEAR_MIPMAP_LINEAR);
    // add actor
    sceneManager()->tree()->addActor( quad.get(), fx_1.get(), tr_1.get() );

    // (2)
    // transform
    vl::ref<vl::Transform> tr_2 = new vl::Transform;
    rendering()->as<vl::Rendering>()->transform()->addChild(tr_2.get());
    tr_2->setLocalMatrix(vl::mat4::getTranslation(+5,0,0));
    // effect
    vl::ref<vl::Effect> fx_2 = new vl::Effect;
    fx_2->shader()->enable(vl::EN_BLEND);
    // setup texture
    vl::ref<vl::Texture> texture_2 = new vl::Texture( img2.get(), vl::TF_RGBA, use_mipmaps, false );
    fx_2->shader()->gocTextureSampler(0)->setTexture( texture_2.get() );
    fx_2->shader()->gocTextureSampler(0)->texture()->getTexParameter()->setMagFilter(vl::TPF_LINEAR);
    fx_2->shader()->gocTextureSampler(0)->texture()->getTexParameter()->setMinFilter(vl::TPF_LINEAR_MIPMAP_LINEAR);
    // add actor
    sceneManager()->tree()->addActor( quad.get(), fx_2.get(), tr_2.get() );

    // (x)
    // transform
    vl::ref<vl::Transform> tr_x = new vl::Transform;
    rendering()->as<vl::Rendering>()->transform()->addChild(tr_x.get());
    tr_x->setLocalMatrix(vl::mat4::getTranslation(-2.5-5,+7.5,0) * vl::mat4::getScaling(0.5f,0.5f,1.0f));
    // effect
    vl::ref<vl::Effect> fx_x = new vl::Effect;
    fx_x->shader()->enable(vl::EN_BLEND);
    // setup texture
    vl::ref<vl::Texture> texture_x = new vl::Texture( img_x.get(), vl::TF_RGBA, use_mipmaps, false );
    fx_x->shader()->gocTextureSampler(0)->setTexture( texture_x.get() );
    fx_x->shader()->gocTextureSampler(0)->texture()->getTexParameter()->setMagFilter(vl::TPF_LINEAR);
    fx_x->shader()->gocTextureSampler(0)->texture()->getTexParameter()->setMinFilter(vl::TPF_LINEAR_MIPMAP_LINEAR);
    // add actor
    sceneManager()->tree()->addActor( quad.get(), fx_x.get(), tr_x.get() );

    // (y)
    // transform
    vl::ref<vl::Transform> tr_y = new vl::Transform;
    rendering()->as<vl::Rendering>()->transform()->addChild(tr_y.get());
    tr_y->setLocalMatrix(vl::mat4::getTranslation(-2.5,+7.5,0) * vl::mat4::getScaling(0.5f,0.5f,1.0f));
    // effect
    vl::ref<vl::Effect> fx_y = new vl::Effect;
    fx_y->shader()->enable(vl::EN_BLEND);
    // setup texture
    vl::ref<vl::Texture> texture_y = new vl::Texture( img_y.get(), vl::TF_RGBA, use_mipmaps, false );
    fx_y->shader()->gocTextureSampler(0)->setTexture( texture_y.get() );
    fx_y->shader()->gocTextureSampler(0)->texture()->getTexParameter()->setMagFilter(vl::TPF_LINEAR);
    fx_y->shader()->gocTextureSampler(0)->texture()->getTexParameter()->setMinFilter(vl::TPF_LINEAR_MIPMAP_LINEAR);
    // add actor
    sceneManager()->tree()->addActor( quad.get(), fx_y.get(), tr_y.get() );

    // (z)
    // transform
    vl::ref<vl::Transform> tr_z = new vl::Transform;
    rendering()->as<vl::Rendering>()->transform()->addChild(tr_z.get());
    tr_z->setLocalMatrix(vl::mat4::getTranslation(+2.5,+7.5,0) * vl::mat4::getScaling(0.5f,0.5f,1.0f));
    // effect
    vl::ref<vl::Effect> fx_z = new vl::Effect;
    fx_z->shader()->enable(vl::EN_BLEND);
    // setup texture
    vl::ref<vl::Texture> texture_z = new vl::Texture( img_z.get(), vl::TF_RGBA, use_mipmaps, false );
    fx_z->shader()->gocTextureSampler(0)->setTexture( texture_z.get() );
    fx_z->shader()->gocTextureSampler(0)->texture()->getTexParameter()->setMagFilter(vl::TPF_LINEAR);
    fx_z->shader()->gocTextureSampler(0)->texture()->getTexParameter()->setMinFilter(vl::TPF_LINEAR_MIPMAP_LINEAR);
    // add actor
    sceneManager()->tree()->addActor( quad.get(), fx_z.get(), tr_z.get() );

    // (w)
    // transform
    vl::ref<vl::Transform> tr_w = new vl::Transform;
    rendering()->as<vl::Rendering>()->transform()->addChild(tr_w.get());
    tr_w->setLocalMatrix(vl::mat4::getTranslation(+2.5+5.0,+7.5,0) * vl::mat4::getScaling(0.5f,0.5f,1.0f));
    // effect
    vl::ref<vl::Effect> fx_w = new vl::Effect;
    fx_w->shader()->enable(vl::EN_BLEND);
    // setup texture
    vl::ref<vl::Texture> texture_w = new vl::Texture( img_w.get(), vl::TF_RGBA, use_mipmaps, false );
    fx_w->shader()->gocTextureSampler(0)->setTexture( texture_w.get() );
    fx_w->shader()->gocTextureSampler(0)->texture()->getTexParameter()->setMagFilter(vl::TPF_LINEAR);
    fx_w->shader()->gocTextureSampler(0)->texture()->getTexParameter()->setMinFilter(vl::TPF_LINEAR_MIPMAP_LINEAR);
    // add actor
    sceneManager()->tree()->addActor( quad.get(), fx_w.get(), tr_w.get() );

    // (a)
    // transform
    vl::ref<vl::Transform> tr_a = new vl::Transform;
    rendering()->as<vl::Rendering>()->transform()->addChild(tr_a.get());
    tr_a->setLocalMatrix(vl::mat4::getTranslation(-2.5-5,-7.5,0) * vl::mat4::getScaling(0.5f,0.5f,1.0f));
    // effect
    vl::ref<vl::Effect> fx_a = new vl::Effect;
    fx_a->shader()->enable(vl::EN_BLEND);
    // setup texture
    vl::ref<vl::Texture> texture_a = new vl::Texture( img_a.get(), vl::TF_RGBA, use_mipmaps, false );
    fx_a->shader()->gocTextureSampler(0)->setTexture( texture_a.get() );
    fx_a->shader()->gocTextureSampler(0)->texture()->getTexParameter()->setMagFilter(vl::TPF_LINEAR);
    fx_a->shader()->gocTextureSampler(0)->texture()->getTexParameter()->setMinFilter(vl::TPF_LINEAR_MIPMAP_LINEAR);
    // add actor
    sceneManager()->tree()->addActor( quad.get(), fx_a.get(), tr_a.get() );

    // (b)
    // transform
    vl::ref<vl::Transform> tr_b = new vl::Transform;
    rendering()->as<vl::Rendering>()->transform()->addChild(tr_b.get());
    tr_b->setLocalMatrix(vl::mat4::getTranslation(-2.5,-7.5,0) * vl::mat4::getScaling(0.5f,0.5f,1.0f));
    // effect
    vl::ref<vl::Effect> fx_b = new vl::Effect;
    fx_b->shader()->enable(vl::EN_BLEND);
    // setup texture
    vl::ref<vl::Texture> texture_b = new vl::Texture( img_b.get(), vl::TF_RGBA, use_mipmaps, false );
    fx_b->shader()->gocTextureSampler(0)->setTexture( texture_b.get() );
    fx_b->shader()->gocTextureSampler(0)->texture()->getTexParameter()->setMagFilter(vl::TPF_LINEAR);
    fx_b->shader()->gocTextureSampler(0)->texture()->getTexParameter()->setMinFilter(vl::TPF_LINEAR_MIPMAP_LINEAR);
    // add actor
    sceneManager()->tree()->addActor( quad.get(), fx_b.get(), tr_b.get() );

    // (c)
    // transform
    vl::ref<vl::Transform> tr_c = new vl::Transform;
    rendering()->as<vl::Rendering>()->transform()->addChild(tr_c.get());
    tr_c->setLocalMatrix(vl::mat4::getTranslation(+2.5,-7.5,0) * vl::mat4::getScaling(0.5f,0.5f,1.0f));
    // effect
    vl::ref<vl::Effect> fx_c = new vl::Effect;
    fx_c->shader()->enable(vl::EN_BLEND);
    // setup texture
    vl::ref<vl::Texture> texture_c = new vl::Texture( img_c.get(), vl::TF_RGBA, use_mipmaps, false );
    fx_c->shader()->gocTextureSampler(0)->setTexture( texture_c.get() );
    fx_c->shader()->gocTextureSampler(0)->texture()->getTexParameter()->setMagFilter(vl::TPF_LINEAR);
    fx_c->shader()->gocTextureSampler(0)->texture()->getTexParameter()->setMinFilter(vl::TPF_LINEAR_MIPMAP_LINEAR);
    // add actor
    sceneManager()->tree()->addActor( quad.get(), fx_c.get(), tr_c.get() );

    // (d)
    // transform
    vl::ref<vl::Transform> tr_d = new vl::Transform;
    rendering()->as<vl::Rendering>()->transform()->addChild(tr_d.get());
    tr_d->setLocalMatrix(vl::mat4::getTranslation(+2.5+5,-7.5,0) * vl::mat4::getScaling(0.5f,0.5f,1.0f));
    // effect
    vl::ref<vl::Effect> fx_d = new vl::Effect;
    fx_d->shader()->enable(vl::EN_BLEND);
    // setup texture
    vl::ref<vl::Texture> texture_d = new vl::Texture( img_d.get(), vl::TF_RGBA, use_mipmaps, false );
    fx_d->shader()->gocTextureSampler(0)->setTexture( texture_d.get() );
    fx_d->shader()->gocTextureSampler(0)->texture()->getTexParameter()->setMagFilter(vl::TPF_LINEAR);
    fx_d->shader()->gocTextureSampler(0)->texture()->getTexParameter()->setMinFilter(vl::TPF_LINEAR_MIPMAP_LINEAR);
    // add actor
    sceneManager()->tree()->addActor( quad.get(), fx_d.get(), tr_d.get() );
  }
 T* operator->() { VL_CHECK(mObject); return mObject; }
 const T* operator->() const { VL_CHECK(mObject); return mObject; }
  void initEvent()
  {
    if (!vl::Has_GLSL)
    {
      vl::Log::error("OpenGL Shading Language not supported.\n");
      vl::Time::sleep(2000);
      exit(1);
    }

    vl::Log::notify(appletInfo());

    mTransform = new vl::Transform;

    // generate torus, with normals and uv coords
    vl::ref<vl::Geometry> model = vl::makeTorus( vl::vec3(0,0,0), 10, 2, TORUS_SEGS, TORUS_SEGS, 2.0f );
    model->transform( vl::mat4::getRotation( 45.0f, 1.0f, 1.0f, 0.0f ) );

    // setup effect
    vl::ref<vl::Effect> effect = new vl::Effect;
    effect->shader()->setRenderState( new vl::Light, 0 );
    effect->shader()->enable(vl::EN_LIGHTING);
    effect->shader()->enable(vl::EN_DEPTH_TEST);
    effect->shader()->enable(vl::EN_CULL_FACE);
    mTorus = sceneManager()->tree()->addActor( model.get(), effect.get(), mTransform.get() );

    // setup texture
    vl::ref<vl::Texture> texture0 = new vl::Texture;
    texture0->prepareTexture2D("images/normalmap.jpg", vl::TF_RGBA);
    effect->shader()->gocTextureSampler(0)->setTexture(texture0.get());
    texture0->getTexParameter()->setAnisotropy(16.0);
    texture0->getTexParameter()->setMagFilter(vl::TPF_LINEAR);
    texture0->getTexParameter()->setMinFilter(vl::TPF_LINEAR_MIPMAP_LINEAR);

    // setup GLSL shader
    mGLSL = effect->shader()->gocGLSLProgram();
    mGLSL->attachShader( new vl::GLSLVertexShader("/glsl/bumpmap.vs") );
    mGLSL->attachShader( new vl::GLSLFragmentShader("/glsl/bumpmap.fs") );
    // samper0
    vl::ref<vl::Uniform> sampler0 = new vl::Uniform("sampler0");
    sampler0->setUniformI(0);
    mGLSL->setUniform( sampler0.get() );
    // light_obj_space_pos
    mLightObjSpacePosition = new vl::Uniform("light_obj_space_pos");
    mGLSL->setUniform( mLightObjSpacePosition.get() );

    // compute the tangent vector for each vertex

    vl::ref<vl::ArrayFloat3> tangent = new vl::ArrayFloat3;
    tangent->resize( model->vertexArray()->size() );

    vl::Geometry::computeTangentSpace(
      model->vertexArray()->size(), 
      (vl::fvec3*)model->vertexArray()->ptr(), 
      (vl::fvec3*)model->normalArray()->ptr(), 
      (vl::fvec2*)model->texCoordArray(0)->ptr(),
      model->drawCalls()->at(0),
      tangent->begin(), 
      NULL );

    // bind the tangent vertex attribute
    mGLSL->linkProgram();
    // note that you need to link the GLSL program before calling this
    int tangent_idx = mGLSL->getAttribLocation("tangent"); VL_CHECK( tangent_idx != -1 );
    model->setVertexAttribArray(tangent_idx, tangent.get() );

    // visualize the TBN vectors
    visualizeTangentSpace( model.get(), tangent.get() );
  }
Beispiel #10
0
 const Plane& plane(unsigned i) const { VL_CHECK(i<mPlanes.size()); return mPlanes[i]; }
Beispiel #11
0
 void setPlane(unsigned i, const Plane& plane) { VL_CHECK(i<mPlanes.size()); mPlanes[i] = plane; }
  virtual void initEvent()
  {
    if (!vl::defLoadWriterManager()->canLoad("md2"))
    {
      vl::Log::error("App_MorphAnimation requires VL_IO_2D_MD2.\n");
      vl::Time::sleep(2000);
      exit(1);
    }

    vl::Log::notify(appletInfo());

    const int actor_count = 1000;

    ghostCameraManipulator()->setMovementSpeed(500.0f);
    bool glsl_vertex_blend = vl::Has_GL_Version_2_0 ? true : false;
    const float area_unit  = 1500.0f*1500.0f/2000.0f;
    const float size = sqrt( actor_count * area_unit );

    // common effect settings

    vl::ref<vl::Light> light = new vl::Light;
    vl::ref<vl::Effect> ground_fx = new vl::Effect;
    ground_fx->shader()->setRenderState( light.get(), 0 );
    ground_fx->shader()->enable(vl::EN_LIGHTING);
    ground_fx->shader()->enable(vl::EN_DEPTH_TEST);

    // ground

    vl::ref<vl::Geometry> ground;
    ground = vl::makeGrid( vl::vec3(0,-30,0), size*1.1f, size*1.1f, 20, 20 );
    ground->computeNormals();
    sceneManager()->tree()->addActor(ground.get(), ground_fx.get() );

    vl::ref<vl::ResourceDatabase> res_db = vl::loadResource("/3rdparty/pknight/tris.md2");
    VL_CHECK(res_db && res_db->get<vl::Geometry>(0))

    vl::ref<vl::MorphingCallback> morph_cb1 = new vl::MorphingCallback;
    morph_cb1->init(res_db.get());

    vl::ref<vl::Effect> effect[4] = { new vl::Effect, new vl::Effect, new vl::Effect, new vl::Effect };
    const char* texname[] = { "/3rdparty/pknight/evil.tif", "/3rdparty/pknight/knight.tif", "/3rdparty/pknight/ctf_r.tif", "/3rdparty/pknight/ctf_b.tif" };
    for(int i=0; i<4; ++i)
    {
      effect[i]->shader()->setRenderState( light.get(), 0 );
      effect[i]->shader()->enable(vl::EN_LIGHTING);
      effect[i]->shader()->enable(vl::EN_DEPTH_TEST);
      vl::ref<vl::Texture> texture = new vl::Texture;
      texture->prepareTexture2D(texname[i], vl::TF_RGBA);
      effect[i]->shader()->gocTextureSampler(0)->setTexture( texture.get() );

      if (glsl_vertex_blend)
      {
        vl::ref<vl::GLSLProgram> glsl = effect[i]->shader()->gocGLSLProgram();
        effect[i]->shader()->gocGLSLProgram()->attachShader(new vl::GLSLVertexShader("glsl/vertex_blend.vs"));
      }
    }

    /* multi instancing */
    for(int i=0; i<actor_count; i++)
    {
      float x = rand() % RAND_MAX / (float)RAND_MAX - 0.5f;
      float z = rand() % RAND_MAX / (float)RAND_MAX - 0.5f;
      x *= size;
      z *= size;
      vl::ref<vl::Actor> morph_act2 = new vl::Actor;
      vl::ref<vl::MorphingCallback> morph_cb2 = new vl::MorphingCallback;
      morph_cb2->bindActor( morph_act2.get() );
      morph_cb2->initFrom( morph_cb1.get() );

      morph_act2->setEffect( effect[i%4].get() );

      sceneManager()->tree()->addActor( morph_act2.get() );
      morph_act2->setTransform( new vl::Transform );
      morph_act2->transform()->setLocalMatrix( vl::mat4::getTranslation(x,-morph_act2->lod(0)->boundingBox().minCorner().y(),z) );
      morph_act2->transform()->computeWorldMatrix(NULL);

      switch(i % 5)
      {
        case 0: morph_cb2->setAnimation(0,   39,  1.5f); break; // stand
        case 1: morph_cb2->setAnimation(40,  45,  1.5f); break; // run
        case 2: morph_cb2->setAnimation(46,  53,  1.5f); break; // attack
        case 3: morph_cb2->setAnimation(112, 122, 1.5f); break; // wave
        case 4: morph_cb2->setAnimation(190, 197, 1.5f); break; // die
      }

      morph_cb2->startAnimation();
      morph_cb2->setGLSLVertexBlendEnabled(glsl_vertex_blend);
    }
  }
 void eraseChild(unsigned index)
 {
   VL_CHECK(index<childrenCount())
   mNodes[index]->mParent = NULL;
   mNodes.erase(mNodes.begin()+index);
 }
 void setUniform4f(int count, const float* value) { initData(count*4); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Float4; VL_CHECK(GLEW_Has_Shading_Language_20); }
 void getTexCoordArrayAt(int i, int& out_tex_unit, const ArrayAbstract* &tex_array) const
 {
   VL_CHECK(i<mTexCoordArrays.size());
   out_tex_unit = mTexCoordArrays[i]->mTextureUnit;
   tex_array = mTexCoordArrays[i]->mTexCoordArray.get();
 }
 void setUniform1d(int count, const double* value) { initDouble(count*1); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Double;  VL_CHECK(GLEW_VERSION_4_0); }
  virtual void initEvent()
  {
    /* This test shows how to implement an advanced form of geometry instancing on the GPU.
       The test creates 10 batches of 100 objects each, each batch is assigned to a GLSL program,
       the matrix and normal matrices are passed as uniforms. One actor is sufficient to represent
       a batch or 100 objects. The matrices are updated once every 30 seconds thus gaining a
       significant performance improvement.
    */

    if (!GLEW_EXT_draw_instanced)
    {
      vl::Log::error("GL_EXT_draw_instanced not supported.\n");
      vl::Time::sleep(3000);
      exit(1);
    }

    vl::ref<vl::Geometry> box_set = vl::makeBox( vl::vec3(0,0,0), 2, 2, 2, false);
    box_set->computeNormals();
    box_set->setObjectName("Box Set");
    box_set->setColor(vl::white);

    /* setting multiple instances is as easy as calling this function! */
    vl::DrawArrays* draw_arrays = dynamic_cast<vl::DrawArrays*>( box_set->drawCalls()->at(0) );
    VL_CHECK(draw_arrays)
    draw_arrays->setInstances(100);

    /* create a AABB that approximately reflects the geometry generated by the shader */
    box_set->setBoundingBox( vl::AABB(vl::vec3(-1,-1,-1), vl::vec3(45+1, 45+1, 45+1)) );

    for(int batch=0; batch<10; ++batch)
    {
      /* box effect */
      vl::ref<vl::Effect> fx = new vl::Effect;
      fx->shader()->setRenderState( new vl::Light(0) );
      fx->shader()->enable(vl::EN_LIGHTING);
      fx->shader()->enable(vl::EN_CULL_FACE);
      fx->shader()->enable(vl::EN_DEPTH_TEST);
      fx->shader()->gocMaterial()->setColorMaterialEnabled(false);

      /* use a multi instancing vertex shader */
      vl::GLSLProgram* glsl = fx->shader()->gocGLSLProgram();
      glsl->attachShader( new vl::GLSLVertexShader("/glsl/geometry_instancing.vs") );

      /* add the objects to the scene */

      vl::Actor* actor = sceneManager()->tree()->addActor( box_set.get(), fx.get() );

      _model_view_matrix[batch] = new vl::Uniform("model_view_matrix");
      _normal_matrix[batch]     = new vl::Uniform("normal_matrix");

      #if 1
        // the uniforms must be per actor
        actor->gocUniformSet()->setUniform( _model_view_matrix[batch].get() );
        actor->gocUniformSet()->setUniform( _normal_matrix[batch].get() );
      #else
        // is not coorect to send the uniform per-shader
        fx->shader()->setUniform( _model_view_matrix[batch].get() );
        fx->shader()->setUniform( _normal_matrix[batch].get() );
      #endif
    }

    /* aabb effect */
    vl::ref<vl::Effect> box_fx = new vl::Effect;
    box_fx->shader()->setRenderState( new vl::Light(0) );
    box_fx->shader()->enable(vl::EN_DEPTH_TEST);
    box_fx->shader()->gocPolygonMode()->set(vl::PM_LINE, vl::PM_LINE);

    /* shows bounding box */
    vl::ref<vl::Geometry> box = vl::makeBox( box_set->boundingBox() );
    box->setObjectName("Wire box");
    box->setColor(vl::red);
    box->computeNormals();
    sceneManager()->tree()->addActor( box.get(), box_fx.get() );

    for(unsigned i=0; i<1000; ++i)
    {
      rot[i].x() = rand()%100 - 50.0f;
      rot[i].y() = rand()%100 - 50.0f;
      rot[i].z() = rand()%100 - 50.0f;
      rot[i].normalize();
    }
  }
 const T& operator*() const { VL_CHECK(mObject); return *mObject; }
 void setUniformMatrix4x3f(int count, const float* value) { initData(count*4*3); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Mat4x3F; VL_CHECK(GLEW_Has_Shading_Language_21); }
 T& operator*() { VL_CHECK(mObject); return *mObject; }
 void setUniformMatrix4x3d(int count, const double* value) { initDouble(count*4*3); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Mat4x3D; VL_CHECK(GLEW_VERSION_4_0); }
 const T_VectorType& at(size_t i) const { VL_CHECK(i<size()); return *(reinterpret_cast<const T_VectorType*>(ptr())+i); }
 void getUniform(unsigned int* value) { VL_CHECK(type() != UT_NONE); VL_CHECK(mData.size()); memcpy( value, &mData[0], sizeof(mData[0]) * mData.size()); }
 /** Sets the lod to be used for rendering. It must be: 0 <= lod < VL_MAX_EFFECT_LOD. */
 void setActiveLod(int lod) 
 { 
   VL_CHECK( lod < VL_MAX_EFFECT_LOD )
   VL_CHECK( lod >= 0 )
   mActiveLod = lod; 
 }
    bool readValue(VLXValue& val)
    {
      unsigned char chunk = 0;

      if (!readChunk(chunk))
        return false;

      std::string str;

      switch(chunk)
      {

      case VLB_ChunkStructure:
        val.setStructure( new VLXStructure );
        return parseStructure( val.getStructure() );
      
      case VLB_ChunkList:
        val.setList( new VLXList );
        return parseList( val.getList() );

      case VLB_ChunkArrayInteger:
        {
          // tag
          if (!readString(str))
            return false;
          else
            val.setArrayInteger( new VLXArrayInteger( str.c_str() ) );

          // count
          long long count = 0;
          if (!readInteger(count))
            return false;

          // values
          VLXArrayInteger& arr = *val.getArrayInteger();
          if (count)
          {
            long long encode_count = 0;
            if (!readInteger(encode_count))
              return false;
            VL_CHECK(encode_count >= 0)
            if (encode_count)
            {
              std::vector<unsigned char> encoded;
              encoded.resize((size_t)encode_count);
              inputFile()->readUInt8(&encoded[0], encode_count);
              decodeIntegers(encoded, arr.value());
            }
          }
          VL_CHECK((size_t)count == arr.value().size())
          return (size_t)count == arr.value().size();
        }

      case VLB_ChunkArrayRealDouble:
        {
          // tag
          if (!readString(str))
            return false;
          else
            val.setArrayReal( new VLXArrayReal( str.c_str() ) );
          // count
          long long count = 0;
          if (!readInteger(count))
            return false;
          // values
          VLXArrayReal& arr = *val.getArrayReal();
          arr.value().resize( (size_t)count );
          if (count)
          {
#if 1
            long long c = inputFile()->readDouble( &arr.value()[0], count );
            VL_CHECK(c == count * (int)sizeof(double))
            return c == count * (int)sizeof(double);
#elif 0
            long long zsize = 0;
            readInteger(zsize);
            std::vector<unsigned char> zipped;
            zipped.resize((size_t)zsize);
            inputFile()->read(&zipped[0], zipped.size());
            bool ok = decompress(&zipped[0], (size_t)zsize, &arr.value()[0]);
            VL_CHECK(ok);
            return ok;
#endif
          }
          else
            return true;
        }

      case VLB_ChunkArrayRealFloat:
        {
          // tag
          if (!readString(str))
            return false;
          else
            val.setArrayReal( new VLXArrayReal( str.c_str() ) );
          // count
          long long count = 0;
          if (!readInteger(count))
            return false;
          // values
          VLXArrayReal& arr = *val.getArrayReal();
          arr.value().resize( (size_t)count );
          if (count)
          {
#if 1
            std::vector<float> floats;
            floats.resize( (size_t)count );
            long long c = inputFile()->readFloat( &floats[0], count );
            // copy over floats to doubles
            for(size_t i=0; i<floats.size(); ++i)
              arr.value()[i] = floats[i];
            VL_CHECK(c == count * (int)sizeof(float))
            return c == count * (int)sizeof(float);
#elif 0
            long long zsize = 0;
            readInteger(zsize);
            std::vector<unsigned char> zipped;
            zipped.resize((size_t)zsize);
            inputFile()->read(&zipped[0], zipped.size());
            bool ok = decompress(&zipped[0], (size_t)zsize, &arr.value()[0]);
            VL_CHECK(ok);
            return ok;
#endif
          }
          else
            return true;
        }