예제 #1
0
void BeginStencilCommand::init(float depth, bool inverted, float alphaThreshold, Node* stencil, bool clearStencil)
{
    _globalOrder = depth;
    _inverted = inverted;
    _alphaThreshold = alphaThreshold;
    _stencil = stencil;
    _clearStencil = clearStencil;
    
    if (_stencil && _alphaThreshold < 1)
    {
#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
#else
        // since glAlphaTest do not exists in OES, use a shader that writes
        // pixel only if greater than an alpha threshold
        GLProgram *program = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_ALPHA_TEST_NO_MV);
        GLint alphaValueLocation = glGetUniformLocation(program->getProgram(), GLProgram::UNIFORM_NAME_ALPHA_TEST_VALUE);
        // set our alphaThreshold
        program->use();
        program->setUniformLocationWith1f(alphaValueLocation, _alphaThreshold);
        // we need to recursively apply this shader to all the nodes in the stencil node
        // FIXME: we should have a way to apply shader to all nodes without having to do this
        setProgram(_stencil, program);
#endif
    }
}
예제 #2
0
void ShaderNode::loadShaderVertex(const char *vert, const char *frag)
{
    GLProgram *shader = new GLProgram();
    shader->initWithVertexShaderFilename(vert, frag);

    shader->addAttribute("aVertex", GLProgram::VERTEX_ATTRIB_POSITION);
    shader->link();

    shader->updateUniforms();

    _uniformCenter = glGetUniformLocation(shader->getProgram(), "center");
    _uniformResolution = glGetUniformLocation(shader->getProgram(), "resolution");
    _uniformTime = glGetUniformLocation(shader->getProgram(), "time");

    this->setShaderProgram(shader);

    shader->release();
}
void LayerShaderStudy05::initData()
{
    GLProgram* pProgram = GLProgram::createWithFilenames("res/shader_study/pos_col_uniform.vert", "res/shader_study/pos_col_uniform.frag");
    setGLProgram(pProgram);
    
    Size winSize = Director::getInstance()->getWinSize();
    GLfloat vertexlist[] = {
        0.0f,0.0f,
        winSize.width,0.0f,
        winSize.width*0.5f,winSize.height};
    
    // gen bind vao
    glGenVertexArrays(1, &m_vao);
    glBindVertexArray(m_vao);
    // gen bind vbo
    glGenBuffers(1, &m_vbo);
    glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexlist), vertexlist, GL_STREAM_DRAW);
    
    // input params
    GLuint attributePositionID = glGetAttribLocation(pProgram->getProgram(), "a_position");
    // vertex
    glEnableVertexAttribArray(attributePositionID);
    //    glVertexAttribPointer(attributePositionID, 2, GL_FLOAT, GL_FALSE, sizeof(V2F_C4B_T2F), (GLvoid *)offsetof(V2F_C4B_T2F, vertices));
    // 注意:stride参数是取了 2-GL_FLOAT 的内容后的偏移值,所以此处为0 可以理解为第一个参数和第二个参数之间的内存间隔,上面注释内容是从Demo3和Demo4中取得的代码,可以和此处进行对比,则理解更为透彻
    // 而最后一个参数,是在数组中需要访问数据的起始地址,是相对于数组的地址,而不是内存的地址
    glVertexAttribPointer(attributePositionID, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
    
    // uniform
    GLuint uniformColorID = glGetUniformLocation(pProgram->getProgram(), "u_color");
    glUniform4f(uniformColorID, 0, 0, 1, 1);
    
    // clear
    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    
    CHECK_GL_ERROR_DEBUG();
}
예제 #4
0
void FSprite::InitShader(const std::string& alpha_file)
{
#ifdef ETC1
    //Shader
    GLProgram* glp = new GLProgram();
    glp->autorelease();
    
    glp->initWithFilenames("testv.vsh", "test.fsh");
    glp->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
    glp->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
    glp->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORD);
    glp->link();
    glp->updateUniforms();
    
    opacity_location_ = glGetUniformLocation(glp->getProgram(), "u_opacity");
    
    current_alpha_file_ = alpha_file;
    
//  #pragma message WARN("getTextureForKey or someth else, texture should be added on loading scene, do not add (cocos should check that anyway but still dont do it)  all the time!!")
    Texture2D* tex = Director::getInstance()->getTextureCache()->addImage(alpha_file);
	setBlendFunc(BlendFunc({ GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA }));
    //setBlendFunc((BlendFunc) { GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA });
    
    GLProgramState* glprogramstate = GLProgramState::getOrCreateWithGLProgram(glp);
    
    setGLProgramState(glprogramstate);
    
    glprogramstate->setUniformFloat(opacity_location_, (float)getOpacity()/255.0);
    
    glprogramstate->setUniformTexture("u_texture1", tex);
    

    
    setGLProgram(glp);
