当前位置: 首页>>代码示例>>C++>>正文


C++ HardwareVertexBufferSharedPtr::writeData方法代码示例

本文整理汇总了C++中HardwareVertexBufferSharedPtr::writeData方法的典型用法代码示例。如果您正苦于以下问题:C++ HardwareVertexBufferSharedPtr::writeData方法的具体用法?C++ HardwareVertexBufferSharedPtr::writeData怎么用?C++ HardwareVertexBufferSharedPtr::writeData使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在HardwareVertexBufferSharedPtr的用法示例。


在下文中一共展示了HardwareVertexBufferSharedPtr::writeData方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: createQuad

void GeomUtils::createQuad(VertexData*& vertexData)
{
	assert(vertexData);

	vertexData->vertexCount = 4;
	vertexData->vertexStart = 0;

	VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
	VertexBufferBinding* bind = vertexData->vertexBufferBinding;

	vertexDecl->addElement(0, 0, VET_FLOAT3, VES_POSITION);

	HardwareVertexBufferSharedPtr vbuf = 
		HardwareBufferManager::getSingleton().createVertexBuffer(
		vertexDecl->getVertexSize(0),
		vertexData->vertexCount,
		HardwareBuffer::HBU_STATIC_WRITE_ONLY);

	// Bind buffer
	bind->setBinding(0, vbuf);
	// Upload data
	float data[]={
		-1,1,-1,  // corner 1
		-1,-1,-1, // corner 2
		1,1,-1,   // corner 3
		1,-1,-1}; // corner 4
		vbuf->writeData(0, sizeof(data), data, true);
}
开发者ID:Anti-Mage,项目名称:ogre,代码行数:28,代码来源:GeomUtils.cpp

示例2: fillHardwareBuffers

void NxLine::fillHardwareBuffers()
{
	int size = mPoints.size();
	prepareHardwareBuffers(size,0, mUseVertexColour);
 
	if (!size) 
	{ 
		mBox.setExtents(Vector3::ZERO,Vector3::ZERO);
		mDirty=false;
		return;
	}

	Nx::Vector3 vaabMin = mPoints[0];
	Nx::Vector3 vaabMax = mPoints[0];

	HardwareVertexBufferSharedPtr vbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(0);

	Real *prPos = static_cast<Real*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));
	{
		for(int i = 0; i < size; i++)
		{
			*prPos++ = mPoints[i].x;
			*prPos++ = mPoints[i].y;
			*prPos++ = mPoints[i].z;

			if(mPoints[i].x < vaabMin.x)
				vaabMin.x = mPoints[i].x;
			if(mPoints[i].y < vaabMin.y)
				vaabMin.y = mPoints[i].y;
			if(mPoints[i].z < vaabMin.z)
				vaabMin.z = mPoints[i].z;

			if(mPoints[i].x > vaabMax.x)
				vaabMax.x = mPoints[i].x;
			if(mPoints[i].y > vaabMax.y)
				vaabMax.y = mPoints[i].y;
			if(mPoints[i].z > vaabMax.z)
				vaabMax.z = mPoints[i].z;
		}
	}

	vbuf->unlock();


	if( mUseVertexColour ) {
		HardwareVertexBufferSharedPtr cbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(1);
		cbuf->writeData(0, size * sizeof(unsigned int), &mPointsColor[0], true );
	}


	mBox.setExtents( NxVec3ToOgre( vaabMin ), NxVec3ToOgre(  vaabMax ) );
	mDirty = false;

}
开发者ID:nxgraphics,项目名称:NxGraphics,代码行数:54,代码来源:NxRenderablesLines.cpp

示例3: SetTextureCoordinates

void NxTriangles::SetTextureCoordinates( const float * Coordinates )
{
 
	HardwareVertexBufferSharedPtr cbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(2);

	 
	cbuf->writeData(0, cbuf->getNumVertices() * sizeof(float) * (mUVW ? 3 : 2), Coordinates, true );

 

}
开发者ID:nxgraphics,项目名称:NxGraphics,代码行数:11,代码来源:NxRenderablesTriangles.cpp

示例4: createPlane

	//---------------------------------------------------------------------
	void PrefabFactory::createPlane(Mesh* mesh)
	{
		SubMesh* sub = mesh->createSubMesh();
		float vertices[32] = {
			-100, -100, 0,	// pos
			0,0,1,			// normal
			0,1,			// texcoord
			100, -100, 0,
			0,0,1,
			1,1,
			100,  100, 0,
			0,0,1,
			1,0,
			-100,  100, 0 ,
			0,0,1,
			0,0 
		};
		mesh->sharedVertexData = OGRE_NEW VertexData();
		mesh->sharedVertexData->vertexCount = 4;
		VertexDeclaration* decl = mesh->sharedVertexData->vertexDeclaration;
		VertexBufferBinding* bind = mesh->sharedVertexData->vertexBufferBinding;

		size_t offset = 0;
		decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
		offset += VertexElement::getTypeSize(VET_FLOAT3);
		decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
		offset += VertexElement::getTypeSize(VET_FLOAT3);
		decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
		offset += VertexElement::getTypeSize(VET_FLOAT2);

		HardwareVertexBufferSharedPtr vbuf = 
			HardwareBufferManager::getSingleton().createVertexBuffer(
			offset, 4, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
		bind->setBinding(0, vbuf);

		vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);

		sub->useSharedVertices = true;
		HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
			createIndexBuffer(
			HardwareIndexBuffer::IT_16BIT, 
			6, 
			HardwareBuffer::HBU_STATIC_WRITE_ONLY);

		unsigned short faces[6] = {0,1,2,
			0,2,3 };
		sub->indexData->indexBuffer = ibuf;
		sub->indexData->indexCount = 6;
		sub->indexData->indexStart =0;
		ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true);

		mesh->_setBounds(AxisAlignedBox(-100,-100,0,100,100,0), true);
		mesh->_setBoundingSphereRadius(Math::Sqrt(100*100+100*100));
	}
