void PUBillboardChain::render( Renderer* renderer, const Mat4 &transform, ParticleSystem3D* particleSystem ) { auto camera = Camera::getVisitingCamera(); auto cameraMat = camera->getNodeToWorldTransform(); if (!_chainSegmentList.empty()) { updateVertexBuffer(cameraMat); updateIndexBuffer(); if (!_vertices.empty() && !_indices.empty()) { GLuint texId = this->getTextureName(); _stateBlock->setBlendFunc(particleSystem->getBlendFunc()); _meshCommand->init(0, texId, _glProgramState, _stateBlock, _vertexBuffer->getVBO(), _indexBuffer->getVBO(), GL_TRIANGLES, GL_UNSIGNED_SHORT, _indices.size(), transform, Node::FLAGS_RENDER_AS_3D); _meshCommand->setSkipBatching(true); _meshCommand->setTransparent(true); _glProgramState->setUniformVec4("u_color", Vec4(1,1,1,1)); renderer->addCommand(_meshCommand); } } }
//----------------------------------------------------------------------- bool BillboardChain::preRender(SceneManager* sm, RenderSystem* rsys) { // Retrieve the current viewport from the scene manager. // The viewport is only valid during a viewport update. Viewport *currentViewport = sm->getCurrentViewport(); if( !currentViewport ) return false; updateVertexBuffer(currentViewport->getCamera()); return true; }
void LightInstanceBatchHW::injectRender() { if( (mRenderOperation.numberOfInstances = updateVertexBuffer( mCurrentCamera )) ) { Technique* tech = mMaterial->getBestTechnique(); for (size_t i=0; i<tech->getNumPasses(); ++i) { mManager->_injectRenderWithPass(tech->getPass(i), this, false); } } }
void av::osg::TriangleContainer::evaluateLocalSideEffect() { Geometry::evaluateLocalSideEffect(); if(mVecFieldHasChanged) updateVertexBuffer(); if(mColorFieldHasChanged) updateColor(); if(mModeFieldHasChanged) updateMode(); if(mNormalFieldHasChanged) updateNormal(); }
//--------------------------------------------------------------------- void TerrainQuadTreeNode::updateVertexData(bool positions, bool deltas, const Rect& rect, bool cpuData) { if (rect.left <= mBoundaryX || rect.right > mOffsetX || rect.top <= mBoundaryY || rect.bottom > mOffsetY) { // Do we have vertex data? if (mVertexDataRecord) { // Trim to our bounds Rect updateRect(mOffsetX, mOffsetY, mBoundaryX, mBoundaryY); updateRect.left = std::max(updateRect.left, rect.left); updateRect.right = std::min(updateRect.right, rect.right); updateRect.top = std::max(updateRect.top, rect.top); updateRect.bottom = std::min(updateRect.bottom, rect.bottom); // update the GPU buffer directly // TODO: do we have no use for CPU vertex data after initial load? // if so, destroy it to free RAM, this should be fast enough to // to direct if(!cpuData) { if(mVertexDataRecord->gpuPosVertexBuf == NULL) createGpuVertexData(); } updateVertexBuffer(updateRect); } // pass on to children if (!isLeaf()) { for (int i = 0; i < 4; ++i) { mChildren[i]->updateVertexData(positions, deltas, rect, cpuData); // merge bounds from children AABB childBox = mChildren[i]->getAABB(); // this box is relative to child centre VEC3 boxoffset = mChildren[i]->getLocalCentre() - getLocalCentre(); childBox.m_minCorner = childBox.m_minCorner + boxoffset; childBox.m_maxCorner = childBox.m_maxCorner + boxoffset; mAABB.Merge(childBox); } } } }
//----------------------------------------------------------------------- void LightInstanceBatchHW::setStaticAndUpdate( bool bStatic ) { //We were dirty but didn't update bounds. Do it now. if( mKeepStatic && mBoundsDirty ) mCreator->_addDirtyBatch( this ); mKeepStatic = bStatic; if( mKeepStatic ) { //One final update, since there will be none from now on //(except further calls to this function). Pass NULL because //we want to include only those who were added to the scene //but we don't want to perform culling mRenderOperation.numberOfInstances = updateVertexBuffer( 0 ); } }
void Canvas::renderSprites(vector<Sprite*> &sprites, kick::EngineUniforms *engineUniforms, Material* replacementMaterial) { if (sprites.size() == 0){ return; } updateVertexBuffer(sprites); auto mat = replacementMaterial ? replacementMaterial : mMaterial; if (!replacementMaterial ){ mMaterial->setShader(sprites[0]->textureAtlas()->shader()); mMaterial->setUniform("mainTexture", sprites[0]->textureAtlas()->texture()); } auto shader = mat->shader(); assert(shader); mMesh->bind(shader.get()); shader->bind_uniforms(mMaterial, engineUniforms, transform().get()); mMesh->render(0); sprites.clear(); }
void RenderTerrainNode::createRenderData() { if (isLeaf()) { m_renderData = GearApplication::getApp()->getRender()->createRenderBase(); RenderVertexBufferDesc vbdesc; if (m_terrain->getUseVertexCompression()) { vbdesc.semanticFormats[RenderVertexBuffer::SEMANTIC_POSITION] = RenderVertexBuffer::FORMAT_USHORT4; vbdesc.semanticFormats[RenderVertexBuffer::SEMANTIC_TEXCOORD0] = RenderVertexBuffer::FORMAT_FLOAT1; } else { vbdesc.semanticFormats[RenderVertexBuffer::SEMANTIC_POSITION] = RenderVertexBuffer::FORMAT_FLOAT3; vbdesc.semanticFormats[RenderVertexBuffer::SEMANTIC_TEXCOORD0] = RenderVertexBuffer::FORMAT_FLOAT2; } size_t baseNumVerts = (size_t)Math::Sqr(m_terrain->getBatchSize()); size_t numVerts = baseNumVerts; vbdesc.hint = RenderVertexBuffer::HINT_STATIC; vbdesc.maxVertices = numVerts; RenderVertexBuffer* vb = GearApplication::getApp()->getRender()->createVertexBuffer(vbdesc); m_renderData->appendVertexBuffer(vb); m_renderData->setVertexBufferRange(0,numVerts); m_renderData->setIndexBuffer(m_terrain->getIndexBuffer()); m_renderData->setIndexBufferRange(0,m_terrain->getIndexBuffer()->getMaxIndices()); m_renderData->setPrimitives(RenderBase::PRIMITIVE_TRIANGLE_STRIP); Rect updateRect(m_offsetX, m_offsetY, m_boundaryX, m_boundaryY); updateVertexBuffer(vb, updateRect); setMesh(m_renderData); } }
//----------------------------------------------------------------------- void LightInstanceBatchHW::_updateRenderQueue( RenderQueue* queue ) { if( !mKeepStatic ) { //Completely override base functionality, since we don't cull on an "all-or-nothing" basis //and we don't support skeletal animation if( (mRenderOperation.numberOfInstances = updateVertexBuffer( mCurrentCamera )) ) queue->addRenderable( this ); } else { if( mManager->getCameraRelativeRendering() ) { OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Camera-relative rendering is incompatible" " with Instancing's static batches. Disable at least one of them", "InstanceBatch::_updateRenderQueue"); } //Don't update when we're static if( mRenderOperation.numberOfInstances ) queue->addRenderable( this ); } }
//--------------------------------------------------------------------- void TerrainQuadTreeNode::createCpuVertexData() { if (mVertexDataRecord) { destroyCpuVertexData(); // Calculate number of vertices // Base geometry size * size size_t baseNumVerts = (size_t)(mVertexDataRecord->size * mVertexDataRecord->size); size_t numVerts = baseNumVerts; // Now add space for skirts // Skirts will be rendered as copies of the edge vertices translated downwards // Some people use one big fan with only 3 vertices at the bottom, // but this requires creating them much bigger that necessary, meaning // more unnecessary overdraw, so we'll use more vertices // You need 2^levels + 1 rows of full resolution (max 129) vertex copies, plus // the same number of columns. There are common vertices at intersections uint16 levels = mVertexDataRecord->treeLevels; mVertexDataRecord->numSkirtRowsCols = (uint16)(pow(2, levels) + 1); mVertexDataRecord->skirtRowColSkip = (mVertexDataRecord->size - 1) / (mVertexDataRecord->numSkirtRowsCols - 1); numVerts += mVertexDataRecord->size * mVertexDataRecord->numSkirtRowsCols; numVerts += mVertexDataRecord->size * mVertexDataRecord->numSkirtRowsCols; // manually create CPU-side buffer const uint32 nVertSizePos = sizeof(uint16) * 2 + sizeof(float); const uint32 nVertSizeDelta = sizeof(float) * 2; mVertexDataRecord->cpuVertexPosData = new char[nVertSizePos * numVerts]; mVertexDataRecord->cpuVertexDeltaData = new float[nVertSizeDelta * numVerts]; mVertexDataRecord->cpuVertexCount= numVerts; Rect updateRect(mOffsetX, mOffsetY, mBoundaryX, mBoundaryY); updateVertexBuffer(updateRect); mVertexDataRecord->gpuVertexDataDirty = true; } }
//----------------------------------------------------------------------- void BillboardChain::_notifyCurrentCamera(Camera* cam) { updateVertexBuffer(cam); }
void av::osg::TriangleContainer::update() { updateVertexBuffer(); updateColor(); updateNormal(); }
void TMXLayer::updateTotalQuads() { if(_quadsDirty) { Size tileSize = CC_SIZE_PIXELS_TO_POINTS(_tileSet->_tileSize); Size texSize = _tileSet->_imageSize; _tileToQuadIndex.clear(); (*_totalQuads).resize(int(_layerSize.width * _layerSize.height)); //[CY MOD] (*_indices).resize(6 * int(_layerSize.width * _layerSize.height)); //[CY MOD] _tileToQuadIndex.resize(int(_layerSize.width * _layerSize.height),-1); _indicesVertexZOffsets.clear(); int quadIndex = 0; for(int y = 0; y < _layerSize.height; ++y) { for(int x =0; x < _layerSize.width; ++x) { int tileIndex = getTileIndexByPos(x, y); int tileGID = _tiles[tileIndex]; if(tileGID == 0) continue; _tileToQuadIndex[tileIndex] = quadIndex; auto& quad = (*_totalQuads)[quadIndex]; //[CY MOD] Vec3 nodePos(float(x), float(y), 0); _tileToNodeTransform.transformPoint(&nodePos); float left, right, top, bottom, z; z = getVertexZForPos(Vec2(x, y)); auto iter = _indicesVertexZOffsets.find(z); if(iter == _indicesVertexZOffsets.end()) { _indicesVertexZOffsets[z] = 1; } else { iter->second++; } // vertices if (tileGID & kTMXTileDiagonalFlag) { left = nodePos.x; right = nodePos.x + tileSize.height; bottom = nodePos.y + tileSize.width; top = nodePos.y; } else { left = nodePos.x; right = nodePos.x + tileSize.width; bottom = nodePos.y + tileSize.height; top = nodePos.y; } if(tileGID & kTMXTileVerticalFlag) std::swap(top, bottom); if(tileGID & kTMXTileHorizontalFlag) std::swap(left, right); if(tileGID & kTMXTileDiagonalFlag) { // FIXME: not working correcly quad.bl.vertices.x = left; quad.bl.vertices.y = bottom; quad.bl.vertices.z = z; quad.br.vertices.x = left; quad.br.vertices.y = top; quad.br.vertices.z = z; quad.tl.vertices.x = right; quad.tl.vertices.y = bottom; quad.tl.vertices.z = z; quad.tr.vertices.x = right; quad.tr.vertices.y = top; quad.tr.vertices.z = z; } else { quad.bl.vertices.x = left; quad.bl.vertices.y = bottom; quad.bl.vertices.z = z; quad.br.vertices.x = right; quad.br.vertices.y = bottom; quad.br.vertices.z = z; quad.tl.vertices.x = left; quad.tl.vertices.y = top; quad.tl.vertices.z = z; quad.tr.vertices.x = right; quad.tr.vertices.y = top; quad.tr.vertices.z = z; } // texcoords Rect tileTexture = _tileSet->getRectForGID(tileGID); left = (tileTexture.origin.x) / texSize.width; right = (tileTexture.origin.x+tileTexture.size.width) / texSize.width; bottom = (tileTexture.origin.y)/ texSize.height; top = (tileTexture.origin.y+tileTexture.size.height) / texSize.height; quad.bl.texCoords.u = left; quad.bl.texCoords.v = bottom; quad.br.texCoords.u = right; quad.br.texCoords.v = bottom; quad.tl.texCoords.u = left; quad.tl.texCoords.v = top; quad.tr.texCoords.u = right; quad.tr.texCoords.v = top; quad.bl.colors = Color4B::WHITE; quad.br.colors = Color4B::WHITE; quad.tl.colors = Color4B::WHITE; quad.tr.colors = Color4B::WHITE; ++quadIndex; } } int offset = 0; for(auto iter = _indicesVertexZOffsets.begin(); iter != _indicesVertexZOffsets.end(); ++iter) { std::swap(offset, iter->second); offset += iter->second; } updateVertexBuffer(); _quadsDirty = false; } }