#endif
}
예제 #5
0
void ClippingNode::visit(Renderer *renderer, const Mat4 &parentTransform, uint32_t parentFlags)
{
    if (!_visible || !hasContent())
        return;
    
    uint32_t flags = processParentFlags(parentTransform, parentFlags);

    // IMPORTANT:
    // To ease the migration to v3.0, we still support the Mat4 stack,
    // but it is deprecated and your code should not rely on it
    Director* director = Director::getInstance();
    CCASSERT(nullptr != director, "Director is null when setting matrix stack");
    director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
    director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, _modelViewTransform);

    //Add group command
        
    _groupCommand.init(_globalZOrder);
    renderer->addCommand(&_groupCommand);

    renderer->pushGroup(_groupCommand.getRenderQueueID());

    _beforeVisitCmd.init(_globalZOrder);
    _beforeVisitCmd.func = CC_CALLBACK_0(StencilStateManager::onBeforeVisit, _stencilStateManager);
    renderer->addCommand(&_beforeVisitCmd);
    
    auto alphaThreshold = this->getAlphaThreshold();
    if (alphaThreshold < 1)
    {
#if CC_CLIPPING_NODE_OPENGLES
        // since glAlphaTest do not exists in OES, use a shader that writes
        // pixel only if greater than an alpha threshold
        GLProgram *program = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_ALPHA_TEST_NO_MV);
        GLint alphaValueLocation = glGetUniformLocation(program->getProgram(), GLProgram::UNIFORM_NAME_ALPHA_TEST_VALUE);
        // set our alphaThreshold
        program->use();
        program->setUniformLocationWith1f(alphaValueLocation, alphaThreshold);
        // we need to recursively apply this shader to all the nodes in the stencil node
        // FIXME: we should have a way to apply shader to all nodes without having to do this
        setProgram(_stencil, program);