开发者ID:terminus510,项目名称:OgreBulletTest,代码行数:55,代码来源:OgrePrefabFactory.cpp

示例5: _updateColors

void MovableText::_updateColors(void)
{
	assert(mpFont);
	assert(!mpMaterial.isNull());

	// Convert to system-specific
	RGBA color;
	Root::getSingleton().convertColourValue(mColor, &color);
	HardwareVertexBufferSharedPtr vbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(COLOUR_BINDING);
	//RGBA *pDest = static_cast<RGBA*>(vbuf->lock(HardwareBuffer::HBL_NORMAL));
	RGBA* pDest=(RGBA*)malloc(vbuf->getSizeInBytes());
	RGBA* oDest=pDest;
	for (uint i = 0; i < mRenderOp.vertexData->vertexCount; ++i)
		*pDest++ = color;
	//vbuf->unlock();
	vbuf->writeData(0, vbuf->getSizeInBytes(), oDest, true);
	free(oDest);
	mUpdateColors = false;
}
开发者ID:Winceros,项目名称:main,代码行数:19,代码来源:MovableText.cpp

示例6: updateColours

void ColoredTextAreaOverlayElement::updateColours(void)
{
	if(!mRenderOp.vertexData) return;
	// Convert to system-specific
	RGBA topColour, bottomColour;
	// Set default to white
	Root::getSingleton().convertColourValue(ColourValue::White, &topColour);
	Root::getSingleton().convertColourValue(ColourValue::White, &bottomColour);

	HardwareVertexBufferSharedPtr vbuf = 
		mRenderOp.vertexData->vertexBufferBinding->getBuffer(COLOUR_BINDING);

	//RGBA* pDest = static_cast<RGBA*>(
	//	vbuf->lock(HardwareBuffer::HBL_NORMAL) );
	RGBA* pDest=(RGBA*)malloc(vbuf->getSizeInBytes());
	RGBA* oDest=pDest;

	for (size_t i = 0; i < mAllocSize; ++i)
	{
		if (i < m_Colors.size())
		{
			Root::getSingleton().convertColourValue(GetColor(m_Colors[i], m_ValueTop), &topColour);
			Root::getSingleton().convertColourValue(GetColor(m_Colors[i], m_ValueBottom), &bottomColour);
		}

		// First tri (top, bottom, top)
		*pDest++ = topColour;
		*pDest++ = bottomColour;
		*pDest++ = topColour;
		// Second tri (top, bottom, bottom)
		*pDest++ = topColour;
		*pDest++ = bottomColour;
		*pDest++ = bottomColour;
	}
	vbuf->writeData(0, vbuf->getSizeInBytes(), oDest, true);
	free(oDest);
	//vbuf->unlock();
}
开发者ID:Winceros,项目名称:main,代码行数:38,代码来源:ColoredTextAreaOverlayElement.cpp

示例7: createOgreSubMesh

