//updateParticle void ParticleFluidEmitter::update(float delta) { //tick the emitter m_time += delta; m_respawnTime+= delta; int numberSpawn = 0; //if respawn time is greater than our release delay then we spawn at least one particle so work out how many to spawn if(m_respawnTime>m_releaseDelay) { numberSpawn = (int)(m_respawnTime/m_releaseDelay); m_respawnTime -= (numberSpawn * m_releaseDelay); } // spawn the required number of particles for(int count = 0;count < numberSpawn;count++) { //get the next free particle int particleIndex = getNextFreeParticle(); if(particleIndex >=0) { //if we got a particle ID then spawn it addPhysXParticle(particleIndex); } } //check to see if we need to release particles because they are either too old or have hit the particle sink //lock the particle buffer so we can work on it and get a pointer to read data PxParticleReadData* rd = m_pf->lockParticleReadData(); // access particle data from PxParticleReadData was OK if (rd) { vector<PxU32> particlesToRemove; //we need to build a list of particles to remove so we can do it all in one go PxStrideIterator<const PxParticleFlags> flagsIt(rd->flagsBuffer); PxStrideIterator<const PxVec3> positionIt(rd->positionBuffer); for (unsigned i = 0; i < rd->validParticleRange; ++i, ++flagsIt, ++positionIt) { if (*flagsIt & PxParticleFlag::eVALID) { //if particle is either too old or has hit the sink then mark it for removal. We can't remove it here because we buffer is locked if (*flagsIt & PxParticleFlag::eCOLLISION_WITH_DRAIN) { //mark our local copy of the particle free releaseParticle(i); //add to our list of particles to remove particlesToRemove.push_back(i); } } } // return ownership of the buffers back to the SDK rd->unlock(); //if we have particles to release then pass the particles to remove to PhysX so it can release them if(particlesToRemove.size()>0) { //create a buffer of particle indicies which we are going to remove PxStrideIterator<const PxU32> indexBuffer(&particlesToRemove[0]); //free particles from the physics system m_pf->releaseParticles(particlesToRemove.size(), indexBuffer); } } }
void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override { bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage(); SkMatrix localMatrix; if (this->usesLocalCoords() && !this->viewMatrix().invert(&localMatrix)) { SkDebugf("Cannot invert\n"); return; } SkAutoTUnref<const GrGeometryProcessor> gp(create_fill_rect_gp(canTweakAlphaForCoverage, localMatrix, this->usesLocalCoords(), this->coverageIgnored())); batchTarget->initDraw(gp, pipeline); size_t vertexStride = gp->getVertexStride(); SkASSERT(canTweakAlphaForCoverage ? vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr) : vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr)); int instanceCount = fGeoData.count(); SkAutoTUnref<const GrIndexBuffer> indexBuffer(this->getIndexBuffer( batchTarget->resourceProvider())); InstancedHelper helper; void* vertices = helper.init(batchTarget, kTriangles_GrPrimitiveType, vertexStride, indexBuffer, kVertsPerAAFillRect, kIndicesPerAAFillRect, instanceCount); if (!vertices || !indexBuffer) { SkDebugf("Could not allocate vertices\n"); return; } for (int i = 0; i < instanceCount; i++) { const Geometry& args = fGeoData[i]; this->generateAAFillRectGeometry(vertices, i * kVertsPerAAFillRect * vertexStride, vertexStride, args.fColor, args.fViewMatrix, args.fRect, args.fDevRect, canTweakAlphaForCoverage); } helper.issueDraw(batchTarget); }
void RenderState::generateQuadIndexBuffer() { std::vector<GLushort> indices; indices.reserve(MAX_QUAD_VERTICES / 4 * 6); for (size_t i = 0; i < MAX_QUAD_VERTICES; i += 4) { indices.push_back(i + 2); indices.push_back(i + 0); indices.push_back(i + 1); indices.push_back(i + 1); indices.push_back(i + 3); indices.push_back(i + 2); } GL::genBuffers(1, &m_quadIndexBuffer); indexBuffer(m_quadIndexBuffer); GL::bufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLushort), reinterpret_cast<GLbyte*>(indices.data()), GL_STATIC_DRAW); }
void DistortionMesh::setIndices() { indexBuffer().set(); }
QGeometry *ObjLoader::geometry() const { QByteArray bufferBytes; const int count = m_points.size(); const quint32 elementSize = 3 + (hasTextureCoordinates() ? 2 : 0) + (hasNormals() ? 3 : 0) + (hasTangents() ? 4 : 0); const quint32 stride = elementSize * sizeof(float); bufferBytes.resize(stride * count); float* fptr = reinterpret_cast<float*>(bufferBytes.data()); for (int index = 0; index < count; ++index) { *fptr++ = m_points.at(index).x(); *fptr++ = m_points.at(index).y(); *fptr++ = m_points.at(index).z(); if (hasTextureCoordinates()) { *fptr++ = m_texCoords.at(index).x(); *fptr++ = m_texCoords.at(index).y(); } if (hasNormals()) { *fptr++ = m_normals.at(index).x(); *fptr++ = m_normals.at(index).y(); *fptr++ = m_normals.at(index).z(); } if (hasTangents()) { *fptr++ = m_tangents.at(index).x(); *fptr++ = m_tangents.at(index).y(); *fptr++ = m_tangents.at(index).z(); *fptr++ = m_tangents.at(index).w(); } } // of buffer filling loop QBuffer *buf(new QBuffer(QBuffer::VertexBuffer)); buf->setData(bufferBytes); QGeometry *geometry = new QGeometry(); QAttribute *positionAttribute = new QAttribute(buf, QAttribute::defaultPositionAttributeName(), QAttribute::Float, 3, count, 0, stride); geometry->addAttribute(positionAttribute); quint32 offset = sizeof(float) * 3; if (hasTextureCoordinates()) { QAttribute *texCoordAttribute = new QAttribute(buf, QAttribute::defaultTextureCoordinateAttributeName(), QAttribute::Float, 2, count, offset, stride); geometry->addAttribute(texCoordAttribute); offset += sizeof(float) * 2; } if (hasNormals()) { QAttribute *normalAttribute = new QAttribute(buf, QAttribute::defaultNormalAttributeName(), QAttribute::Float, 3, count, offset, stride); geometry->addAttribute(normalAttribute); offset += sizeof(float) * 3; } if (hasTangents()) { QAttribute *tangentAttribute = new QAttribute(buf, QAttribute::defaultTangentAttributeName(),QAttribute::Float, 4, count, offset, stride); geometry->addAttribute(tangentAttribute); offset += sizeof(float) * 4; } QByteArray indexBytes; QAttribute::DataType ty; if (m_indices.size() < 65536) { // we can use USHORT ty = QAttribute::UnsignedShort; indexBytes.resize(m_indices.size() * sizeof(quint16)); quint16* usptr = reinterpret_cast<quint16*>(indexBytes.data()); for (int i=0; i<m_indices.size(); ++i) *usptr++ = static_cast<quint16>(m_indices.at(i)); } else { // use UINT - no conversion needed, but let's ensure int is 32-bit! ty = QAttribute::UnsignedInt; Q_ASSERT(sizeof(int) == sizeof(quint32)); indexBytes.resize(m_indices.size() * sizeof(quint32)); memcpy(indexBytes.data(), reinterpret_cast<const char*>(m_indices.data()), indexBytes.size()); } QBuffer *indexBuffer(new QBuffer(QBuffer::IndexBuffer)); indexBuffer->setData(indexBytes); QAttribute *indexAttribute = new QAttribute(indexBuffer, ty, 1, m_indices.size()); indexAttribute->setAttributeType(QAttribute::IndexAttribute); geometry->addAttribute(indexAttribute); return geometry; }
void loadMeshes( CalCoreModel* calCoreModel, MeshesVector& meshes ) throw (std::runtime_error) { const int maxVertices = Constants::MAX_VERTEX_PER_MODEL; const int maxFaces = Constants::MAX_VERTEX_PER_MODEL * 3; std::auto_ptr< CalHardwareModel > calHardwareModel( new CalHardwareModel( calCoreModel ) ); osg::ref_ptr< VertexBuffer > vertexBuffer( new VertexBuffer( maxVertices ) ); osg::ref_ptr< WeightBuffer > weightBuffer( new WeightBuffer( maxVertices ) ); osg::ref_ptr< MatrixIndexBuffer > matrixIndexBuffer( new MatrixIndexBuffer( maxVertices ) ); osg::ref_ptr< NormalBuffer > normalBuffer( new NormalBuffer( maxVertices ) ); osg::ref_ptr< NormalBuffer > tangentBuffer( new NormalBuffer( maxVertices ) ); osg::ref_ptr< NormalBuffer > binormalBuffer( new NormalBuffer( maxVertices ) ); osg::ref_ptr< TexCoordBuffer > texCoordBuffer( new TexCoordBuffer( maxVertices ) ); std::vector< CalIndex > indexBuffer( maxFaces*3 ); std::vector< float > floatMatrixIndexBuffer( maxVertices*4 ); calHardwareModel->setVertexBuffer((char*)vertexBuffer->getDataPointer(), 3*sizeof(float)); #ifdef OSG_CAL_BYTE_BUFFERS std::vector< float > floatNormalBuffer( getVertexCount()*3 ); calHardwareModel->setNormalBuffer((char*)&floatNormalBuffer.begin(), 3*sizeof(float)); #else calHardwareModel->setNormalBuffer((char*)normalBuffer->getDataPointer(), 3*sizeof(float)); #endif calHardwareModel->setWeightBuffer((char*)weightBuffer->getDataPointer(), 4*sizeof(float)); calHardwareModel->setMatrixIndexBuffer((char*)&floatMatrixIndexBuffer.front(), 4*sizeof(float)); calHardwareModel->setTextureCoordNum( 1 ); calHardwareModel->setTextureCoordBuffer(0, // texture stage # (char*)texCoordBuffer->getDataPointer(), 2*sizeof(float)); calHardwareModel->setIndexBuffer( &indexBuffer.front() ); // calHardwareModel->setCoreMeshIds(_activeMeshes); // if ids not set all meshes will be used at load() time //std::cout << "calHardwareModel->load" << std::endl; calHardwareModel->load( 0, 0, Constants::MAX_BONES_PER_MESH ); //std::cout << "calHardwareModel->load ok" << std::endl; int vertexCount = calHardwareModel->getTotalVertexCount(); // int faceCount = calHardwareModel->getTotalFaceCount(); // std::cout << "vertexCount = " << vertexCount << "; faceCount = " << faceCount << std::endl; GLubyte* matrixIndexBufferData = (GLubyte*) matrixIndexBuffer->getDataPointer(); for ( int i = 0; i < vertexCount*4; i++ ) { matrixIndexBufferData[i] = static_cast< GLubyte >( floatMatrixIndexBuffer[i] ); } #ifdef OSG_CAL_BYTE_BUFFERS GLbyte* normals = (GLbyte*) normalBuffer->getDataPointer(); for ( int i = 0; i < vertexCount*3; i++ ) { normals[i] = static_cast< GLbyte >( floatNormalBuffer[i]*127.0 ); } #endif // invert UVs for OpenGL (textures are inverted otherwise - for example, see abdulla/klinok) GLfloat* texCoordBufferData = (GLfloat*) texCoordBuffer->getDataPointer(); for ( float* tcy = texCoordBufferData + 1; tcy < texCoordBufferData + 2*vertexCount; tcy += 2 ) { *tcy = 1.0f - *tcy; } // -- And now create meshes data -- int unriggedBoneIndex = calCoreModel->getCoreSkeleton()->getVectorCoreBone().size(); // we add empty bone in ModelData to handle unrigged vertices; for( int hardwareMeshId = 0; hardwareMeshId < calHardwareModel->getHardwareMeshCount(); hardwareMeshId++ ) { calHardwareModel->selectHardwareMesh(hardwareMeshId); int faceCount = calHardwareModel->getFaceCount(); if ( faceCount == 0 ) { continue; // we ignore empty meshes } CalHardwareModel::CalHardwareMesh* hardwareMesh = &calHardwareModel->getVectorHardwareMesh()[ hardwareMeshId ]; osg::ref_ptr< MeshData > m( new MeshData ); m->name = calCoreModel->getCoreMesh( hardwareMesh->meshId )->getName(); m->coreMaterial = hardwareMesh->pCoreMaterial; if ( m->coreMaterial == NULL ) { CalCoreMesh* coreMesh = calCoreModel->getCoreMesh( hardwareMesh->meshId ); CalCoreSubmesh* coreSubmesh = coreMesh->getCoreSubmesh( hardwareMesh->submeshId ); // hardwareMesh->pCoreMaterial = // coreModel->getCoreMaterial( coreSubmesh->getCoreMaterialThreadId() ); char buf[ 1024 ]; snprintf( buf, 1024, "pCoreMaterial == NULL for mesh '%s' (mesh material id = %d), verify your mesh file data", m->name.c_str(), coreSubmesh->getCoreMaterialThreadId() ); throw std::runtime_error( buf ); } // -- Create index buffer -- int indexesCount = faceCount * 3; int startIndex = calHardwareModel->getStartIndex(); if ( indexesCount <= 0x100 ) { m->indexBuffer = new osg::DrawElementsUByte( osg::PrimitiveSet::TRIANGLES, indexesCount ); GLubyte* data = (GLubyte*)m->indexBuffer->getDataPointer(); const CalIndex* i = &indexBuffer[ startIndex ]; const CalIndex* iEnd = &indexBuffer[ startIndex + indexesCount ]; while ( i < iEnd ) { *data++ = (GLubyte)*i++; } } else if ( indexesCount <= 0x10000 ) { m->indexBuffer = new osg::DrawElementsUShort( osg::PrimitiveSet::TRIANGLES, indexesCount ); GLushort* data = (GLushort*)m->indexBuffer->getDataPointer(); const CalIndex* i = &indexBuffer[ startIndex ]; const CalIndex* iEnd = &indexBuffer[ startIndex + indexesCount ]; while ( i < iEnd ) { *data++ = (GLushort)*i++; } } else { m->indexBuffer = new osg::DrawElementsUInt( osg::PrimitiveSet::TRIANGLES, indexesCount ); GLuint* data = (GLuint*)m->indexBuffer->getDataPointer(); const CalIndex* i = &indexBuffer[ startIndex ]; const CalIndex* iEnd = &indexBuffer[ startIndex + indexesCount ]; while ( i < iEnd ) { *data++ = (GLuint)*i++; } } // -- Create other buffers -- int vertexCount = calHardwareModel->getVertexCount(); int baseVertexIndex = calHardwareModel->getBaseVertexIndex(); #define SUB_BUFFER( _type, _name ) \ new _type( _name->begin() + baseVertexIndex, \ _name->begin() + baseVertexIndex + vertexCount ) m->vertexBuffer = SUB_BUFFER( VertexBuffer, vertexBuffer ); m->weightBuffer = SUB_BUFFER( WeightBuffer, weightBuffer ); m->matrixIndexBuffer = SUB_BUFFER( MatrixIndexBuffer, matrixIndexBuffer ); m->normalBuffer = SUB_BUFFER( NormalBuffer, normalBuffer ); m->texCoordBuffer = SUB_BUFFER( TexCoordBuffer, texCoordBuffer ); // -- Parameters and buffers setup -- m->boundingBox = calculateBoundingBox( m->vertexBuffer.get() ); m->bonesIndices = hardwareMesh->m_vectorBonesIndices; checkRigidness( m.get(), unriggedBoneIndex ); checkForEmptyTexCoord( m.get() ); generateTangentAndHandednessBuffer( m.get(), &indexBuffer[ startIndex ] ); meshes.push_back( m.get() ); } }
void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override { int instanceCount = fGeoData.count(); SkMatrix invert; if (this->usesLocalCoords() && !this->viewMatrix().invert(&invert)) { SkDebugf("Could not invert viewmatrix\n"); return; } uint32_t flags = 0; flags |= this->viewMatrix().isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0; GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBilerp_FilterMode); // Setup GrGeometryProcessor GrBatchAtlas* atlas = fAtlas; SkAutoTUnref<GrGeometryProcessor> dfProcessor( GrDistanceFieldPathGeoProc::Create(this->color(), this->viewMatrix(), atlas->getTexture(), params, flags, false)); this->initDraw(batchTarget, dfProcessor, pipeline); static const int kVertsPerQuad = 4; static const int kIndicesPerQuad = 6; SkAutoTUnref<const GrIndexBuffer> indexBuffer( batchTarget->resourceProvider()->refQuadIndexBuffer()); // allocate vertices size_t vertexStride = dfProcessor->getVertexStride(); SkASSERT(vertexStride == 2 * sizeof(SkPoint)); const GrVertexBuffer* vertexBuffer; int vertexCount = kVertsPerQuad * instanceCount; int firstVertex; void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride, vertexCount, &vertexBuffer, &firstVertex); if (!vertices || !indexBuffer) { SkDebugf("Could not allocate vertices\n"); return; } // We may have to flush while uploading path data to the atlas, so we set up the draw here int maxInstancesPerDraw = indexBuffer->maxQuads(); GrDrawTarget::DrawInfo drawInfo; drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); drawInfo.setStartVertex(0); drawInfo.setStartIndex(0); drawInfo.setVerticesPerInstance(kVertsPerQuad); drawInfo.setIndicesPerInstance(kIndicesPerQuad); drawInfo.adjustStartVertex(firstVertex); drawInfo.setVertexBuffer(vertexBuffer); drawInfo.setIndexBuffer(indexBuffer); int instancesToFlush = 0; for (int i = 0; i < instanceCount; i++) { Geometry& args = fGeoData[i]; // get mip level SkScalar maxScale = this->viewMatrix().getMaxScale(); const SkRect& bounds = args.fPath.getBounds(); SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height()); SkScalar size = maxScale * maxDim; uint32_t desiredDimension; if (size <= kSmallMIP) { desiredDimension = kSmallMIP; } else if (size <= kMediumMIP) { desiredDimension = kMediumMIP; } else { desiredDimension = kLargeMIP; } // check to see if path is cached // TODO: handle stroked vs. filled version of same path PathData::Key key = { args.fPath.getGenerationID(), desiredDimension }; args.fPathData = fPathCache->find(key); if (NULL == args.fPathData || !atlas->hasID(args.fPathData->fID)) { // Remove the stale cache entry if (args.fPathData) { fPathCache->remove(args.fPathData->fKey); fPathList->remove(args.fPathData); SkDELETE(args.fPathData); } SkScalar scale = desiredDimension/maxDim; args.fPathData = SkNEW(PathData); if (!this->addPathToAtlas(batchTarget, dfProcessor, pipeline, &drawInfo, &instancesToFlush, maxInstancesPerDraw, atlas, args.fPathData, args.fPath, args.fStroke, args.fAntiAlias, desiredDimension, scale)) { SkDebugf("Can't rasterize path\n"); return; } } atlas->setLastUseToken(args.fPathData->fID, batchTarget->currentToken()); // Now set vertices intptr_t offset = reinterpret_cast<intptr_t>(vertices); offset += i * kVertsPerQuad * vertexStride; SkPoint* positions = reinterpret_cast<SkPoint*>(offset); this->drawPath(batchTarget, atlas, pipeline, dfProcessor, positions, vertexStride, this->viewMatrix(), args.fPath, args.fPathData); instancesToFlush++; } this->flush(batchTarget, &drawInfo, instancesToFlush, maxInstancesPerDraw); }
void Font::read(const void * data, size_t size) { std::istringstream in(std::string(static_cast<const char*>(data), size)); // SignedDistanceFontFile sdff; // sdff.read(in); uint8_t header[4]; readStream(in, header); if (memcmp(header, "SDFF", 4)) { FAIL("Bad font file"); } uint16_t version; readStream(in, version); // read font name if (version > 0x0001) { char c; readStream(in, c); while (c) { mFamily += c; readStream(in, c); } } // read font data readStream(in, mLeading); readStream(in, mAscent); readStream(in, mDescent); readStream(in, mSpaceWidth); mFontSize = mAscent + mDescent; // read metrics data mMetrics.clear(); uint16_t count; readStream(in, count); for (int i = 0; i < count; ++i) { uint16_t charcode; readStream(in, charcode); Metrics & m = mMetrics[charcode]; readStream(in, m.ul.x); readStream(in, m.ul.y); readStream(in, m.size.x); readStream(in, m.size.y); readStream(in, m.offset.x); readStream(in, m.offset.y); readStream(in, m.d); m.lr = m.ul + m.size; } // read image data readPngToTexture((const char *) data + in.tellg(), size - in.tellg(), mTexture, mTextureSize); std::vector<TextureVertex> vertexData; std::vector<GLuint> indexData; float texH = 0, texW = 0, texA = 0; int characters = 0; std::for_each(mMetrics.begin(), mMetrics.end(), [&] ( MetricsData::reference & md ) { uint16_t id = md.first; Font::Metrics & m = md.second; ++characters; GLuint index = (GLuint)vertexData.size(); rectf bounds = getBounds(m, mFontSize); rectf texBounds = getTexCoords(m); QuadBuilder qb(bounds, texBounds); for (int i = 0; i < 4; ++i) { vertexData.push_back(qb.vertices[i]); } m.indexOffset = indexData.size(); indexData.push_back(index + 0); indexData.push_back(index + 1); indexData.push_back(index + 2); indexData.push_back(index + 0); indexData.push_back(index + 2); indexData.push_back(index + 3); }); gl::VertexBufferPtr vertexBuffer(new gl::VertexBuffer(vertexData)); gl::IndexBufferPtr indexBuffer(new gl::IndexBuffer(indexData)); mGeometry = gl::GeometryPtr( new gl::Geometry(vertexBuffer, indexBuffer, characters * 2, gl::Geometry::Flag::HAS_TEXTURE)); mGeometry->buildVertexArray(); }