#endif

    }
    _stencil->visit(renderer, _modelViewTransform, flags);

    _afterDrawStencilCmd.init(_globalZOrder);
    _afterDrawStencilCmd.func = CC_CALLBACK_0(StencilStateManager::onAfterDrawStencil, _stencilStateManager);
    renderer->addCommand(&_afterDrawStencilCmd);

    int i = 0;
    bool visibleByCamera = isVisitableByVisitingCamera();
    
    if(!_children.empty())
    {
        sortAllChildren();
        // draw children zOrder < 0
        for(auto size = _children.size(); i < size; ++i)
        {
            auto node = _children.at(i);
            
            if ( node && node->getLocalZOrder() < 0 )
                node->visit(renderer, _modelViewTransform, flags);
            else
                break;
        }
        // self draw
        if (visibleByCamera)
            this->draw(renderer, _modelViewTransform, flags);

        for(auto it=_children.cbegin()+i, itCend = _children.cend(); it != itCend; ++it)
            (*it)->visit(renderer, _modelViewTransform, flags);
    }
    else if (visibleByCamera)
    {
        this->draw(renderer, _modelViewTransform, flags);
    }

    _afterVisitCmd.init(_globalZOrder);
    _afterVisitCmd.func = CC_CALLBACK_0(StencilStateManager::onAfterVisit, _stencilStateManager);
    renderer->addCommand(&_afterVisitCmd);

    renderer->popGroup();
    
    director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
}
예제 #6
0
void ClippingNode::visit()
{
    if(!_visible)
        return;
    
    kmGLPushMatrix();
    transform();
    //Add group command
    
    Renderer* renderer = Director::getInstance()->getRenderer();
    
    _groupCommand.init(0,_vertexZ);
    renderer->addCommand(&_groupCommand);

    renderer->pushGroup(_groupCommand.getRenderQueueID());

    _beforeVisitCmd.init(0,_vertexZ);
    _beforeVisitCmd.func = CC_CALLBACK_0(ClippingNode::onBeforeVisit, this);
    renderer->addCommand(&_beforeVisitCmd);
    if (_alphaThreshold < 1)
    {
#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WINDOWS || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
#else
        // since glAlphaTest do not exists in OES, use a shader that writes
        // pixel only if greater than an alpha threshold
        GLProgram *program = ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_ALPHA_TEST);
        GLint alphaValueLocation = glGetUniformLocation(program->getProgram(), GLProgram::UNIFORM_NAME_ALPHA_TEST_VALUE);
        // set our alphaThreshold
        program->use();
        program->setUniformLocationWith1f(alphaValueLocation, _alphaThreshold);
        // we need to recursively apply this shader to all the nodes in the stencil node
        // XXX: we should have a way to apply shader to all nodes without having to do this
        setProgram(_stencil, program);
        
#endif

    }
    _stencil->visit();

    _afterDrawStencilCmd.init(0,_vertexZ);
    _afterDrawStencilCmd.func = CC_CALLBACK_0(ClippingNode::onAfterDrawStencil, this);
    renderer->addCommand(&_afterDrawStencilCmd);

    int i = 0;
    
    if(!_children.empty())
    {
        sortAllChildren();
        // draw children zOrder < 0
        for( ; i < _children.size(); i++ )
        {
            auto node = _children.at(i);
            
            if ( node && node->getZOrder() < 0 )
                node->visit();
            else
                break;
        }
        // self draw
        this->draw();
        
        for(auto it=_children.cbegin()+i; it != _children.cend(); ++it)
            (*it)->visit();
    }
    else
    {
        this->draw();
    }

    _afterVisitCmd.init(0,_vertexZ);
    _afterVisitCmd.func = CC_CALLBACK_0(ClippingNode::onAfterVisit, this);
    renderer->addCommand(&_afterVisitCmd);

    renderer->popGroup();
    
    kmGLPopMatrix();
}
예제 #7
0
void ClippingNode::visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated)
{
    if(!_visible)
        return;
    
    bool dirty = parentTransformUpdated || _transformUpdated;
    if(dirty)
        _modelViewTransform = transform(parentTransform);
    _transformUpdated = false;

    // IMPORTANT:
    // To ease the migration to v3.0, we still support the kmGL stack,
    // but it is deprecated and your code should not rely on it
    kmGLPushMatrix();
    kmGLLoadMatrix(&_modelViewTransform);

    //Add group command
        
    _groupCommand.init(_globalZOrder);
    renderer->addCommand(&_groupCommand);

    renderer->pushGroup(_groupCommand.getRenderQueueID());

    _beforeVisitCmd.init(_globalZOrder);
    _beforeVisitCmd.func = CC_CALLBACK_0(ClippingNode::onBeforeVisit, this);
    renderer->addCommand(&_beforeVisitCmd);
    if (_alphaThreshold < 1)
    {
#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WINDOWS || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
#else
        // since glAlphaTest do not exists in OES, use a shader that writes
        // pixel only if greater than an alpha threshold
        GLProgram *program = ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_ALPHA_TEST_NO_MV);
        GLint alphaValueLocation = glGetUniformLocation(program->getProgram(), GLProgram::UNIFORM_NAME_ALPHA_TEST_VALUE);
        // set our alphaThreshold
        program->use();
        program->setUniformLocationWith1f(alphaValueLocation, _alphaThreshold);
        // we need to recursively apply this shader to all the nodes in the stencil node
        // XXX: we should have a way to apply shader to all nodes without having to do this
        setProgram(_stencil, program);
        
#endif

    }
    _stencil->visit(renderer, _modelViewTransform, dirty);

    _afterDrawStencilCmd.init(_globalZOrder);
    _afterDrawStencilCmd.func = CC_CALLBACK_0(ClippingNode::onAfterDrawStencil, this);
    renderer->addCommand(&_afterDrawStencilCmd);

    int i = 0;
    
    if(!_children.empty())
    {
        sortAllChildren();
        // draw children zOrder < 0
        for( ; i < _children.size(); i++ )
        {
            auto node = _children.at(i);
            
            if ( node && node->getLocalZOrder() < 0 )
                node->visit(renderer, _modelViewTransform, dirty);
            else
                break;
        }
        // self draw
        this->draw(renderer, _modelViewTransform, dirty);
        
        for(auto it=_children.cbegin()+i; it != _children.cend(); ++it)
            (*it)->visit(renderer, _modelViewTransform, dirty);
    }
    else
    {
        this->draw(renderer, _modelViewTransform, dirty);
    }

    _afterVisitCmd.init(_globalZOrder);
    _afterVisitCmd.func = CC_CALLBACK_0(ClippingNode::onAfterVisit, this);
    renderer->addCommand(&_afterVisitCmd);

    renderer->popGroup();
    
    kmGLPopMatrix();
}