// Convert Nif::NiTriShape to Ogre::SubMesh, attached to the given
// mesh.
void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std::list<VertexBoneAssignment> &vertexBoneAssignments)
{
    //  cout << "s:" << shape << "\n";
    NiTriShapeData *data = shape->data.getPtr();
    SubMesh *sub = mesh->createSubMesh(shape->name.toString());

    int nextBuf = 0;

    // This function is just one long stream of Ogre-barf, but it works
    // great.

    // Add vertices
    int numVerts = data->vertices.length / 3;
    sub->vertexData = new VertexData();
    sub->vertexData->vertexCount = numVerts;
    sub->useSharedVertices = false;

    VertexDeclaration *decl = sub->vertexData->vertexDeclaration;
    decl->addElement(nextBuf, 0, VET_FLOAT3, VES_POSITION);

    HardwareVertexBufferSharedPtr vbuf =
        HardwareBufferManager::getSingleton().createVertexBuffer(
            VertexElement::getTypeSize(VET_FLOAT3),
            numVerts, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY, false);

    if(flip)
	{
		float *datamod = new float[data->vertices.length];
		//std::cout << "Shape" << shape->name.toString() << "\n";
		for(int i = 0; i < numVerts; i++)
		{
			int index = i * 3;
			const float *pos = data->vertices.ptr + index;
		    Ogre::Vector3 original = Ogre::Vector3(*pos  ,*(pos+1), *(pos+2));
			original = mTransform * original;
			mBoundingBox.merge(original);
			datamod[index] = original.x;
			datamod[index+1] = original.y;
			datamod[index+2] = original.z;
		}
        vbuf->writeData(0, vbuf->getSizeInBytes(), datamod, false);
        delete [] datamod;
	}
	else
	{
		vbuf->writeData(0, vbuf->getSizeInBytes(), data->vertices.ptr, false);
	}


    VertexBufferBinding* bind = sub->vertexData->vertexBufferBinding;
    bind->setBinding(nextBuf++, vbuf);

    if (data->normals.length)
    {
        decl->addElement(nextBuf, 0, VET_FLOAT3, VES_NORMAL);
        vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
                   VertexElement::getTypeSize(VET_FLOAT3),
                   numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);

		if(flip)
		{
			Quaternion rotation = mTransform.extractQuaternion();
			rotation.normalise();

			float *datamod = new float[data->normals.length];
			for(int i = 0; i < numVerts; i++)
		    {
			    int index = i * 3;
			    const float *pos = data->normals.ptr + index;
		        Ogre::Vector3 original = Ogre::Vector3(*pos  ,*(pos+1), *(pos+2));
				original = rotation * original;
				if (mNormaliseNormals)
			    {
                    original.normalise();
				}


			    datamod[index] = original.x;
			    datamod[index+1] = original.y;
			    datamod[index+2] = original.z;
		    }
			vbuf->writeData(0, vbuf->getSizeInBytes(), datamod, false);
            delete [] datamod;
		}
		else
		{
            vbuf->writeData(0, vbuf->getSizeInBytes(), data->normals.ptr, false);
		}
        bind->setBinding(nextBuf++, vbuf);
    }

    
    // Vertex colors
    if (data->colors.length)
    {
        const float *colors = data->colors.ptr;
        RenderSystem* rs = Root::getSingleton().getRenderSystem();
        std::vector<RGBA> colorsRGB(numVerts);
//.........这里部分代码省略.........
开发者ID:Thynix,项目名称:openmw,代码行数:101,代码来源:ogre_nif_loader.cpp

示例8: sqrt

void BasicTutorial2::createColourCube()
{
    /// Create the mesh via the MeshManager
    Ogre::MeshPtr msh = MeshManager::getSingleton().createManual("ColourCube", "General");
 
    /// Create one submesh
    SubMesh* sub = msh->createSubMesh();
 
    const float sqrt13 = 0.577350269f; /* sqrt(1/3) */
 
    /// Define the vertices (8 vertices, each have 3 floats for position and 3 for normal)
    const size_t nVertices = 8;
    const size_t vbufCount = 3*2*nVertices;
    float vertices[vbufCount] = {
            -100.0,100.0,-100.0,        //0 position
            -sqrt13,sqrt13,-sqrt13,     //0 normal
            100.0,100.0,-100.0,         //1 position
            sqrt13,sqrt13,-sqrt13,      //1 normal
            100.0,-100.0,-100.0,        //2 position
            sqrt13,-sqrt13,-sqrt13,     //2 normal
            -100.0,-100.0,-100.0,       //3 position
            -sqrt13,-sqrt13,-sqrt13,    //3 normal
            -100.0,100.0,100.0,         //4 position
            -sqrt13,sqrt13,sqrt13,      //4 normal
            100.0,100.0,100.0,          //5 position
            sqrt13,sqrt13,sqrt13,       //5 normal
            100.0,-100.0,100.0,         //6 position
            sqrt13,-sqrt13,sqrt13,      //6 normal
            -100.0,-100.0,100.0,        //7 position
            -sqrt13,-sqrt13,sqrt13,     //7 normal
    };
 
    RenderSystem* rs = Root::getSingleton().getRenderSystem();
    RGBA colours[nVertices];
    RGBA *pColour = colours;
    // Use render system to convert colour value since colour packing varies
    rs->convertColourValue(ColourValue(1.0,0.0,0.0), pColour++); //0 colour
    rs->convertColourValue(ColourValue(1.0,1.0,0.0), pColour++); //1 colour
    rs->convertColourValue(ColourValue(0.0,1.0,0.0), pColour++); //2 colour
    rs->convertColourValue(ColourValue(0.0,0.0,0.0), pColour++); //3 colour
    rs->convertColourValue(ColourValue(1.0,0.0,1.0), pColour++); //4 colour
    rs->convertColourValue(ColourValue(1.0,1.0,1.0), pColour++); //5 colour
    rs->convertColourValue(ColourValue(0.0,1.0,1.0), pColour++); //6 colour
    rs->convertColourValue(ColourValue(0.0,0.0,1.0), pColour++); //7 colour
 
    /// Define 12 triangles (two triangles per cube face)
    /// The values in this table refer to vertices in the above table
    const size_t ibufCount = 36;
    unsigned short faces[ibufCount] = {
            0,2,3,
            0,1,2,
            1,6,2,
            1,5,6,
            4,6,5,
            4,7,6,
            0,7,4,
            0,3,7,
            0,5,1,
            0,4,5,
            2,7,3,
            2,6,7
    };
 
    /// Create vertex data structure for 8 vertices shared between submeshes
    msh->sharedVertexData = new VertexData();
    msh->sharedVertexData->vertexCount = nVertices;
 
    /// Create declaration (memory format) of vertex data
    VertexDeclaration* decl = msh->sharedVertexData->vertexDeclaration;
    size_t offset = 0;
    // 1st buffer
    decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
    offset += VertexElement::getTypeSize(VET_FLOAT3);
    decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
    offset += VertexElement::getTypeSize(VET_FLOAT3);
    /// Allocate vertex buffer of the requested number of vertices (vertexCount) 
    /// and bytes per vertex (offset)
    HardwareVertexBufferSharedPtr vbuf = 
        HardwareBufferManager::getSingleton().createVertexBuffer(
        offset, msh->sharedVertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
    /// Upload the vertex data to the card
    vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);
 
    /// Set vertex buffer binding so buffer 0 is bound to our vertex buffer
    VertexBufferBinding* bind = msh->sharedVertexData->vertexBufferBinding; 
    bind->setBinding(0, vbuf);
 
    // 2nd buffer
    offset = 0;
    decl->addElement(1, offset, VET_COLOUR, VES_DIFFUSE);
    offset += VertexElement::getTypeSize(VET_COLOUR);
    /// Allocate vertex buffer of the requested number of vertices (vertexCount) 
    /// and bytes per vertex (offset)
    vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
        offset, msh->sharedVertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
    /// Upload the vertex data to the card
    vbuf->writeData(0, vbuf->getSizeInBytes(), colours, true);
 
    /// Set vertex buffer binding so buffer 1 is bound to our colour buffer
    bind->setBinding(1, vbuf);
//.........这里部分代码省略.........
开发者ID:asvsfs,项目名称:TheJourney,代码行数:101,代码来源:BasicTutorial2.cpp

示例9: createCube


//.........这里部分代码省略.........
			1,1,
			CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			1,0,0,
			1,0,
			CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			1,0,0,
			0,0,

			// up side
			-CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			0,1,0,
			0,1,
			CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			0,1,0,
			1,1,
			CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			0,1,0,
			1,0,
			-CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			0,1,0,
			0,0,

			// down side
			-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			0,-1,0,
			0,1,
			CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			0,-1,0,
			1,1,
			CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			0,-1,0,
			1,0,
			-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			0,-1,0,
			0,0 
		};

		mesh->sharedVertexData = OGRE_NEW VertexData();
		mesh->sharedVertexData->vertexCount = NUM_VERTICES;
		VertexDeclaration* decl = mesh->sharedVertexData->vertexDeclaration;
		VertexBufferBinding* bind = mesh->sharedVertexData->vertexBufferBinding;

		size_t offset = 0;
		decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
		offset += VertexElement::getTypeSize(VET_FLOAT3);
		decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
		offset += VertexElement::getTypeSize(VET_FLOAT3);
		decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
		offset += VertexElement::getTypeSize(VET_FLOAT2);

		HardwareVertexBufferSharedPtr vbuf = 
			HardwareBufferManager::getSingleton().createVertexBuffer(
			offset, NUM_VERTICES, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
		bind->setBinding(0, vbuf);

		vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);

		sub->useSharedVertices = true;
		HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
			createIndexBuffer(
			HardwareIndexBuffer::IT_16BIT, 
			NUM_INDICES,
			HardwareBuffer::HBU_STATIC_WRITE_ONLY);

		unsigned short faces[NUM_INDICES] = {
			// front
			0,1,2,
			0,2,3,

			// back
			4,5,6,
			4,6,7,

			// left
			8,9,10,
			8,10,11,

			// right
			12,13,14,
			12,14,15,

			// up
			16,17,18,
			16,18,19,

			// down
			20,21,22,
			20,22,23
		};

		sub->indexData->indexBuffer = ibuf;
		sub->indexData->indexCount = NUM_INDICES;
		sub->indexData->indexStart = 0;
		ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true);

		mesh->_setBounds(AxisAlignedBox(-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE), true);

		mesh->_setBoundingSphereRadius(CUBE_HALF_SIZE);
	}
