hovergames / avalon

Various extensions, helper and functions for cocos2d-x
Other
91 stars 37 forks source link

How to use DynamicLight? #51

Open ttohin opened 10 years ago

ttohin commented 10 years ago

I didn't find examples how to use avalon::graphics::DynamicLight and I created empty project with HelloWorld::init method like this. So, I don't see dynamic lighting and/or shadows from sprite baba.png

bool HelloWorld::init()
{
  if ( !Layer::init() )
  {
    return false;
  }
  Size visibleSize = Director::getInstance()->getVisibleSize();
  Vec2 origin = Director::getInstance()->getVisibleOrigin();

  auto bg = Sprite::create("HelloWorld.png");

  // position the sprite on the center of the screen
  bg->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
  bg->setScale(2, 2);

  // add the sprite as a child to this layer
  this->addChild(bg);

  auto baba = Sprite::create("baba.png");
  baba->cocos2d::Node::setPosition({visibleSize.width/2, visibleSize.height/2});
  this->addChild(baba);

  auto dynamicLight = avalon::graphics::DynamicLight::create();
  dynamicLight->debugDrawEnabled = true;
  dynamicLight->setShadowCasters(*baba);
  dynamicLight->setPosition({visibleSize.width/2 + 40, visibleSize.height/2});
  this->addChild(dynamicLight);

  return true;
}

Main question is. What do I wrong?

And another ones about signature of method:

void DynamicLight::setShadowCasters(Node& casters) 

Why casters is reference? Do we really need in copying here? And why casters are plural (may be list of Nodes expected here)?

namkazt commented 10 years ago

Have same problems here!

namkazt commented 10 years ago

just need to fix alot to make it runable, the most important is need to use GLProgramState to pass variables. and it seem like DynamicLight not create draw command.

redstair commented 10 years ago

Can't get it to work either. How did you fix it? Can you please post your code? Thank you very much in advance!

namkazt commented 9 years ago

here is my own code to make it work ( it's really dirty ) In HelloWorld.h

    cocos2d::Sprite* shadowCasters;
    cocos2d::RenderTexture* occlusionMap;
    cocos2d::RenderTexture* shadowMap1D;
    cocos2d::RenderTexture* finalShadowMap;
    cocos2d::GLProgramState* smss;
    cocos2d::GLProgramState* srss;
    cocos2d::Sprite* fsm;
    cocos2d::Point lightPos;

In HelloWorld.cpp ( init function )

    int lightSize = 1000;
    lightPos = Point(visibleSize.width / 2, visibleSize.height / 2);

    GLProgram* shadowMapShader = this->loadShader("shader/pass.vsh", "shader/shadowMap.fsh");
    GLProgram* shadowRenderShader = this->loadShader("shader/pass.vsh", "shader/shadowRender.fsh");

    shadowCasters = Sprite::create("test.png");
    shadowCasters->setPosition(visibleSize.width / 2, visibleSize.height / 2);
    shadowCasters->retain();
    this->addChild(shadowCasters, 200);

    occlusionMap = RenderTexture::create(lightSize, lightSize);
    //occlusionMap->setPosition(visibleSize.width / 2, visibleSize.height / 2);
    occlusionMap->retain();
    shadowMap1D = RenderTexture::create(lightSize, 16);
    //shadowMap1D->setPosition(visibleSize.width / 2, visibleSize.height / 2);
    shadowMap1D->retain();
    finalShadowMap = RenderTexture::create(lightSize, lightSize);
    //finalShadowMap->setPosition(visibleSize.width / 2, visibleSize.height / 2);
    finalShadowMap->retain();

    smss = GLProgramState::getOrCreateWithGLProgram(shadowMapShader);
    smss->setUniformVec2("resolution", Vec2(lightSize, lightSize));
    smss->setUniformFloat("upScale", 1.0);
    smss->setUniformFloat("accuracy", 1.0);

    srss = GLProgramState::getOrCreateWithGLProgram(shadowRenderShader);
    srss->setUniformVec2("resolution", Vec2(lightSize, lightSize));
    srss->setUniformFloat("softShadows", true ? 1.0f : 0.0f);

    Point p1 = shadowCasters->getAnchorPoint();
    Point p2 = shadowCasters->getPosition();
    // Render light region to occluder FBO
    occlusionMap->beginWithClear(0.0, 0.0, 0.0, 0.0);
    //shadowCasters->setAnchorPoint({ 0, 0 });
    //shadowCasters->setPosition({ x, y });
    shadowCasters->visit();
    occlusionMap->end();
    shadowCasters->setAnchorPoint(p1);
    shadowCasters->setPosition(p2);

    // Build a 1D shadow map from occlude FBO

    Sprite* ocM = Sprite::createWithTexture(occlusionMap->getSprite()->getTexture());
    //ocM->setPosition(visibleSize.width / 2, visibleSize.height / 2);
    smss->setUniformTexture("u_texture", ocM->getTexture());
    ocM->setGLProgramState(smss);
    ocM->retain();

    shadowMap1D->beginWithClear(0.0, 0.0, 0.0, 0.0);
    ocM->setAnchorPoint({ 0.5, 0.5 });
    ocM->setPosition({ static_cast<float>(lightSize / 2.0), static_cast<float>(lightSize / 2.0) });
    ocM->visit();
    shadowMap1D->end();

    Sprite* sM1d = Sprite::createWithTexture(shadowMap1D->getSprite()->getTexture());
    //sM1d->setPosition(visibleSize.width / 2, visibleSize.height / 2);
    sM1d->retain();

    srss->setUniformTexture("u_texture", ocM->getTexture());
    srss->setUniformTexture("u_texture2", sM1d->getTexture());

    fsm = Sprite::createWithTexture(finalShadowMap->getSprite()->getTexture());
    fsm->setPosition(visibleSize.width / 2 + (lightSize - visibleSize.width) / 2, visibleSize.height / 2 + (lightSize - visibleSize.height) / 2);
    fsm->setColor({ 255, 255, 255 });
    fsm->setGLProgramState(srss);
    fsm->retain();
    fsm->setScaleY(-1);
    fsm->setBlendFunc({ GL_AMBIENT_AND_DIFFUSE, GL_ONE });
    this->addChild(fsm, 201);

here is load shader function ( from old code )

GLProgram* HelloWorld::loadShader(const GLchar* vertexShader, const GLchar* fragmentShader)
{
    auto shader = ShaderCache::getInstance()->getGLProgram(fragmentShader);
    if (!shader) {
        shader = new GLProgram();
        shader->retain();
        shader->initWithVertexShaderFilename(vertexShader, fragmentShader);
        shader->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
        shader->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
        shader->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
        shader->link();
        shader->updateUniforms();
        shader->use();
    }

    return shader;
}
namkazt commented 9 years ago

as i see many guys want to get this source so i create new repository. Check it out at here : https://github.com/namkazt/NewDynamicLight.

Borisas commented 9 years ago

Getting openGL errors when running your test with cocos2d-x 3.4