//----------------------------------------------------------------------- void PUBillboardChain::init( const std::string &texFile ) { GLProgram* glProgram = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_3D_PARTICLE_COLOR); if (!texFile.empty()) { auto tex = Director::getInstance()->getTextureCache()->addImage(texFile); if (tex) { _texture = tex; glProgram = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_3D_PARTICLE_TEXTURE); } } auto glProgramState = GLProgramState::create(glProgram); glProgramState->retain(); GLsizei stride = sizeof(VertexInfo); glProgramState->setVertexAttribPointer(s_attributeNames[GLProgram::VERTEX_ATTRIB_POSITION], 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*)offsetof(VertexInfo, position)); glProgramState->setVertexAttribPointer(s_attributeNames[GLProgram::VERTEX_ATTRIB_TEX_COORD], 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*)offsetof(VertexInfo, uv)); glProgramState->setVertexAttribPointer(s_attributeNames[GLProgram::VERTEX_ATTRIB_COLOR], 4, GL_FLOAT, GL_FALSE, stride, (GLvoid*)offsetof(VertexInfo, color)); _glProgramState = glProgramState; _meshCommand = new (std::nothrow) MeshCommand(); _meshCommand->setTransparent(true); _meshCommand->setDepthTestEnabled(true); _meshCommand->setDepthWriteEnabled(false); _meshCommand->setCullFace(GL_BACK); _meshCommand->setCullFaceEnabled(true); }
/** * Draws the model * * @param transform Transform matrix * @param flags Flags to draw */ void NewParametricShaderNode::onDraw(const Mat4 &transform, uint32_t flags) { setCommon3dEnvironment(); auto glProgramState = getGLProgramState(); // Pass the position parameter to the vertex shader's attribute variable glProgramState->setVertexAttribPointer("a_position", 3, GL_FLOAT, GL_FALSE, 44, _vertices[0].position); glProgramState->setVertexAttribPointer("a_normal", 3, GL_FLOAT, GL_FALSE, 44, _vertices[0].normal); glProgramState->setVertexAttribPointer("a_texCoord", 2, GL_FLOAT, GL_FALSE, 44, _vertices[0].texCoord); glProgramState->setVertexAttribPointer("a_tangent", 3, GL_FLOAT, GL_FALSE, 44, _vertices[0].tangent); glProgramState->apply(transform); glEnable(GL_DEPTH_TEST); glCullFace(GL_BACK); // glCullFace(GL_FRONT); glEnable(GL_CULL_FACE); // Alpha blenfing // glEnable(GL_BLEND); // glDisable(GL_BLEND); // glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // glBlendFunc(GL_ONE, GL_ONE); // Draw triangles using indices glDrawElements(GL_TRIANGLES, _numIndices, GL_UNSIGNED_SHORT, _indices); // glDisable(GL_BLEND); // CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, 3); }
bool PUParticle3DEntityRender::initRender( const std::string &texFile ) { GLProgram* glProgram = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_3D_PARTICLE_COLOR); if (!texFile.empty()) { auto tex = Director::getInstance()->getTextureCache()->addImage(texFile); if (tex) { _texture = tex; glProgram = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_3D_PARTICLE_TEXTURE); } else _texture = nullptr; } auto glProgramState = GLProgramState::create(glProgram); glProgramState->retain(); GLsizei stride = sizeof(VertexInfo); glProgramState->setVertexAttribPointer(s_attributeNames[GLProgram::VERTEX_ATTRIB_POSITION], 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*)offsetof(VertexInfo, position)); glProgramState->setVertexAttribPointer(s_attributeNames[GLProgram::VERTEX_ATTRIB_TEX_COORD], 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*)offsetof(VertexInfo, uv)); glProgramState->setVertexAttribPointer(s_attributeNames[GLProgram::VERTEX_ATTRIB_COLOR], 4, GL_FLOAT, GL_FALSE, stride, (GLvoid*)offsetof(VertexInfo, color)); _glProgramState = glProgramState; _meshCommand = new (std::nothrow) MeshCommand(); _meshCommand->setSkipBatching(true); _meshCommand->setTransparent(true); _stateBlock->setDepthTest(_depthTest); _stateBlock->setDepthWrite(_depthWrite); _stateBlock->setCullFaceSide(RenderState::CULL_FACE_SIDE_BACK); _stateBlock->setCullFace(true); return true; }
/** * Draw a primitive. * * @param transform Transform matrix * @param flags Flags to draw */ void ShaderTextureNode::onDraw(const Mat4 &transform, uint32_t flags) { GLfloat vertices[48] = { -1, -1, 0, 1, 1, 1, 1, 1, // Lower-Left 1, -1, 1, 1, 1, 1, 1, 1, // Lower-Right 1, 1, 1, 0, 1, 1, 1, 1, // Upper-Right -1, -1, 0, 1, 1, 1, 1, 1, // Lower-Left 1, 1, 1, 0, 1, 1, 1, 1, // Upper-Right -1, 1, 0, 0, 1, 1, 1, 1, // Upper-Left }; auto glProgramState = getGLProgramState(); glProgramState->setVertexAttribPointer("a_position", 2, GL_FLOAT, GL_FALSE, 32, vertices); glProgramState->setVertexAttribPointer("a_texCoord", 2, GL_FLOAT, GL_FALSE, 32, vertices + 2); glProgramState->setVertexAttribPointer("a_color", 4, GL_FLOAT, GL_FALSE, 32, vertices + 4); glProgramState->apply(transform); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glDisable(GL_DEPTH_TEST); glCullFace(GL_BACK); glEnable(GL_CULL_FACE); // Alpha blending // glEnable(GL_BLEND); // glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDrawArrays(GL_TRIANGLES, 0, 6); // glDisable(GL_BLEND); CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, 6); }
void Sprite3D::genGLProgramState(bool useLight) { _shaderUsingLight = useLight; std::unordered_map<const MeshVertexData*, GLProgramState*> glProgramestates; for(auto& mesh : _meshVertexDatas) { bool textured = mesh->hasVertexAttrib(GLProgram::VERTEX_ATTRIB_TEX_COORD); bool hasSkin = mesh->hasVertexAttrib(GLProgram::VERTEX_ATTRIB_BLEND_INDEX) && mesh->hasVertexAttrib(GLProgram::VERTEX_ATTRIB_BLEND_WEIGHT); bool hasNormal = mesh->hasVertexAttrib(GLProgram::VERTEX_ATTRIB_NORMAL); GLProgram* glProgram = nullptr; const char* shader = nullptr; if(textured) { if (hasSkin) { if (hasNormal && _shaderUsingLight) shader = GLProgram::SHADER_3D_SKINPOSITION_NORMAL_TEXTURE; else shader = GLProgram::SHADER_3D_SKINPOSITION_TEXTURE; } else { if (hasNormal && _shaderUsingLight) shader = GLProgram::SHADER_3D_POSITION_NORMAL_TEXTURE; else shader = GLProgram::SHADER_3D_POSITION_TEXTURE; } } else { shader = GLProgram::SHADER_3D_POSITION; } if (shader) glProgram = GLProgramCache::getInstance()->getGLProgram(shader); auto programstate = GLProgramState::create(glProgram); long offset = 0; auto attributeCount = mesh->getMeshVertexAttribCount(); for (auto k = 0; k < attributeCount; k++) { auto meshattribute = mesh->getMeshVertexAttrib(k); programstate->setVertexAttribPointer(s_attributeNames[meshattribute.vertexAttrib], meshattribute.size, meshattribute.type, GL_FALSE, static_cast<GLsizei>(mesh->getVertexBuffer()->getElementSize()), (GLvoid*)offset); offset += meshattribute.attribSizeBytes; } glProgramestates[mesh] = programstate; } for (auto& it : _meshes) { auto glProgramState = glProgramestates[it->getMeshIndexData()->getMeshVertexData()]; it->setGLProgramState(glProgramState); } }
void ShaderNode::onDraw(const Mat4 &transform, uint32_t flags) { float w = SIZE_X, h = SIZE_Y; GLfloat vertices[12] = {0,0, w,0, w,h, 0,0, 0,h, w,h}; auto glProgramState = getGLProgramState(); glProgramState->setVertexAttribPointer("a_position", 2, GL_FLOAT, GL_FALSE, 0, vertices); glProgramState->apply(transform); glDrawArrays(GL_TRIANGLES, 0, 6); CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,6); }
bool Skybox::init() { // create and set our custom shader auto shader = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_3D_SKYBOX); auto state = GLProgramState::create(shader); state->setVertexAttribPointer(GLProgram::ATTRIBUTE_NAME_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(Vec3), nullptr); setGLProgramState(state); initBuffers(); CHECK_GL_ERROR_DEBUG(); return true; }
/// Draw a vertex array void RendererOpenGL::draw(const VertexArray2D& varray, const RenderState& state) { const char* data = reinterpret_cast<const char*>(&varray.m_vertices[0]); if(m_activeShader) { enableVertexAttribArray(0); enableVertexAttribArray(1); enableVertexAttribArray(2); setVertexAttribPointer(0, 2, GL_FLOAT, false, sizeof(VertexArray2D::Vertex), data + 0); setVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, true, sizeof(VertexArray2D::Vertex), data + 8); setVertexAttribPointer(2, 2, GL_FLOAT, false, sizeof(VertexArray2D::Vertex), data + 12); drawArrays(varray.geometryType, 0, varray.m_vertices.size()); disableVertexAttribArray(0); disableVertexAttribArray(1); disableVertexAttribArray(2); } else { glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2, GL_FLOAT, sizeof(VertexArray2D::Vertex), data + 0); glColorPointer(4, GL_UNSIGNED_BYTE,sizeof(VertexArray2D::Vertex), data + 8); glTexCoordPointer(2, GL_FLOAT, sizeof(VertexArray2D::Vertex), data + 12); drawArrays(varray.geometryType, 0, varray.m_vertices.size()); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); } }
void VertexArrayObject::bind() const { useProgram(); switch (vaoSupported_) { case VaoSupported::CHECK_SUPPORTED: if (mw::Window::getOpenGlMajorVersion() >= 3) { vaoSupported_ = VaoSupported::SUPPORTED; // Fall trough to next case. } else { vaoSupported_ = VaoSupported::NOT_SUPPORTED; bindBuffer(); setVertexAttribPointer(); break; } case VaoSupported::SUPPORTED: if (*vao_ == 0) { // Create the vertex array only the first time. glGenVertexArrays(1, &*vao_); glBindVertexArray(*vao_); checkGlError(); // Remove the block to unneeded calls to buffer changes. VertexBufferObject::setIgnoreCurrentBind(true); bindBuffer(); // Restore the block. VertexBufferObject::setIgnoreCurrentBind(false); currentVertexArrayObject = *vao_; setVertexAttribPointer(); } else { glBindVertexArray(*vao_); checkGlError(); } break; case VaoSupported::NOT_SUPPORTED: bindBuffer(); setVertexAttribPointer(); break; } }
//波光效果动画 void Tortoise::initUVAnimation() { // 将vsh与fsh装配成一个完整的Shader文件。 auto glprogram = GLProgram::createWithFilenames("3D/UVAnimation.vsh", "3D/UVAnimation.fsh"); // 由Shader文件创建这个Shader auto glprogramstate = GLProgramState::getOrCreateWithGLProgram(glprogram); // 给精灵设置所用的Shader _sprite->setGLProgramState(glprogramstate); //创建海龟所用的贴图。 auto textrue1 = Director::getInstance()->getTextureCache()->addImage("3D/tortoise.png"); //将贴图设置给Shader中的变量值u_texture1 glprogramstate->setUniformTexture("u_texture1", textrue1); //创建波光贴图。 auto textrue2 = Director::getInstance()->getTextureCache()->addImage("3D/caustics.png"); //将贴图设置给Shader中的变量值u_lightTexture glprogramstate->setUniformTexture("u_lightTexture", textrue2); //注意,对于波光贴图,我们希望它在进行UV动画时能产生四方连续效果,必须设置它的纹理UV寻址方式为GL_REPEAT。 Texture2D::TexParams tRepeatParams; tRepeatParams.magFilter = GL_LINEAR_MIPMAP_LINEAR; tRepeatParams.minFilter = GL_LINEAR; tRepeatParams.wrapS = GL_REPEAT; tRepeatParams.wrapT = GL_REPEAT; textrue2->setTexParameters(tRepeatParams); //在这里,我们设置一个波光的颜色,这里设置为白色。 Vec4 tLightColor(1.0,1.0,1.0,1.0); glprogramstate->setUniformVec4("v_LightColor",tLightColor); //下面这一段,是为了将我们自定义的Shader与我们的模型顶点组织方式进行匹配。模型的顶点数据一般包括位置,法线,色彩,纹理,以及骨骼绑定信息。而Shader需要将内部相应的顶点属性通道与模型相应的顶点属性数据进行绑定才能正确显示出顶点。 long offset = 0; auto attributeCount = _sprite->getMesh()->getMeshVertexAttribCount(); for (auto k = 0; k < attributeCount; k++) { auto meshattribute = _sprite->getMesh()->getMeshVertexAttribute(k); glprogramstate->setVertexAttribPointer(s_attributeNames[meshattribute.vertexAttrib], meshattribute.size, meshattribute.type, GL_FALSE, _sprite->getMesh()->getVertexSizeInBytes(), (GLvoid*)offset); offset += meshattribute.attribSizeBytes; } //uv滚动初始值设为0 _lightAni.x = _lightAni.y = 0; }//end initUVAnimation
void Sprite3D::genGLProgramState() { auto programstate = GLProgramState::getOrCreateWithGLProgram(getDefaultGLProgram(_mesh->hasVertexAttrib(GLProgram::VERTEX_ATTRIB_TEX_COORD))); long offset = 0; auto attributeCount = _mesh->getMeshVertexAttribCount(); for (auto k = 0; k < attributeCount; k++) { auto meshattribute = _mesh->getMeshVertexAttribute(k); programstate->setVertexAttribPointer(s_attributeNames[meshattribute.vertexAttrib], meshattribute.size, meshattribute.type, GL_FALSE, _mesh->getVertexSizeInBytes(), (GLvoid*)offset); offset += meshattribute.attribSizeBytes; } setGLProgramState(programstate); }
void Sprite3D::genGLProgramState() { std::unordered_map<const MeshVertexData*, GLProgramState*> glProgramestates; for(auto& mesh : _meshVertexDatas) { bool textured = mesh->hasVertexAttrib(GLProgram::VERTEX_ATTRIB_TEX_COORD); bool hasSkin = mesh->hasVertexAttrib(GLProgram::VERTEX_ATTRIB_BLEND_INDEX) && mesh->hasVertexAttrib(GLProgram::VERTEX_ATTRIB_BLEND_WEIGHT); GLProgram* glProgram = nullptr; if(textured) { if (hasSkin) glProgram = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_3D_SKINPOSITION_TEXTURE); else glProgram = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_3D_POSITION_TEXTURE); } else { glProgram = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_3D_POSITION); } auto programstate = GLProgramState::create(glProgram); long offset = 0; auto attributeCount = mesh->getMeshVertexAttribCount(); for (auto k = 0; k < attributeCount; k++) { auto meshattribute = mesh->getMeshVertexAttrib(k); programstate->setVertexAttribPointer(s_attributeNames[meshattribute.vertexAttrib], meshattribute.size, meshattribute.type, GL_FALSE, mesh->getVertexBuffer()->getSizePerVertex(), (GLvoid*)offset); offset += meshattribute.attribSizeBytes; } glProgramestates[mesh] = programstate; } for (auto& it : _meshes) { auto glProgramState = glProgramestates[it->getMeshIndexData()->getMeshVertexData()]; it->setGLProgramState(glProgramState); } }
bool VertexAttribBinding::init(MeshIndexData* meshIndexData, GLProgramState* glProgramState) { CCASSERT(meshIndexData && glProgramState, "Invalid arguments"); // One-time initialization. if (__maxVertexAttribs == 0) { GLint temp; glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &temp); __maxVertexAttribs = temp; if (__maxVertexAttribs <= 0) { CCLOGERROR("The maximum number of vertex attributes supported by OpenGL on the current device is 0 or less."); return false; } } _meshIndexData = meshIndexData; _meshIndexData->retain(); _glProgramState = glProgramState; _glProgramState->retain(); auto meshVertexData = meshIndexData->getMeshVertexData(); auto attributeCount = meshVertexData->getMeshVertexAttribCount(); // Parse and set attributes parseAttributes(); long offset = 0; for (auto k = 0; k < attributeCount; k++) { auto meshattribute = meshVertexData->getMeshVertexAttrib(k); setVertexAttribPointer( s_attributeNames[meshattribute.vertexAttrib], meshattribute.size, meshattribute.type, GL_FALSE, meshVertexData->getVertexBuffer()->getSizePerVertex(), (GLvoid*)offset); offset += meshattribute.attribSizeBytes; } // VAO hardware if (Configuration::getInstance()->supportsShareableVAO()) { glGenVertexArrays(1, &_handle); GL::bindVAO(_handle); glBindBuffer(GL_ARRAY_BUFFER, meshVertexData->getVertexBuffer()->getVBO()); auto flags = _vertexAttribsFlags; for (int i = 0; flags > 0; i++) { int flag = 1 << i; if (flag & flags) glEnableVertexAttribArray(i); flags &= ~flag; } glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, meshIndexData->getIndexBuffer()->getVBO()); for(auto &attribute : _attributes) { attribute.second.apply(); } GL::bindVAO(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } return true; }
bool FishLayer::init() { //加载模型文件 std::string fileName = "tortoise.c3b"; m_Sprite = Sprite3D::create(fileName); m_Sprite->setScale(0.1f); auto s = Director::getInstance()->getWinSize(); m_Sprite->setPosition(Vec2(s.width / 2.f, s.height / 2.f)); addChild(m_Sprite); //获取骨骼动画信息 m_Animation3D = Animation3D::create(fileName); if (m_Animation3D) { //从起始到1.933秒截取为游泳动作 m_Swim = Animate3D::create(m_Animation3D, 0.f, 1.933f); m_Swim->retain(); //让精灵循环播放游泳和的受伤动作 Sequence* pSequence = Sequence::create(m_Swim,NULL); m_Sprite->runAction(RepeatForever::create(pSequence)); } // 将vsh与fsh装配成一个完整的Shader文件。 auto glprogram = GLProgram::createWithFilenames("UVAnimation.vsh", "UVAnimation.fsh"); // 由Shader文件创建这个Shader auto glprogramstate = GLProgramState::getOrCreateWithGLProgram(glprogram); // 给精灵设置所用的Shader m_Sprite->setGLProgramState(glprogramstate); //创建海龟所用的贴图。 auto textrue1 = Director::getInstance()->getTextureCache()->addImage("tortoise.png"); //将贴图设置给Shader中的变量值u_texture1 glprogramstate->setUniformTexture("u_texture1", textrue1); //创建波光贴图。 auto textrue2 = Director::getInstance()->getTextureCache()->addImage("caustics.png"); //将贴图设置给Shader中的变量值u_lightTexture glprogramstate->setUniformTexture("u_lightTexture", textrue2); //注意,对于波光贴图,我们希望它在进行UV动画时能产生四方连续效果,必须设置它的纹理UV寻址方式为GL_REPEAT。 Texture2D::TexParams tRepeatParams; tRepeatParams.magFilter = GL_LINEAR_MIPMAP_LINEAR; tRepeatParams.minFilter = GL_LINEAR; tRepeatParams.wrapS = GL_REPEAT; tRepeatParams.wrapT = GL_REPEAT; textrue2->setTexParameters(tRepeatParams); //在这里,我们设置一个波光的颜色,这里设置为白色。 Vec4 tLightColor(1.0,1.0,1.0,1.0); glprogramstate->setUniformVec4("v_LightColor",tLightColor); //下面这一段,是为了将我们自定义的Shader与我们的模型顶点组织方式进行匹配。模型的顶点数据一般包括位置,法线,色彩,纹理,以及骨骼绑定信息。而Shader需要将内部相应的顶点属性通道与模型相应的顶点属性数据进行绑定才能正确显示出顶点。 long offset = 0; auto attributeCount = m_Sprite->getMesh()->getMeshVertexAttribCount(); for (auto k = 0; k < attributeCount; k++) { auto meshattribute = m_Sprite->getMesh()->getMeshVertexAttribute(k); glprogramstate->setVertexAttribPointer(s_attributeNames[meshattribute.vertexAttrib], meshattribute.size, meshattribute.type, GL_FALSE, m_Sprite->getMesh()->getVertexSizeInBytes(), (GLvoid*)offset); offset += meshattribute.attribSizeBytes; } //uv滚动初始值设为0 m_LightAni.x = m_LightAni.y = 0; return true; }