开发者ID:terminus510,项目名称:OgreBulletTest,代码行数:101,代码来源:OgrePrefabFactory.cpp

示例10: initialise

void VolumeRenderable::initialise()
{
	// Create geometry
	size_t nvertices = mSlices*4; // n+1 planes
	size_t elemsize = 3*3;
	size_t dsize = elemsize*nvertices;
	size_t x;
	
	Ogre::IndexData *idata = new Ogre::IndexData();
	Ogre::VertexData *vdata = new Ogre::VertexData();
	
	// Create  structures
	float *vertices = new float[dsize];
	
	float coords[4][2] = {
		{0.0f, 0.0f},
		{0.0f, 1.0f},
		{1.0f, 0.0f},
		{1.0f, 1.0f}
	};
	for(x=0; x<mSlices; x++) 
	{
		for(size_t y=0; y<4; y++)
		{
			float xcoord = coords[y][0]-0.5;
			float ycoord = coords[y][1]-0.5;
			float zcoord = -((float)x/(float)(mSlices-1)  - 0.5f);
			// 1.0f .. a/(a+1)
			// coordinate
			vertices[x*4*elemsize+y*elemsize+0] = xcoord*(mSize/2.0f);
			vertices[x*4*elemsize+y*elemsize+1] = ycoord*(mSize/2.0f);
			vertices[x*4*elemsize+y*elemsize+2] = zcoord*(mSize/2.0f);
			// normal
			vertices[x*4*elemsize+y*elemsize+3] = 0.0f;
			vertices[x*4*elemsize+y*elemsize+4] = 0.0f;
			vertices[x*4*elemsize+y*elemsize+5] = 1.0f;
			// tex
			vertices[x*4*elemsize+y*elemsize+6] = xcoord*sqrtf(3.0f);
			vertices[x*4*elemsize+y*elemsize+7] = ycoord*sqrtf(3.0f);
			vertices[x*4*elemsize+y*elemsize+8] = zcoord*sqrtf(3.0f);
		} 
	}
	unsigned short *faces = new unsigned short[mSlices*6];
	for(x=0; x<mSlices; x++) 
	{
		faces[x*6+0] = x*4+0;
		faces[x*6+1] = x*4+1;
		faces[x*6+2] = x*4+2;
		faces[x*6+3] = x*4+1;
		faces[x*6+4] = x*4+2;
		faces[x*6+5] = x*4+3;
	}
	// Setup buffers
	vdata->vertexStart = 0;
	vdata->vertexCount = nvertices;
	
	VertexDeclaration* decl = vdata->vertexDeclaration;
	VertexBufferBinding* bind = vdata->vertexBufferBinding;

	size_t offset = 0;
	decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
	offset += VertexElement::getTypeSize(VET_FLOAT3);
	decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
	offset += VertexElement::getTypeSize(VET_FLOAT3);
	decl->addElement(0, offset, VET_FLOAT3, VES_TEXTURE_COORDINATES);
	offset += VertexElement::getTypeSize(VET_FLOAT3);

	HardwareVertexBufferSharedPtr vbuf = 
	HardwareBufferManager::getSingleton().createVertexBuffer(
		offset, nvertices, HardwareBuffer::HBU_STATIC_WRITE_ONLY);

	bind->setBinding(0, vbuf);

	vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);
	
	HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
		createIndexBuffer(
			HardwareIndexBuffer::IT_16BIT, 
			mSlices*6, 
			HardwareBuffer::HBU_STATIC_WRITE_ONLY);

	idata->indexBuffer = ibuf;
	idata->indexCount = mSlices*6;
	idata->indexStart = 0;
	ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true);

	// Delete temporary buffers
	delete [] vertices;
	delete [] faces;
	
	// Now make the render operation
	mRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
	mRenderOp.indexData = idata;
	mRenderOp.vertexData = vdata;
	mRenderOp.useIndexes = true;
	
	 // Create a brand new private material
	MaterialPtr material = 
		MaterialManager::getSingleton().create(mTexture, "VolumeRenderable",
			false, 0); // Manual, loader
