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 } }
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(); }
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 }
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); }
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(); }
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(); }