VoxelizeClearPass::VoxelizeClearPass(VCTscene* vctScene,
                      kore::EOperationExecutionType executionType) {
  using namespace kore;

  _name = std::string("VoxelizeClear Pass");
  _useGPUProfiling = vctScene->getUseGPUprofiling();
  
  this->setExecutionType(executionType);

  ShaderProgram* shader = new ShaderProgram();
  shader->loadShader("./assets/shader/voxelizeClear.shader",
                 GL_VERTEX_SHADER);
  shader->setName("VoxelizeClear shader");
  shader->init();
  this->setShaderProgram(shader);


  addStartupOperation(new kore::BindBuffer(GL_DRAW_INDIRECT_BUFFER, 
        vctScene->getVoxelFragTex()->getVoxelFragTexIndCmdBuf()->getHandle()));
  addStartupOperation(new ColorMaskOp(glm::bvec4(false, false, false, false)));


  addStartupOperation(new BindImageTexture(
                    vctScene->getVoxelFragTex()->getShdVoxelFragTex(VOXELATT_COLOR),
                    shader->getUniform("voxelFragTex_color")));

  addStartupOperation(new BindImageTexture(
                    vctScene->getVoxelFragTex()->getShdVoxelFragTex(VOXELATT_NORMAL),
                    shader->getUniform("voxelFragTex_normal")));
  
  addStartupOperation(new kore::DrawIndirectOp(GL_POINTS, 0));

  addStartupOperation(new MemoryBarrierOp(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT));
}
LightInjectionPass::LightInjectionPass(VCTscene* vctScene,
                                kore::SceneNode* lightNode,
                                kore::FrameBuffer* shadowMapFBO,
                                kore::EOperationExecutionType executionType) {

  using namespace kore;

  _name = std::string("Light Injection");
  _useGPUProfiling = vctScene->getUseGPUprofiling();

  this->setExecutionType(executionType);
  _vctScene = vctScene;
  _renderMgr = RenderManager::getInstance();
  _sceneMgr = SceneManager::getInstance();
  _resMgr = ResourceManager::getInstance();
  _shadowMapFBO = shadowMapFBO;


  ShaderProgram* shader = new ShaderProgram;

  shader->loadShader("./assets/shader/LightInjectionFrag.shader",
    GL_VERTEX_SHADER);
  shader->setName("light injection shader");
  shader->init();

  this->setShaderProgram(shader);

  kore::TexSamplerProperties texSamplerProps;
  texSamplerProps.wrapping = glm::uvec3(GL_REPEAT, GL_REPEAT, GL_REPEAT);
  texSamplerProps.minfilter = GL_NEAREST;
  texSamplerProps.magfilter = GL_NEAREST;
  texSamplerProps.type = GL_SAMPLER_2D;
  shader->setSamplerProperties(0, texSamplerProps);

  addStartupOperation(new BindBuffer(
    GL_DRAW_INDIRECT_BUFFER,
    _vctScene->getThreadBuf_nodeMap(_vctScene->getNodePool()->getNumLevels() - 1)->getHandle()));

  addStartupOperation(new ColorMaskOp(glm::bvec4(true, true, true, true)));
  
  std::vector<ShaderData>& vSMBufferTex = shadowMapFBO->getOutputs();
  addStartupOperation(new BindTexture(
                         &vSMBufferTex[1],
                          shader->getUniform("smPosition")));

  addStartupOperation(new BindUniform(
                        vctScene->getVoxelGridNode()->getTransform()->getShaderData("inverse model Matrix"),
                        shader->getUniform("voxelGridTransformI")));
  addStartupOperation(new BindUniform(
                        vctScene->getNodePool()->getShdNumLevels(),
                        shader->getUniform("numLevels")));

  kore::LightComponent* lightComp = static_cast<LightComponent*>(lightNode->getComponent(COMPONENT_LIGHT));
  addStartupOperation(new BindUniform(
                         lightComp->getShaderData("color"),
                         shader->getUniform("lightColor")));

  addStartupOperation(new BindUniform(
                          lightComp->getShaderData("direction"),
                          shader->getUniform("lightDir")));

  addStartupOperation(new BindTexture(
                         vctScene->getNodePool()->getShdNodePoolSampler(NEXT),
                         shader->getUniform("nodePool_next")));

  addStartupOperation(new BindTexture(
                        vctScene->getNodePool()->getShdNodePoolSampler(COLOR),
                        shader->getUniform("nodePool_color")));

  addStartupOperation(new BindImageTexture(
                         vctScene->getBrickPool()->getShdBrickPool(BRICKPOOL_IRRADIANCE),
                         shader->getUniform("brickPool_irradiance")));

  addStartupOperation(new BindImageTexture(
                        vctScene->getBrickPool()->getShdBrickPool(BRICKPOOL_COLOR),
                        shader->getUniform("brickPool_color")));

  addStartupOperation(new BindImageTexture(
                      vctScene->getBrickPool()->getShdBrickPool(BRICKPOOL_NORMAL),
                      shader->getUniform("brickPool_normal")));
  
  // Add node map for all levels
  addStartupOperation(new BindImageTexture(vctScene->getShdLightNodeMap(),
                         shader->getUniform("nodeMap")));

  addStartupOperation(new BindUniform(vctScene->getShdNodeMapOffsets(),
                                      shader->getUniform("nodeMapOffset[0]")));

  addStartupOperation(new BindUniform(vctScene->getShdNodeMapSizes(),
                                      shader->getUniform("nodeMapSize[0]")));

  addStartupOperation(new DrawIndirectOp(GL_POINTS, 0));

  this->addFinishOperation(new MemoryBarrierOp(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT));

  
}