//.........这里部分代码省略.........
开发者ID:Argos86,项目名称:dt2370,代码行数:101,代码来源:VolumeRenderable.cpp

示例11: updateVertexData

    //------------------------------------------------------------------------
    void TerrainBatch::updateVertexData( const Ogre::Rect& vertexRectInTile )
    {
        
        Vector3 center = mBoundingBox.getCenter();

        Ogre::Rect dirtyRect = mVertexRectInTile.intersect( vertexRectInTile );

        if ( mGpuVertexData && (dirtyRect.isNull() == false) )
        {
            mOneVertexSize  = mTileRender->getOneVertexSize();

            ////////////////////////////////////////////////////////////////////////////////

            Ogre::VertexData* tileVertexData    = mTileRender->getCpuVertexData();
            uint16 srcPosRowSkip                = 0;
            unsigned char * srcRootPosBuf       = 0;
            unsigned char * srcRowPosBuf        = 0;
            HardwareVertexBufferSharedPtr srcPosbuf = tileVertexData->vertexBufferBinding->getBuffer(TerrainTileRender::POSITION_BUFFER);

            long destOffsetX        = dirtyRect.left <= mVertexRectInTile.left ? 0 : (dirtyRect.left - mVertexRectInTile.left) ;
            long destOffsetY        = dirtyRect.top  <= mVertexRectInTile.top ? 0 : (dirtyRect.top - mVertexRectInTile.top) ;
            uint16 destPosRowSkip   = 0;
            size_t destRowPos       = 0;
            HardwareVertexBufferSharedPtr destPosbuf = mGpuVertexData->vertexBufferBinding->getBuffer(TerrainTileRender::POSITION_BUFFER);

            if (!srcPosbuf.isNull() && !destPosbuf.isNull())
            {
                srcPosRowSkip   =  mTileRender->getVertexSideSize() * mOneVertexSize;
                srcRootPosBuf   =  static_cast<unsigned char*>(srcPosbuf->lock(HardwareBuffer::HBL_READ_ONLY));
                // skip src buffer in by left/top
                srcRowPosBuf    =  srcRootPosBuf;
                srcRowPosBuf    += dirtyRect.top * srcPosRowSkip + dirtyRect.left * mOneVertexSize;

                destPosRowSkip  = mVertexSideNum * mOneVertexSize;
                // skip dest pos in by left/top
                destRowPos      = destOffsetY * destPosRowSkip + destOffsetX * mOneVertexSize;


                ///////////////////////////////////////////////////////////////////////////////////////

                {
                    size_t destRowHeadPos   = destRowPos;
                    size_t rowCopyLen = (dirtyRect.width() + 1) * mOneVertexSize;
                    for (uint16 y = dirtyRect.top; y <= dirtyRect.bottom; y ++)
                    {
                        destPosbuf->writeData( destRowHeadPos, rowCopyLen, srcRowPosBuf );
                        srcRowPosBuf    += srcPosRowSkip;
                        destRowHeadPos  += destPosRowSkip;
                    }
                }

                ///////////////////////////////////////////////////////////////////////////////////////

                //{
                //    unsigned char * pRootPosBuf = static_cast<unsigned char*>(destPosbuf->lock(  HardwareBuffer::HBL_NORMAL ));
                //    {
                //        pRootPosBuf += destRowPos;
                //        unsigned char * destRowHeadPos   = pRootPosBuf;
                //        unsigned char * destRowPixelPos  = pRootPosBuf;
                //        for (uint16 y = dirtyRect.top; y <= dirtyRect.bottom; y ++)
                //        {
                //            destRowPixelPos = destRowHeadPos;
                //            for (uint16 x = dirtyRect.left; x <= dirtyRect.right; x ++)
                //            {
                //                float* pPosBuf = static_cast<float*>(static_cast<void*>(destRowPixelPos));
                //                if (pPosBuf)
                //                {
                //                    //position
                //                    *pPosBuf++ = *pPosBuf - center.x;
                //                    *pPosBuf++;
                //                    *pPosBuf++ = *pPosBuf - center.z;
                //                }

                //                destRowPixelPos += mOneVertexSize;
                //            }

                //            destRowHeadPos  += destPosRowSkip;
                //        }
                //    }
                //    destPosbuf->unlock();
                //}

                ///////////////////////////////////////////////////////////////////////////////////////

                srcPosbuf->unlock();
                //destPosbuf->unlock();
            }
        }

    }
开发者ID:dnjsflagh1,项目名称:code,代码行数:91,代码来源:TerrainBatch.cpp

示例12: createVertexData

Ogre::VertexData* MeshBuilder::createVertexData()
{
    // Declarations
    std::map<unsigned short, std::vector<tElement> >::iterator  iterSource, iterSourceEnd;
    std::vector<tVertex>::iterator                              iterVertex, iterVertexEnd;
    HardwareVertexBufferSharedPtr                               vbuffer;
    float                                                       fBuffer[4];


    // Create the vertex data
    VertexData* pVertexData = new VertexData();
    pVertexData->vertexStart = 0;
    pVertexData->vertexCount = m_currentSubMesh.vertices.size();


    // Initializes the vertex declaration
    for (iterSource = m_currentSubMesh.verticesElements.begin(), iterSourceEnd = m_currentSubMesh.verticesElements.end();
         iterSource != iterSourceEnd; ++iterSource)
    {
        size_t offset = 0;

        std::vector<tElement>::iterator iter, iterEnd;
        for (iter = iterSource->second.begin(), iterEnd = iterSource->second.end();
             iter != iterEnd; ++iter)
        {
            pVertexData->vertexDeclaration->addElement(iterSource->first, offset, iter->type, iter->semantic, iter->usIndex);
            offset += VertexElement::getTypeSize(iter->type);
        }

        vbuffer = HardwareBufferManager::getSingleton().createVertexBuffer(offset, m_currentSubMesh.vertices.size(),
                                            m_currentSubMesh.vertexBufferInfos[iterSource->first].usage,
                                            m_currentSubMesh.vertexBufferInfos[iterSource->first].bUseShadowBuffer);

        pVertexData->vertexBufferBinding->setBinding(iterSource->first, vbuffer);
    }


    // Add the vertices into their buffers
    VertexBufferBinding::VertexBufferBindingMap bindings = pVertexData->vertexBufferBinding->getBindings();
    for (iterSource = m_currentSubMesh.verticesElements.begin(), iterSourceEnd = m_currentSubMesh.verticesElements.end();
        iterSource != iterSourceEnd; ++iterSource)
    {
        vbuffer = bindings[iterSource->first];

        size_t          offset = 0;
        unsigned int    vertexIndex = 0;

        for (iterVertex = m_currentSubMesh.vertices.begin(), iterVertexEnd = m_currentSubMesh.vertices.end();
            iterVertex != iterVertexEnd; ++iterVertex)
        {
            std::vector<tElement>::iterator iter, iterEnd;
            for (iter = iterSource->second.begin(), iterEnd = iterSource->second.end();
                iter != iterEnd; ++iter)
            {
                switch (iter->semantic)
                {
                case Ogre::VES_POSITION:
                    fBuffer[0] = iterVertex->position.x;
                    fBuffer[1] = iterVertex->position.y;
                    fBuffer[2] = iterVertex->position.z;
                    vbuffer->writeData(offset, VertexElement::getTypeSize(iter->type), fBuffer);
                    break;

                case Ogre::VES_NORMAL:
                    fBuffer[0] = iterVertex->normal.x;
                    fBuffer[1] = iterVertex->normal.y;
                    fBuffer[2] = iterVertex->normal.z;
                    vbuffer->writeData(offset, VertexElement::getTypeSize(iter->type), fBuffer);
                    break;

                case Ogre::VES_BINORMAL:
                    fBuffer[0] = iterVertex->binormal.x;
                    fBuffer[1] = iterVertex->binormal.y;
                    fBuffer[2] = iterVertex->binormal.z;
                    vbuffer->writeData(offset, VertexElement::getTypeSize(iter->type), fBuffer);
                    break;

                case Ogre::VES_TANGENT:
                    fBuffer[0] = iterVertex->tangent.x;
                    fBuffer[1] = iterVertex->tangent.y;
                    fBuffer[2] = iterVertex->tangent.z;
                    vbuffer->writeData(offset, VertexElement::getTypeSize(iter->type), fBuffer);
                    break;

                case Ogre::VES_DIFFUSE:
                    fBuffer[0] = iterVertex->diffuseColour.a;
                    fBuffer[1] = iterVertex->diffuseColour.r;
                    fBuffer[2] = iterVertex->diffuseColour.g;
                    fBuffer[3] = iterVertex->diffuseColour.b;
                    vbuffer->writeData(offset, VertexElement::getTypeSize(iter->type), fBuffer);
                    break;

                case Ogre::VES_SPECULAR:
                    fBuffer[0] = iterVertex->specularColour.a;
                    fBuffer[1] = iterVertex->specularColour.r;
                    fBuffer[2] = iterVertex->specularColour.g;
                    fBuffer[3] = iterVertex->specularColour.b;
                    vbuffer->writeData(offset, VertexElement::getTypeSize(iter->type), fBuffer);
                    break;

//.........这里部分代码省略.........
开发者ID:Kanma,项目名称:Athena-Graphics,代码行数:101,代码来源:MeshBuilder.cpp

示例13: sizeof

void Road2::createMesh()
{
    AxisAlignedBox aab;
    union
    {
        float* vertices;
        CoVertice_t* covertices;
    };
    /// Create the mesh via the MeshManager
    Ogre::String mesh_name = Ogre::String("RoadSystem-").append(Ogre::StringConverter::toString(mid));
    msh = MeshManager::getSingleton().createManual(mesh_name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);

    mainsub = msh->createSubMesh();
    mainsub->setMaterialName("road2");

    /// Define the vertices
    size_t vbufCount = (2 * 3 + 2) * vertexcount;
    vertices = (float*)malloc(vbufCount * sizeof(float));
    int i;
    //fill values
    for (i = 0; i < vertexcount; i++)
    {
        covertices[i].texcoord = tex[i];
        covertices[i].vertex = vertex[i];
        //normals are computed later
        covertices[i].normal = Vector3::ZERO;
        aab.merge(vertex[i]);
    }

    /// Define triangles
    size_t ibufCount = 3 * tricount;

    //compute normals
    for (i = 0; i < tricount && i * 3 + 2 < MAX_TRIS * 3; i++)
    {
        Vector3 v1, v2;
        v1 = covertices[tris[i * 3 + 1]].vertex - covertices[tris[i * 3]].vertex;
        v2 = covertices[tris[i * 3 + 2]].vertex - covertices[tris[i * 3]].vertex;
        v1 = v1.crossProduct(v2);
        v1.normalise();
        covertices[tris[i * 3]].normal += v1;
        covertices[tris[i * 3 + 1]].normal += v1;
        covertices[tris[i * 3 + 2]].normal += v1;
    }
    //normalize
    for (i = 0; i < vertexcount; i++)
    {
        covertices[i].normal.normalise();
    }

    /// Create vertex data structure for vertices shared between sub meshes
    msh->sharedVertexData = new VertexData();
    msh->sharedVertexData->vertexCount = vertexcount;

    /// Create declaration (memory format) of vertex data
    VertexDeclaration* decl = msh->sharedVertexData->vertexDeclaration;
    size_t offset = 0;
    decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
    offset += VertexElement::getTypeSize(VET_FLOAT3);
    decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
    offset += VertexElement::getTypeSize(VET_FLOAT3);
    decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
    offset += VertexElement::getTypeSize(VET_FLOAT2);

    /// Allocate vertex buffer of the requested number of vertices (vertexCount)
    /// and bytes per vertex (offset)
    HardwareVertexBufferSharedPtr vbuf =
        HardwareBufferManager::getSingleton().createVertexBuffer(
            offset, msh->sharedVertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY);

    /// Upload the vertex data to the card
    vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);

    /// Set vertex buffer binding so buffer 0 is bound to our vertex buffer
    VertexBufferBinding* bind = msh->sharedVertexData->vertexBufferBinding;
    bind->setBinding(0, vbuf);

    //for the face
    /// Allocate index buffer of the requested number of vertices (ibufCount)
    HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
        createIndexBuffer(
            HardwareIndexBuffer::IT_16BIT,
            ibufCount,
            HardwareBuffer::HBU_STATIC_WRITE_ONLY);

    /// Upload the index data to the card
    ibuf->writeData(0, ibuf->getSizeInBytes(), tris, true);

    /// Set parameters of the submesh
    mainsub->useSharedVertices = true;
    mainsub->indexData->indexBuffer = ibuf;
    mainsub->indexData->indexCount = ibufCount;
    mainsub->indexData->indexStart = 0;

    msh->_setBounds(aab, true);

    /// Notify Mesh object that it has been loaded
    msh->load();

    free(vertices);
//.........这里部分代码省略.........
开发者ID:Speciesx,项目名称:rigs-of-rods,代码行数:101,代码来源:Road2.cpp

示例14: VertexData

Airbrake::Airbrake(char* basename, int num, node_t *ndref, node_t *ndx, node_t *ndy, node_t *nda, Vector3 pos, float width, float length, float maxang, char* texname, float tx1, float ty1, float tx2, float ty2, float lift_coef)
{
	snode=0;
	noderef=ndref;
	nodex=ndx;
	nodey=ndy;
	nodea=nda;
	offset=pos;
	maxangle=maxang;
	area=width*length*lift_coef;
	char meshname[256];
	sprintf(meshname, "airbrakemesh-%s-%i", basename, num);
	/// Create the mesh via the MeshManager
    msh = MeshManager::getSingleton().createManual(meshname, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);

	union
	{
		float *vertices;
		CoVertice_t *covertices;
	};

    /// Create submesh
    SubMesh* sub = msh->createSubMesh();

	//materials
	sub->setMaterialName(texname);

    /// Define the vertices
    size_t nVertices = 4;
    size_t vbufCount = (2*3+2)*nVertices;
	vertices=(float*)malloc(vbufCount*sizeof(float));

	//textures coordinates
	covertices[0].texcoord=Vector2(tx1, ty1);
	covertices[1].texcoord=Vector2(tx2, ty1);
	covertices[2].texcoord=Vector2(tx2, ty2);
	covertices[3].texcoord=Vector2(tx1, ty2);

    /// Define triangles
    /// The values in this table refer to vertices in the above table
    size_t ibufCount = 3*4;
    unsigned short *faces=(unsigned short*)malloc(ibufCount*sizeof(unsigned short));
	faces[0]=0; faces[1]=1; faces[2]=2;
	faces[3]=0; faces[4]=2; faces[5]=3;
	faces[6]=0; faces[7]=2; faces[8]=1;
	faces[9]=0; faces[10]=3; faces[11]=2;

	//set coords
	covertices[0].vertex=Vector3(0,0,0);
	covertices[1].vertex=Vector3(width,0,0);
	covertices[2].vertex=Vector3(width,0,length);
	covertices[3].vertex=Vector3(0,0,length);

	covertices[0].normal=Vector3(0,1,0);
	covertices[1].normal=Vector3(0,1,0);
	covertices[2].normal=Vector3(0,1,0);
	covertices[3].normal=Vector3(0,1,0);

    /// Create vertex data structure for vertices shared between submeshes
    msh->sharedVertexData = new VertexData();
    msh->sharedVertexData->vertexCount = nVertices;

    /// Create declaration (memory format) of vertex data
    VertexDeclaration* decl = msh->sharedVertexData->vertexDeclaration;
    size_t offset = 0;
    decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
    offset += VertexElement::getTypeSize(VET_FLOAT3);
    decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
    offset += VertexElement::getTypeSize(VET_FLOAT3);
//        decl->addElement(0, offset, VET_FLOAT3, VES_DIFFUSE);
//        offset += VertexElement::getTypeSize(VET_FLOAT3);
    decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
    offset += VertexElement::getTypeSize(VET_FLOAT2);

    /// Allocate vertex buffer of the requested number of vertices (vertexCount)
    /// and bytes per vertex (offset)
    HardwareVertexBufferSharedPtr vbuf =
        HardwareBufferManager::getSingleton().createVertexBuffer(
            offset, msh->sharedVertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE);

    /// Upload the vertex data to the card
    vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);

    /// Set vertex buffer binding so buffer 0 is bound to our vertex buffer
    VertexBufferBinding* bind = msh->sharedVertexData->vertexBufferBinding;
    bind->setBinding(0, vbuf);

	/// Allocate index buffer of the requested number of vertices (ibufCount)
    HardwareIndexBufferSharedPtr faceibuf = HardwareBufferManager::getSingleton().
        createIndexBuffer(
            HardwareIndexBuffer::IT_16BIT,
            ibufCount,
            HardwareBuffer::HBU_STATIC_WRITE_ONLY);

    /// Upload the index data to the card
    faceibuf->writeData(0, faceibuf->getSizeInBytes(), faces, true);

    /// Set parameters of the submesh
    sub->useSharedVertices = true;
    sub->indexData->indexBuffer = faceibuf;
//.........这里部分代码省略.........
开发者ID:adriansnetlis,项目名称:rigs-of-rods,代码行数:101,代码来源:AirBrake.cpp

示例15: createOgreMesh

// Convert Nif::NiTriShape to Ogre::SubMesh, attached to the given
// mesh.
static void createOgreMesh(Mesh *mesh, NiTriShape *shape, const String &material)
{
  NiTriShapeData *data = shape->data.getPtr();
  SubMesh *sub = mesh->createSubMesh(shape->name.toString());

  int nextBuf = 0;

  // This function is just one long stream of Ogre-barf, but it works
  // great.

  // Add vertices
  int numVerts = data->vertices.length / 3;
  sub->vertexData = new VertexData();
  sub->vertexData->vertexCount = numVerts;
  sub->useSharedVertices = false;
  VertexDeclaration *decl = sub->vertexData->vertexDeclaration;
  decl->addElement(nextBuf, 0, VET_FLOAT3, VES_POSITION);
  HardwareVertexBufferSharedPtr vbuf =
    HardwareBufferManager::getSingleton().createVertexBuffer(
      VertexElement::getTypeSize(VET_FLOAT3),
      numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
  vbuf->writeData(0, vbuf->getSizeInBytes(), data->vertices.ptr, true);
  VertexBufferBinding* bind = sub->vertexData->vertexBufferBinding;
  bind->setBinding(nextBuf++, vbuf);

  // Vertex normals
  if(data->normals.length)
    {
      decl->addElement(nextBuf, 0, VET_FLOAT3, VES_NORMAL);
      vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
          VertexElement::getTypeSize(VET_FLOAT3),
          numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
      vbuf->writeData(0, vbuf->getSizeInBytes(), data->normals.ptr, true);
      bind->setBinding(nextBuf++, vbuf);
    }

  // Vertex colors
  if(data->colors.length)
    {
      const float *colors = data->colors.ptr;
      RenderSystem* rs = Root::getSingleton().getRenderSystem();
      std::vector<RGBA> colorsRGB(numVerts);
      RGBA *pColour = &colorsRGB.front();
      for(int i=0; i<numVerts; i++)
	{
	  rs->convertColourValue(ColourValue(colors[0],colors[1],colors[2],
                                             colors[3]),pColour++);
	  colors += 4;
	}
      decl->addElement(nextBuf, 0, VET_COLOUR, VES_DIFFUSE);
      vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
          VertexElement::getTypeSize(VET_COLOUR),
	  numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
      vbuf->writeData(0, vbuf->getSizeInBytes(), &colorsRGB.front(), true);
      bind->setBinding(nextBuf++, vbuf);
    }

  // Texture UV coordinates
  if(data->uvlist.length)
    {
      decl->addElement(nextBuf, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES);
      vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
          VertexElement::getTypeSize(VET_FLOAT2),
          numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY);

      vbuf->writeData(0, vbuf->getSizeInBytes(), data->uvlist.ptr, true);
      bind->setBinding(nextBuf++, vbuf);
    }

  // Triangle faces
  int numFaces = data->triangles.length;
  if(numFaces)
    {
      HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
	createIndexBuffer(HardwareIndexBuffer::IT_16BIT,
			  numFaces,
			  HardwareBuffer::HBU_STATIC_WRITE_ONLY);
      ibuf->writeData(0, ibuf->getSizeInBytes(), data->triangles.ptr, true);
      sub->indexData->indexBuffer = ibuf;
      sub->indexData->indexCount = numFaces;
      sub->indexData->indexStart = 0;
    }

  // Set material if one was given
  if(!material.empty()) sub->setMaterialName(material);

  /* Old commented D code. Might be useful when reimplementing
     animation.
  // Assign this submesh to the given bone
  VertexBoneAssignment v;
  v.boneIndex = ((Bone*)bone)->getHandle();
  v.weight = 1.0;

  std::cerr << "+ Assigning bone index " << v.boneIndex << "\n";

  for(int i=0; i < numVerts; i++)
    {
      v.vertexIndex = i;
//.........这里部分代码省略.........
开发者ID:OndraK,项目名称:openmw,代码行数:101,代码来源:ogre_nif_loader.cpp


注:本文中的HardwareVertexBufferSharedPtr::writeData方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。