//-----------------------------------------------------------------------
	void BillboardChain::setupVertexDeclaration(void)
	{
		if (mVertexDeclDirty)
		{
			VertexDeclaration* decl = mVertexData->vertexDeclaration;
			decl->removeAllElements();

			size_t offset = 0;
			// Add a description for the buffer of the positions of the vertices
			decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
			offset += VertexElement::getTypeSize(VET_FLOAT3);

			if (mUseVertexColour)
			{
				decl->addElement(0, offset, VET_COLOUR, VES_DIFFUSE);
				offset += VertexElement::getTypeSize(VET_COLOUR);
			}

			if (mUseTexCoords)
			{
				decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES);
			}

			if (!mUseTexCoords && !mUseVertexColour)
			{
				LogManager::getSingleton().logMessage(
					"Error - BillboardChain '" + mName + "' is using neither "
					"texture coordinates or vertex colours; it will not be "
					"visible on some rendering APIs so you should change this "
					"so you use one or the other.");
			}
			mVertexDeclDirty = false;
		}
	}
    //---------------------------------------------------------------------
    void BorderPanelOverlayElement::initialise(void)
    {
        bool init = !mInitialised;

        // init mRenderOp2 before calling superclass, as virtual _restoreManualHardwareResources would be called within
        if (init)
        {
            // Setup render op in advance
            mRenderOp2.vertexData = OGRE_NEW VertexData();
            mRenderOp2.vertexData->vertexCount = 4 * 8; // 8 cells, can't necessarily share vertices cos
                                                        // texcoords may differ
            mRenderOp2.vertexData->vertexStart = 0;

            // Vertex declaration
            VertexDeclaration* decl = mRenderOp2.vertexData->vertexDeclaration;
            // Position and texture coords each have their own buffers to allow
            // each to be edited separately with the discard flag
            decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION);
            decl->addElement(TEXCOORD_BINDING, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);

            // Index data
            mRenderOp2.operationType = RenderOperation::OT_TRIANGLE_LIST;
            mRenderOp2.useIndexes = true;
            mRenderOp2.indexData = OGRE_NEW IndexData();
            mRenderOp2.indexData->indexCount = 8 * 6;
            mRenderOp2.indexData->indexStart = 0;
            mRenderOp2.useGlobalInstancingVertexBufferIsAvailable = false;

            // Create sub-object for rendering border
            mBorderRenderable = OGRE_NEW BorderRenderable(this);
        }

        // superclass will handle the interior panel area and call _restoreManualHardwareResources
        PanelOverlayElement::initialise();
    }
    void TextAreaOverlayElement::initialise(void)
    {
        if (!mInitialised)
        {
            // Set up the render op
            // Combine positions and texture coords since they tend to change together
            // since character sizes are different
            mRenderOp.vertexData = OGRE_NEW VertexData();
            VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
            size_t offset = 0;
            // Positions
            decl->addElement(POS_TEX_BINDING, offset, VET_FLOAT3, VES_POSITION);
            offset += VertexElement::getTypeSize(VET_FLOAT3);
            // Texcoords
            decl->addElement(POS_TEX_BINDING, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
            // Colours - store these in a separate buffer because they change less often
            decl->addElement(COLOUR_BINDING, 0, VET_COLOUR, VES_DIFFUSE);

            mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST;
            mRenderOp.useIndexes = false;
            mRenderOp.vertexData->vertexStart = 0;
            mRenderOp.useGlobalInstancingVertexBufferIsAvailable = false;
            // Vertex buffer will be created in checkMemoryAllocation
            mRenderOp.srcRenderable = this;
            checkMemoryAllocation( DEFAULT_INITIAL_CHARS );

            mInitialised = true;
        }

    }
	//---------------------------------------------------------------------
	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));
	}
Exemple #5
0
	ProceduralManualObject* createProceduralParticleSystem()
	{
		particleSystem = static_cast<ProceduralManualObject*>
			(mSceneMgr->createMovableObject("ParticleGSEntity", ProceduralManualObjectFactory::FACTORY_TYPE_NAME));
		particleSystem->setMaterial("Ogre/ParticleGS/Display");

		//Generate the geometry that will seed the particle system
		ManualObject* particleSystemSeed = mSceneMgr->createManualObject("ParticleSeed");
		//This needs to be the initial launcher particle
		particleSystemSeed->begin("Ogre/ParticleGS/Display", RenderOperation::OT_POINT_LIST);
		particleSystemSeed->position(0,0,0); //Position
		particleSystemSeed->textureCoord(1); //Timer
		particleSystemSeed->textureCoord(0); //Type
		particleSystemSeed->textureCoord(0,0,0); //Velocity
		particleSystemSeed->end();

		//Generate the RenderToBufferObject
		RenderToVertexBufferSharedPtr r2vbObject = 
			HardwareBufferManager::getSingleton().createRenderToVertexBuffer();
		r2vbObject->setRenderToBufferMaterialName("Ogre/ParticleGS/Generate");
		
		//Apply the random texture
		TexturePtr randomTexture = RandomTools::generateRandomVelocityTexture();
		r2vbObject->getRenderToBufferMaterial()->getTechnique(0)->getPass(0)->
			getTextureUnitState("RandomTexture")->setTextureName(
			randomTexture->getName(), randomTexture->getTextureType());

		r2vbObject->setOperationType(RenderOperation::OT_POINT_LIST);
		r2vbObject->setMaxVertexCount(16000);
		r2vbObject->setResetsEveryUpdate(false);
		VertexDeclaration* vertexDecl = r2vbObject->getVertexDeclaration();
		size_t offset = 0;
		offset += vertexDecl->addElement(0, offset, VET_FLOAT3, VES_POSITION).getSize(); //Position
		offset += vertexDecl->addElement(0, offset, VET_FLOAT1, VES_TEXTURE_COORDINATES, 0).getSize(); //Timer
		offset += vertexDecl->addElement(0, offset, VET_FLOAT1, VES_TEXTURE_COORDINATES, 1).getSize(); //Type
		offset += vertexDecl->addElement(0, offset, VET_FLOAT3, VES_TEXTURE_COORDINATES, 2).getSize(); //Velocity
		
		//Bind the two together
		particleSystem->setRenderToVertexBuffer(r2vbObject);
		particleSystem->setManualObject(particleSystemSeed);

		//Set bounds
		AxisAlignedBox aabb;
		aabb.setMinimum(-100,-100,-100);
		aabb.setMaximum(100,100,100);
		particleSystem->setBoundingBox(aabb);
		
		return particleSystem;
	}
	//-------------------------------------------------------------------------------//
	void OverlayPanelElement::initialise(const String& texName, float width, float height, float left, float top)
	{
		mTexture = TextureMgr::getSingletonPtr()->getByName(texName);
		setSize(width, height);
		setPosition(left, top);
		mIsVisible = true;

		if(!mIsInitialised)
		{
			mRenderData.vertexData = TITAN_NEW VertexData();
			VertexDeclaration* decl = mRenderData.vertexData->vertexDecl;
			decl->addElement(0,0, VET_FLOAT3, VES_POSITION);

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

			VertexBufferPtr vbuf = HardwareBufferMgr::getSingletonPtr()->createVertexBuffer(decl->getVertexSize(0), mRenderData.vertexData->vertexCount,
				HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
			mRenderData.vertexData->vertexBufferBinding->setBinding(0, vbuf);

			mRenderData.useIndex = false;
			mRenderData.operationType = OT_TRIANGLE_STRIP;

			mIsInitialised = true;
		}

		notifyGeometryOld();
	}
    void WireBoundingBox::_initWireBoundingBox()
    {
        mRenderOp.vertexData = OGRE_NEW VertexData();

        mRenderOp.indexData = 0;
        mRenderOp.vertexData->vertexCount = 24; 
        mRenderOp.vertexData->vertexStart = 0; 
        mRenderOp.operationType = RenderOperation::OT_LINE_LIST; 
        mRenderOp.useIndexes = false; 
        mRenderOp.useGlobalInstancingVertexBufferIsAvailable = false;

        VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
        VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;

        decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION);


        HardwareVertexBufferSharedPtr vbuf = 
            HardwareBufferManager::getSingleton().createVertexBuffer(
                decl->getVertexSize(POSITION_BINDING),
                mRenderOp.vertexData->vertexCount,
                HardwareBuffer::HBU_STATIC_WRITE_ONLY);

        // Bind buffer
        bind->setBinding(POSITION_BINDING, vbuf);

        // set basic white material
        this->setMaterial("BaseWhiteNoLighting");


        
    }
    //---------------------------------------------------------------------
    void PanelOverlayElement::initialise(void)
    {
		bool init = !mInitialised;

		OverlayContainer::initialise();
		if (init)
		{
			// Setup render op in advance
			mRenderOp.vertexData = OGRE_NEW VertexData();
			// Vertex declaration: 1 position, add texcoords later depending on #layers
			// Create as separate buffers so we can lock & discard separately
			VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
			decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION);

			// Basic vertex data
			mRenderOp.vertexData->vertexStart = 0;
			mRenderOp.vertexData->vertexCount = 4;

			// Vertex buffer #1
			HardwareVertexBufferSharedPtr vbuf =
				HardwareBufferManager::getSingleton().createVertexBuffer(
				decl->getVertexSize(POSITION_BINDING), mRenderOp.vertexData->vertexCount,
				HardwareBuffer::HBU_STATIC_WRITE_ONLY// mostly static except during resizing
				);
			// Bind buffer
			mRenderOp.vertexData->vertexBufferBinding->setBinding(POSITION_BINDING, vbuf);

			// No indexes & issue as a strip
			mRenderOp.useIndexes = false;
			mRenderOp.operationType = RenderOperation::OT_TRIANGLE_STRIP;

			mInitialised = true;
		}
    }
Exemple #9
0
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);
}
    //---------------------------------------------------------------------
    void PanelOverlayElement::initialise(void)
    {
        bool init = !mInitialised;

        OverlayContainer::initialise();
        if (init)
        {
            // Setup render op in advance
            mRenderOp.vertexData = OGRE_NEW VertexData();
            // Vertex declaration: 1 position, add texcoords later depending on #layers
            // Create as separate buffers so we can lock & discard separately
            VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
            decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION);

            // Basic vertex data
            mRenderOp.vertexData->vertexStart = 0;
            mRenderOp.vertexData->vertexCount = 4;
            // No indexes & issue as a strip
            mRenderOp.useIndexes = false;
            mRenderOp.operationType = RenderOperation::OT_TRIANGLE_STRIP;
            mRenderOp.useGlobalInstancingVertexBufferIsAvailable = false;

            mInitialised = true;

            _restoreManualHardwareResources();
        }
    }
Exemple #11
0
void Line3D::drawLines(void)
{
   if(mDrawn)
      return;
   else
      mDrawn = true;

   // Initialization stuff
   mRenderOp.indexData = 0;
   mRenderOp.vertexData->vertexCount = mPoints.size();
   mRenderOp.vertexData->vertexStart = 0;
   mRenderOp.operationType = RenderOperation::OT_LINE_LIST; // OT_LINE_LIST, OT_LINE_STRIP
   mRenderOp.useIndexes = false;

   VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration;
   VertexBufferBinding *bind = mRenderOp.vertexData->vertexBufferBinding;

   decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION);

   HardwareVertexBufferSharedPtr vbuf =
      HardwareBufferManager::getSingleton().createVertexBuffer(
         decl->getVertexSize(POSITION_BINDING),
         mRenderOp.vertexData->vertexCount,
         HardwareBuffer::HBU_STATIC_WRITE_ONLY);

   bind->setBinding(POSITION_BINDING, vbuf);

   // Drawing stuff
   int size = mPoints.size();
   Vector3 vaabMin = mPoints[0];
   Vector3 vaabMax = mPoints[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();

   mBox.setExtents(vaabMin, vaabMax);
}
Exemple #12
0
void GeomUtils::createCone(Ogre::VertexData*& vertexData, Ogre::IndexData*& indexData, 
					   float radius , float height, int nVerticesInBase)
{
	assert(vertexData && indexData);

	// define the vertex format
	VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
	// positions
	vertexDecl->addElement(0, 0, VET_FLOAT3, VES_POSITION);
	
	// allocate the vertex buffer
	vertexData->vertexCount = nVerticesInBase + 1;
	HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
	VertexBufferBinding* binding = vertexData->vertexBufferBinding;
	binding->setBinding(0, vBuf);
	float* pVertex = static_cast<float*>(vBuf->lock(HardwareBuffer::HBL_DISCARD));

	// allocate index buffer - cone and base
	indexData->indexCount = (3 * nVerticesInBase) + (3 * (nVerticesInBase - 2));
	indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
	HardwareIndexBufferSharedPtr iBuf = indexData->indexBuffer;
	unsigned short* pIndices = static_cast<unsigned short*>(iBuf->lock(HardwareBuffer::HBL_DISCARD));

	//Positions : cone head and base
	for (int i=0; i<3; i++)
		*pVertex++ = 0.0f;

	//Base :
	float fDeltaBaseAngle = (2 * Math::PI) / nVerticesInBase;
	for (int i=0; i<nVerticesInBase; i++)
	{
		float angle = i * fDeltaBaseAngle;
		*pVertex++ = radius * cosf(angle);
		*pVertex++ = height;
		*pVertex++ = radius * sinf(angle);
	}

	//Indices :
	//Cone head to vertices
	for (int i=0; i<nVerticesInBase; i++)
	{
		*pIndices++ = 0;
		*pIndices++ = (i%nVerticesInBase) + 1;
		*pIndices++ = ((i+1)%nVerticesInBase) + 1;
	}
	//Cone base
	for (int i=0; i<nVerticesInBase-2; i++)
	{
		*pIndices++ = 1;
		*pIndices++ = i + 3;
		*pIndices++ = i + 2;
	}

	// Unlock
	vBuf->unlock();
	iBuf->unlock();
}
  DebugRectangle2D::DebugRectangle2D() : SimpleRenderable ()
  {
#ifdef PLSM2_EIHORT
    mUseIdentityProjection = true;
    mUseIdentityView = true;
#endif
    mRenderOp.indexData = new IndexData();
    mRenderOp.vertexData = new VertexData();
    mRenderOp.operationType = RenderOperation::OT_LINE_LIST;
    mRenderOp.indexData->indexCount = 8;
    mRenderOp.vertexData->vertexCount = 4;
    mRenderOp.vertexData->vertexStart = 0;
    mRenderOp.useIndexes = true;

    VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
    VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;

    decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION);
    const size_t offset = VertexElement::getTypeSize(VET_FLOAT3);
    decl->addElement (POSITION_BINDING, offset, VET_COLOUR, VES_DIFFUSE);

    mRenderOp.indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(
        HardwareIndexBuffer::IT_16BIT,
        mRenderOp.indexData->indexCount,
        HardwareBuffer::HBU_STATIC_WRITE_ONLY);

    HardwareVertexBufferSharedPtr vbuf =
    HardwareBufferManager::getSingleton().createVertexBuffer(
        decl->getVertexSize(POSITION_BINDING),
        mRenderOp.vertexData->vertexCount,
        HardwareBuffer::HBU_STATIC_WRITE_ONLY);

    // Bind buffer
    bind->setBinding(POSITION_BINDING, vbuf);

    SimpleRenderable::setBoundingBox(AxisAlignedBox(-1000 * Vector3::UNIT_SCALE,
            1000 * Vector3::UNIT_SCALE));

    SimpleRenderable::setRenderQueueGroup (RENDER_QUEUE_OVERLAY);

    // set basic white material
    SimpleRenderable::setMaterial("BaseWhiteNoLighting");
  }
    //-----------------------------------------------------------------------------
    VertexDeclaration* VertexDeclaration::clone(void)
    {
        VertexDeclaration* ret = HardwareBufferManager::getSingleton().createVertexDeclaration();

		VertexElementList::const_iterator i, iend;
		iend = mElementList.end();
		for (i = mElementList.begin(); i != iend; ++i)
		{
            ret->addElement(i->getSource(), i->getOffset(), i->getType(), i->getSemantic(), i->getIndex());
        }
        return ret;
    }
   void EffectBillboardChain::_createBuffer(void)
   {
	   if (mRenderOp.vertexData)
	   {
		   delete mRenderOp.vertexData;
		   mRenderOp.vertexData = NULL;
	   }

	   mRenderOp.vertexData = new VertexData();
	   mRenderOp.indexData = NULL;
	   mRenderOp.vertexData->vertexCount = mCurrentNbChainElements * 2;
	   mRenderOp.vertexData->vertexStart = 0;
	   mRenderOp.operationType = RenderOperation::OT_TRIANGLE_STRIP;
	   mRenderOp.useIndexes = false;

	   VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
	   VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;

	   // Add a description for the buffer of the positions of the vertices
       size_t offset = 0;
	   decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
       offset += VertexElement::getTypeSize(VET_FLOAT3);

       decl->addElement(0, offset, VET_COLOUR, VES_DIFFUSE);
       offset += VertexElement::getTypeSize(VET_COLOUR);

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

	   // Create the buffer
	   HardwareVertexBufferSharedPtr pVertexBuffer =
		   HardwareBufferManager::getSingleton().createVertexBuffer(
		   decl->getVertexSize(0),
		   mCurrentNbChainElements * 2,
		   HardwareBuffer::HBU_STATIC_WRITE_ONLY);

	   // Bind the buffer
	   bind->setBinding(0, pVertexBuffer);
   }
SurfacePatchRenderable::SurfacePatchRenderable() : SimpleRenderable()
{
	// Set up what we can of the vertex data
	mRenderOp.vertexData = new VertexData();
	mRenderOp.vertexData->vertexStart = 0;
	mRenderOp.vertexData->vertexCount = 0;
	mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST;

	// Set up what we can of the index data
	mRenderOp.indexData = new IndexData();
	mRenderOp.useIndexes = true;
	mRenderOp.indexData->indexStart = 0;
	mRenderOp.indexData->indexCount = 0;

	// Set up the vertex declaration
	VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration;
	decl->removeAllElements();
	decl->addElement(0, 0, VET_FLOAT3, VES_POSITION);
	decl->addElement(0, 3 * sizeof(float), VET_FLOAT3, VES_NORMAL);
	decl->addElement(0, 6 * sizeof(float), VET_FLOAT3, VES_TEXTURE_COORDINATES);
	decl->addElement(0, 9 * sizeof(float), VET_FLOAT3, VES_TEXTURE_COORDINATES, 1);
}
Exemple #17
0
	//-------------------------------------------------------------------------------//
	void OverlayPanelElement::updateTexData()
	{
		if(!mTexture.isNull() &&mIsInitialised)
		{
			VertexDeclaration* decl = mRenderData.vertexData->vertexDecl;
			if(mTexCoordNum == 0)
			{
				decl->addElement(1, 0,VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);

				VertexBufferPtr vbuf = HardwareBufferMgr::getSingletonPtr()->createVertexBuffer(decl->getVertexSize(1), mRenderData.vertexData->vertexCount,
					HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);

				mRenderData.vertexData->vertexBufferBinding->setBinding(1,vbuf);
				mTexCoordNum = 1;
			}

			if(mTexCoordNum)
			{
				VertexBufferPtr buf = mRenderData.vertexData->vertexBufferBinding->getBuffer(1);
				float* pVBStart = static_cast<float*>(buf->lock(HardwareBuffer::HBL_DISCARD));

				size_t uvSize = VertexElement::getTypeSize(VET_FLOAT2) / sizeof(float);
				size_t vertexSize = decl->getVertexSize(1) / sizeof(float);
				
				float* pTex = pVBStart;

				pTex[0] = mU1;	pTex[1] = mV1;
				pTex += vertexSize;

				pTex[0] = mU1;	pTex[1] = mV2;
				pTex += vertexSize;
				
				pTex[0] = mU2;	pTex[1] = mV1;
				pTex += vertexSize;

				pTex[0] = mU2;	pTex[1] = mV2;

				buf->unlock();
			}
			
		}
	}
    //---------------------------------------------------------------------
    void PanelOverlayElement::updateTextureGeometry(void)
    {
        // Generate for as many texture layers as there are in material
        if (!mpMaterial.isNull() && mInitialised)
        {
            // Assume one technique and pass for the moment
            size_t numLayers = mpMaterial->getTechnique(0)->getPass(0)->getNumTextureUnitStates();

            VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
            // Check the number of texcoords we have in our buffer now
            if (mNumTexCoordsInBuffer > numLayers)
            {
                // remove extras
                for (size_t i = mNumTexCoordsInBuffer; i > numLayers; --i)
                {
                    decl->removeElement(VES_TEXTURE_COORDINATES, 
						static_cast<unsigned short>(i));
                }
            }
            else if (mNumTexCoordsInBuffer < numLayers)
            {
                // Add extra texcoord elements
                size_t offset = VertexElement::getTypeSize(VET_FLOAT2) * mNumTexCoordsInBuffer;
                for (size_t i = mNumTexCoordsInBuffer; i < numLayers; ++i)
                {
                    decl->addElement(TEXCOORD_BINDING,
                        offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 
						static_cast<unsigned short>(i));
                    offset += VertexElement::getTypeSize(VET_FLOAT2);

                }
            }

            // if number of layers changed at all, we'll need to reallocate buffer
            if (mNumTexCoordsInBuffer != numLayers)
            {
                // NB reference counting will take care of the old one if it exists
                HardwareVertexBufferSharedPtr newbuf =
                    HardwareBufferManager::getSingleton().createVertexBuffer(
                    decl->getVertexSize(TEXCOORD_BINDING), mRenderOp.vertexData->vertexCount,
                    HardwareBuffer::HBU_STATIC_WRITE_ONLY // mostly static except during resizing
                    );
                // Bind buffer, note this will unbind the old one and destroy the buffer it had
                mRenderOp.vertexData->vertexBufferBinding->setBinding(TEXCOORD_BINDING, newbuf);
                // Set num tex coords in use now
                mNumTexCoordsInBuffer = numLayers;
            }

            // Get the tcoord buffer & lock
			if (mNumTexCoordsInBuffer)
			{
				HardwareVertexBufferSharedPtr vbuf =
					mRenderOp.vertexData->vertexBufferBinding->getBuffer(TEXCOORD_BINDING);
				float* pVBStart = static_cast<float*>(
					vbuf->lock(HardwareBuffer::HBL_DISCARD) );

				size_t uvSize = VertexElement::getTypeSize(VET_FLOAT2) / sizeof(float);
				size_t vertexSize = decl->getVertexSize(TEXCOORD_BINDING) / sizeof(float);
				for (ushort i = 0; i < numLayers; ++i)
				{
				    // Calc upper tex coords
                    Real upperX = mU2 * mTileX[i];
                    Real upperY = mV2 * mTileY[i];


				    /*
					    0-----2
					    |    /|
					    |  /  |
					    |/    |
					    1-----3
				    */
				    // Find start offset for this set
				    float* pTex = pVBStart + (i * uvSize);

                    pTex[0] = mU1;
                    pTex[1] = mV1;

                    pTex += vertexSize; // jump by 1 vertex stride
                    pTex[0] = mU1;
                    pTex[1] = upperY;

                    pTex += vertexSize;
                    pTex[0] = upperX;
                    pTex[1] = mV1;

                    pTex += vertexSize;
                    pTex[0] = upperX;
                    pTex[1] = upperY;
				}
				vbuf->unlock();
			}
        }
    }
	//---------------------------------------------------------------------
	void PrefabFactory::createSphere(Mesh* mesh)
	{
		// sphere creation code taken from the DeferredShading sample, originally from the wiki
		SubMesh *pSphereVertex = mesh->createSubMesh();

		const int NUM_SEGMENTS = 16;
		const int NUM_RINGS = 16;
		const Real SPHERE_RADIUS = 50.0;

		mesh->sharedVertexData = OGRE_NEW VertexData();
		VertexData* vertexData = mesh->sharedVertexData;

		// define the vertex format
		VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
		size_t currOffset = 0;
		// positions
		vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION);
		currOffset += VertexElement::getTypeSize(VET_FLOAT3);
		// normals
		vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL);
		currOffset += VertexElement::getTypeSize(VET_FLOAT3);
		// two dimensional texture coordinates
		vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);

		// allocate the vertex buffer
		vertexData->vertexCount = (NUM_RINGS + 1) * (NUM_SEGMENTS+1);
		HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
		VertexBufferBinding* binding = vertexData->vertexBufferBinding;
		binding->setBinding(0, vBuf);
		float* pVertex = static_cast<float*>(vBuf->lock(HardwareBuffer::HBL_DISCARD));

		// allocate index buffer
		pSphereVertex->indexData->indexCount = 6 * NUM_RINGS * (NUM_SEGMENTS + 1);
		pSphereVertex->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, pSphereVertex->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
		HardwareIndexBufferSharedPtr iBuf = pSphereVertex->indexData->indexBuffer;
		unsigned short* pIndices = static_cast<unsigned short*>(iBuf->lock(HardwareBuffer::HBL_DISCARD));

		float fDeltaRingAngle = (Math::PI / NUM_RINGS);
		float fDeltaSegAngle = (2 * Math::PI / NUM_SEGMENTS);
		unsigned short wVerticeIndex = 0 ;

		// Generate the group of rings for the sphere
		for( int ring = 0; ring <= NUM_RINGS; ring++ ) {
			float r0 = SPHERE_RADIUS * sinf (ring * fDeltaRingAngle);
			float y0 = SPHERE_RADIUS * cosf (ring * fDeltaRingAngle);

			// Generate the group of segments for the current ring
			for(int seg = 0; seg <= NUM_SEGMENTS; seg++) {
				float x0 = r0 * sinf(seg * fDeltaSegAngle);
				float z0 = r0 * cosf(seg * fDeltaSegAngle);

				// Add one vertex to the strip which makes up the sphere
				*pVertex++ = x0;
				*pVertex++ = y0;
				*pVertex++ = z0;

				Vector3 vNormal = Vector3(x0, y0, z0).normalisedCopy();
				*pVertex++ = vNormal.x;
				*pVertex++ = vNormal.y;
				*pVertex++ = vNormal.z;

				*pVertex++ = (float) seg / (float) NUM_SEGMENTS;
				*pVertex++ = (float) ring / (float) NUM_RINGS;

				if (ring != NUM_RINGS) {
					// each vertex (except the last) has six indicies pointing to it
					*pIndices++ = wVerticeIndex + NUM_SEGMENTS + 1;
					*pIndices++ = wVerticeIndex;               
					*pIndices++ = wVerticeIndex + NUM_SEGMENTS;
					*pIndices++ = wVerticeIndex + NUM_SEGMENTS + 1;
					*pIndices++ = wVerticeIndex + 1;
					*pIndices++ = wVerticeIndex;
					wVerticeIndex ++;
				}
			}; // end for seg
		} // end for ring

		// Unlock
		vBuf->unlock();
		iBuf->unlock();
		// Generate face list
		pSphereVertex->useSharedVertices = true;

		// the original code was missing this line:
		mesh->_setBounds( AxisAlignedBox( Vector3(-SPHERE_RADIUS, -SPHERE_RADIUS, -SPHERE_RADIUS), 
			Vector3(SPHERE_RADIUS, SPHERE_RADIUS, SPHERE_RADIUS) ), false );

		mesh->_setBoundingSphereRadius(SPHERE_RADIUS);
	}
	//---------------------------------------------------------------------
	void PrefabFactory::createCube(Mesh* mesh)
	{
		SubMesh* sub = mesh->createSubMesh();

		const int NUM_VERTICES = 4 * 6; // 4 vertices per side * 6 sides
		const int NUM_ENTRIES_PER_VERTEX = 8;
		const int NUM_VERTEX_ENTRIES = NUM_VERTICES * NUM_ENTRIES_PER_VERTEX;
		const int NUM_INDICES = 3 * 2 * 6; // 3 indices per face * 2 faces per side * 6 sides

		const Real CUBE_SIZE = 100.0f;
		const Real CUBE_HALF_SIZE = CUBE_SIZE / 2.0f;

		// Create 4 vertices per side instead of 6 that are shared for the whole cube.
		// The reason for this is with only 6 vertices the normals will look bad
		// since each vertex can "point" in a different direction depending on the face it is included in.
		float vertices[NUM_VERTEX_ENTRIES] = {
			// front side
			-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,	// pos
			0,0,1,	// normal
			0,1,	// texcoord
			CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			0,0,1,
			1,1,
			CUBE_HALF_SIZE,  CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			0,0,1,
			1,0,
			-CUBE_HALF_SIZE,  CUBE_HALF_SIZE, CUBE_HALF_SIZE ,
			0,0,1,
			0,0,

			// back side
			CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			0,0,-1,
			0,1,
			-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			0,0,-1,
			1,1,
			-CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			0,0,-1,
			1,0,
			CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			0,0,-1,
			0,0,

			// left side
			-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			-1,0,0,
			0,1,
			-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			-1,0,0,
			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, 

			// right side
			CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			1,0,0,
			0,1,
			CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			1,0,0,
			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);
	}
Exemple #21
0
	void Rectangle2D::_initRectangle2D(bool includeTextureCoords, Ogre::HardwareBuffer::Usage vBufUsage) 
    {
        // use identity projection and view matrices
        mUseIdentityProjection = true;
        mUseIdentityView = true;

        mRenderOp.vertexData = OGRE_NEW VertexData();

        mRenderOp.indexData = 0;
        mRenderOp.vertexData->vertexCount = 4; 
        mRenderOp.vertexData->vertexStart = 0; 
        mRenderOp.operationType = RenderOperation::OT_TRIANGLE_STRIP; 
        mRenderOp.useIndexes = false; 
        mRenderOp.useGlobalInstancingVertexBufferIsAvailable = false;

        VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
        VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;

        decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION);


        HardwareVertexBufferSharedPtr vbuf = 
            HardwareBufferManager::getSingleton().createVertexBuffer(
            decl->getVertexSize(POSITION_BINDING),
            mRenderOp.vertexData->vertexCount,
            vBufUsage);

        // Bind buffer
        bind->setBinding(POSITION_BINDING, vbuf);

		decl->addElement(NORMAL_BINDING, 0, VET_FLOAT3, VES_NORMAL);

		vbuf = 
			HardwareBufferManager::getSingleton().createVertexBuffer(
            decl->getVertexSize(NORMAL_BINDING),
            mRenderOp.vertexData->vertexCount,
            vBufUsage);

		bind->setBinding(NORMAL_BINDING, vbuf);

		float *pNorm = static_cast<float*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));
		*pNorm++ = 0.0f;
		*pNorm++ = 0.0f;
		*pNorm++ = 1.0f;

		*pNorm++ = 0.0f;
		*pNorm++ = 0.0f;
		*pNorm++ = 1.0f;

		*pNorm++ = 0.0f;
		*pNorm++ = 0.0f;
		*pNorm++ = 1.0f;

		*pNorm++ = 0.0f;
		*pNorm++ = 0.0f;
		*pNorm++ = 1.0f;

		vbuf->unlock();

        if (includeTextureCoords)
        {
            decl->addElement(TEXCOORD_BINDING, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES);


            HardwareVertexBufferSharedPtr tvbuf = 
                HardwareBufferManager::getSingleton().createVertexBuffer(
                decl->getVertexSize(TEXCOORD_BINDING),
                mRenderOp.vertexData->vertexCount,
                vBufUsage);

            // Bind buffer
            bind->setBinding(TEXCOORD_BINDING, tvbuf);

            // Set up basic tex coordinates
            setDefaultUVs();
        }

        // set basic white material
        this->setMaterial("BaseWhiteNoLighting");
    }
Exemple #22
0
WaterMesh::WaterMesh(const String& inMeshName, Real planeSize, int inComplexity)
{
    int x,y,b; // I prefer to initialize for() variables inside it, but VC doesn't like it ;(

    this->meshName = inMeshName ;
    this->complexity = inComplexity ;
    numFaces = 2 * complexity * complexity;
    numVertices = (complexity + 1) * (complexity + 1) ;
    lastTimeStamp = 0 ;
    lastAnimationTimeStamp = 0;
    lastFrameTime = 0 ;

    // initialize algorithm parameters
    PARAM_C = 0.3f ; // ripple speed
    PARAM_D = 0.4f ; // distance
    PARAM_U = 0.05f ; // viscosity
    PARAM_T = 0.13f ; // time
    useFakeNormals = false ;

    // allocate space for normal calculation
    vNormals = new Vector3[numVertices];

    // create mesh and submesh
    mesh = MeshManager::getSingleton().createManual(meshName,
        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
    subMesh = mesh->createSubMesh();
    subMesh->useSharedVertices=false;

    // Vertex buffers
    subMesh->vertexData = new VertexData();
    subMesh->vertexData->vertexStart = 0;
    subMesh->vertexData->vertexCount = numVertices;

    VertexDeclaration* vdecl = subMesh->vertexData->vertexDeclaration;
    VertexBufferBinding* vbind = subMesh->vertexData->vertexBufferBinding;


    vdecl->addElement(0, 0, VET_FLOAT3, VES_POSITION);
    vdecl->addElement(1, 0, VET_FLOAT3, VES_NORMAL);
    vdecl->addElement(2, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES);

    // Prepare buffer for positions - todo: first attempt, slow
    posVertexBuffer =
         HardwareBufferManager::getSingleton().createVertexBuffer(
            3*sizeof(float),
            numVertices,
            HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
    vbind->setBinding(0, posVertexBuffer);

    // Prepare buffer for normals - write only
    normVertexBuffer =
         HardwareBufferManager::getSingleton().createVertexBuffer(
            3*sizeof(float),
            numVertices,
            HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
    vbind->setBinding(1, normVertexBuffer);

    // Prepare texture coords buffer - static one
    // todo: optimize to write directly into buffer
    float *texcoordsBufData = new float[numVertices*2];
    for(y=0;y<=complexity;y++) {
        for(x=0;x<=complexity;x++) {
            texcoordsBufData[2*(y*(complexity+1)+x)+0] = (float)x / complexity ;
            texcoordsBufData[2*(y*(complexity+1)+x)+1] = 1.0f - ((float)y / (complexity)) ;
        }
    }
    texcoordsVertexBuffer =
         HardwareBufferManager::getSingleton().createVertexBuffer(
            2*sizeof(float),
            numVertices,
            HardwareBuffer::HBU_STATIC_WRITE_ONLY);
    texcoordsVertexBuffer->writeData(0,
        texcoordsVertexBuffer->getSizeInBytes(),
        texcoordsBufData,
        true); // true?
    delete [] texcoordsBufData;
    vbind->setBinding(2, texcoordsVertexBuffer);

    // Prepare buffer for indices
    indexBuffer =
        HardwareBufferManager::getSingleton().createIndexBuffer(
            HardwareIndexBuffer::IT_16BIT,
            3*numFaces,
            HardwareBuffer::HBU_STATIC, true);
    unsigned short *faceVertexIndices = (unsigned short*)
        indexBuffer->lock(0, numFaces*3*2, HardwareBuffer::HBL_DISCARD);
    for(y=0 ; y<complexity ; y++) {
        for(x=0 ; x<complexity ; x++) {
            unsigned short *twoface = faceVertexIndices + (y*complexity+x)*2*3;
            int p0 = y*(complexity+1) + x ;
            int p1 = y*(complexity+1) + x + 1 ;
            int p2 = (y+1)*(complexity+1) + x ;
            int p3 = (y+1)*(complexity+1) + x + 1 ;
            twoface[0]=p2; //first tri
            twoface[1]=p1;
            twoface[2]=p0;
            twoface[3]=p2; //second tri
            twoface[4]=p3;
            twoface[5]=p1;
        }
    }
    indexBuffer->unlock();
    // Set index buffer for this submesh
    subMesh->indexData->indexBuffer = indexBuffer;
    subMesh->indexData->indexStart = 0;
    subMesh->indexData->indexCount = 3*numFaces;

    /*  prepare vertex positions
     *  note - we use 3 vertex buffers, since algorighm uses two last phases
     *  to calculate the next one
     */
    for(b=0;b<3;b++) {
        vertexBuffers[b] = new float[numVertices * 3] ;
        for(y=0;y<=complexity;y++) {
            for(x=0;x<=complexity;x++) {
                int numPoint = y*(complexity+1) + x ;
                float* vertex = vertexBuffers[b] + 3*numPoint ;
                vertex[0]=(float)(x) / (float)(complexity) * (float) planeSize ;
                vertex[1]= 0 ; // rand() % 30 ;
                vertex[2]=(float)(y) / (float)(complexity) * (float) planeSize ;
            }
        }
    }

    AxisAlignedBox meshBounds(0,0,0,
        planeSize,0, planeSize);
    mesh->_setBounds(meshBounds);

    currentBuffNumber = 0 ;
    posVertexBuffer->writeData(0,
        posVertexBuffer->getSizeInBytes(), // size
        vertexBuffers[currentBuffNumber], // source
        true); // discard?

    mesh->load();
    mesh->touch();
}
void NxLine::createVertexDeclaration()
{
	VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration;
	decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION);
	if(mUseVertexColour)decl->addElement( TEXCOORD_BINDING, 0, VET_COLOUR, VES_DIFFUSE );
}
Exemple #24
0
Mesh *GrassLoader::generateGrass_SPRITE(PageInfo &page, GrassLayer *layer, float *grassPositions, unsigned int grassCount)
{
	//Calculate the number of quads to be added
	unsigned int quadCount;
	quadCount = grassCount;

	// check for overflows of the uint16's
	unsigned int maxUInt16 = std::numeric_limits<uint16>::max();
	if(grassCount > maxUInt16)
	{
		LogManager::getSingleton().logMessage("grass count overflow: you tried to use more than " + StringConverter::toString(maxUInt16) + " (thats the maximum) grass meshes for one page");
		return 0;
	}
	if(quadCount > maxUInt16)
	{
		LogManager::getSingleton().logMessage("quad count overflow: you tried to use more than " + StringConverter::toString(maxUInt16) + " (thats the maximum) grass meshes for one page");
		return 0;
	}

	//Create manual mesh to store grass quads
	MeshPtr mesh = MeshManager::getSingleton().createManual(getUniqueID(), ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
	SubMesh *subMesh = mesh->createSubMesh();
	subMesh->useSharedVertices = false;

	//Setup vertex format information
	subMesh->vertexData = new VertexData;
	subMesh->vertexData->vertexStart = 0;
	subMesh->vertexData->vertexCount = 4 * quadCount;

	VertexDeclaration* dcl = subMesh->vertexData->vertexDeclaration;
	size_t offset = 0;
	dcl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
	offset += VertexElement::getTypeSize(VET_FLOAT3);
	dcl->addElement(0, offset, VET_FLOAT4, VES_NORMAL);
	offset += VertexElement::getTypeSize(VET_FLOAT4);
	dcl->addElement(0, offset, VET_COLOUR, VES_DIFFUSE);
	offset += VertexElement::getTypeSize(VET_COLOUR);
	dcl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES);
	offset += VertexElement::getTypeSize(VET_FLOAT2);

	//Populate a new vertex buffer with grass
	HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton()
		.createVertexBuffer(offset, subMesh->vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
	float* pReal = static_cast<float*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));

	//Calculate size variance
	float rndWidth = layer->maxWidth - layer->minWidth;
	float rndHeight = layer->maxHeight - layer->minHeight;

	float minY = Math::POS_INFINITY, maxY = Math::NEG_INFINITY;
	float *posPtr = grassPositions;	//Position array "iterator"
	for (uint16 i = 0; i < grassCount; ++i)
	{
		//Get the x and z positions from the position array
		float x = *posPtr++;
		float z = *posPtr++;

		//Calculate height
		float y;
		if (heightFunction){
			y = heightFunction(x, z, heightFunctionUserData);
		} else {
			y = 0;
		}

		float x1 = (x - page.centerPoint.x);
		float z1 = (z - page.centerPoint.z);

		//Get the color at the grass position
		uint32 color;
		if (layer->colorMap)
			color = layer->colorMap->getColorAt(x, z, layer->mapBounds);
		else
			color = 0xFFFFFFFF;

		//Calculate size
		float rnd = *posPtr++;	//The same rnd value is used for width and height to maintain aspect ratio
		float halfXScale = (layer->minWidth + rndWidth * rnd) * 0.5f;
		float scaleY = (layer->minHeight + rndHeight * rnd);

		//Randomly mirror grass textures
		float uvLeft, uvRight;
		if (*posPtr++ > 0.5f){
			uvLeft = 0;
			uvRight = 1;
		} else {
			uvLeft = 1;
			uvRight = 0;
		}

		//Add vertices
		*pReal++ = x1; *pReal++ = y; *pReal++ = z1;					//center position
		*pReal++ = -halfXScale; *pReal++ = scaleY; *pReal++ = 0; *pReal++ = 0;	//normal (used to store relative corner positions)
		*((uint32*)pReal++) = color;								//color
		*pReal++ = uvLeft; *pReal++ = 0;							//uv

		*pReal++ = x1; *pReal++ = y; *pReal++ = z1;					//center position
		*pReal++ = +halfXScale; *pReal++ = scaleY; *pReal++ = 0; *pReal++ = 0;	//normal (used to store relative corner positions)
		*((uint32*)pReal++) = color;								//color
		*pReal++ = uvRight; *pReal++ = 0;							//uv

		*pReal++ = x1; *pReal++ = y; *pReal++ = z1;					//center position
		*pReal++ = -halfXScale; *pReal++ = 0.0f; *pReal++ = 0; *pReal++ = 0;		//normal (used to store relative corner positions)
		*((uint32*)pReal++) = color;								//color
		*pReal++ = uvLeft; *pReal++ = 1;							//uv

		*pReal++ = x1; *pReal++ = y; *pReal++ = z1;					//center position
		*pReal++ = +halfXScale; *pReal++ = 0.0f; *pReal++ = 0; *pReal++ = 0;		//normal (used to store relative corner positions)
		*((uint32*)pReal++) = color;								//color
		*pReal++ = uvRight; *pReal++ = 1;							//uv

		//Update bounds
		if (y < minY) minY = y;
		if (y + scaleY > maxY) maxY = y + scaleY;
	}

	vbuf->unlock();
	subMesh->vertexData->vertexBufferBinding->setBinding(0, vbuf);

	//Populate index buffer
	subMesh->indexData->indexStart = 0;
	subMesh->indexData->indexCount = 6 * quadCount;
	subMesh->indexData->indexBuffer = HardwareBufferManager::getSingleton()
		.createIndexBuffer(HardwareIndexBuffer::IT_16BIT, subMesh->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
	uint16* pI = static_cast<uint16*>(subMesh->indexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD));
	for (uint16 i = 0; i < quadCount; ++i)
	{
		uint16 offset = i * 4;

		*pI++ = 0 + offset;
		*pI++ = 2 + offset;
		*pI++ = 1 + offset;

		*pI++ = 1 + offset;
		*pI++ = 2 + offset;
		*pI++ = 3 + offset;
	}

	subMesh->indexData->indexBuffer->unlock();
	//subMesh->setBuildEdgesEnabled(autoEdgeBuildEnabled);


	//Finish up mesh
	AxisAlignedBox bounds(page.bounds.left - page.centerPoint.x, minY, page.bounds.top - page.centerPoint.z,
		page.bounds.right - page.centerPoint.x, maxY, page.bounds.bottom - page.centerPoint.z);
	mesh->_setBounds(bounds);
	Vector3 temp = bounds.getMaximum() - bounds.getMinimum();
	mesh->_setBoundingSphereRadius(temp.length() * 0.5f);

	LogManager::getSingleton().setLogDetail(static_cast<LoggingLevel>(0));
	mesh->setAutoBuildEdgeLists(autoEdgeBuildEnabled);
	mesh->load();
	LogManager::getSingleton().setLogDetail(LL_NORMAL);

	//Apply grass material to mesh
	subMesh->setMaterialName(layer->material->getName());

	//Return the mesh
	return mesh.getPointer();
}
void MovableText::_setupGeometry()
{
  assert(mpFont);
  assert(!mpMaterial.isNull());

  unsigned int vertexCount = 0;

  //count letters to determine how many vertices are needed
  std::string::iterator i = mCaption.begin();
  std::string::iterator iend = mCaption.end();
  for ( ; i != iend; ++i )
  {
    if ((*i != ' ') && (*i != '\n'))
    {
      vertexCount += 6;
    }
  }

  if (mRenderOp.vertexData)
  {
    delete mRenderOp.vertexData;
    mRenderOp.vertexData = NULL;
    mUpdateColors = true;
  }

  if (mCaption.empty())
  {
    return;
  }

  if (!mRenderOp.vertexData)
    mRenderOp.vertexData = new VertexData();

  mRenderOp.indexData = 0;
  mRenderOp.vertexData->vertexStart = 0;
  mRenderOp.vertexData->vertexCount = vertexCount;
  mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST;
  mRenderOp.useIndexes = false;

  VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration;
  VertexBufferBinding *bind = mRenderOp.vertexData->vertexBufferBinding;
  size_t offset = 0;

  // create/bind positions/tex.ccord. buffer
  if (!decl->findElementBySemantic(VES_POSITION))
    decl->addElement(POS_TEX_BINDING, offset, VET_FLOAT3, VES_POSITION);

  offset += VertexElement::getTypeSize(VET_FLOAT3);

  if (!decl->findElementBySemantic(VES_TEXTURE_COORDINATES))
    decl->addElement(POS_TEX_BINDING, offset, Ogre::VET_FLOAT2,
        Ogre::VES_TEXTURE_COORDINATES, 0);

  HardwareVertexBufferSharedPtr ptbuf =
      HardwareBufferManager::getSingleton().createVertexBuffer(
          decl->getVertexSize(POS_TEX_BINDING),
          mRenderOp.vertexData->vertexCount,
          HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
  bind->setBinding(POS_TEX_BINDING, ptbuf);

  // Colours - store these in a separate buffer because they change less often
  if (!decl->findElementBySemantic(VES_DIFFUSE))
    decl->addElement(COLOUR_BINDING, 0, VET_COLOUR, VES_DIFFUSE);

  HardwareVertexBufferSharedPtr cbuf =
      HardwareBufferManager::getSingleton().createVertexBuffer(
          decl->getVertexSize(COLOUR_BINDING),
          mRenderOp.vertexData->vertexCount,
          HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
  bind->setBinding(COLOUR_BINDING, cbuf);

  float *pPCBuff =
      static_cast<float*> (ptbuf->lock(HardwareBuffer::HBL_DISCARD));

  Real spaceWidth = mSpaceWidth;
  // Derive space width from a capital A
  if (spaceWidth == 0)
    spaceWidth = mpFont->getGlyphAspectRatio('A') * mCharHeight * 2.0;

  float total_height = mCharHeight;
  float total_width = 0.0f;
  float current_width = 0.0f;
  i = mCaption.begin();
  iend = mCaption.end();
  for ( ; i != iend; ++i )
  {
    if (*i == '\n')
    {
      total_height += mCharHeight + 0.01;

      if ( current_width > total_width )
      {
        total_width = current_width;
        current_width = 0.0;
      }
    }
    else
    {
      current_width += mpFont->getGlyphAspectRatio(*i) * mCharHeight * 2.0;
    }
  }

  if ( current_width > total_width )
  {
    total_width = current_width;
  }

  float top = 0.0f;
  switch (mVerticalAlignment)
  {
  case MovableText::V_ABOVE:
    top = total_height * 2;
    break;
  case MovableText::V_CENTER:
    top = 0.5 * total_height * 2;
    break;
  case MovableText::V_BELOW:
    top = 0.0f;
    break;
  }

  float starting_left = 0.0f;
  switch (mHorizontalAlignment)
  {
  case MovableText::H_LEFT:
    starting_left = 0.0f;
    break;
  case MovableText::H_CENTER:
    starting_left = -total_width / 2.0f;
    break;
  }

  float left = starting_left;

  bool newLine = true;
  Real len = 0.0f;
  // for calculation of AABB
  Ogre::Vector3 min(9999999.0f), max(-9999999.0f), currPos(0.0f);
  Ogre::Real maxSquaredRadius = -99999999.0f;
  float largestWidth = 0.0f;
  for (i = mCaption.begin(); i != iend; ++i)
  {
    if (newLine)
    {
      len = 0.0f;
      for (String::iterator j = i; j != iend && *j != '\n'; j++)
      {
        if (*j == ' ')
          len += spaceWidth;
        else
          len += mpFont->getGlyphAspectRatio(*j) * mCharHeight * 2.0;
      }
      newLine = false;
    }

    if (*i == '\n')
    {
      left = starting_left;
      top -= mCharHeight * 2.0;
      newLine = true;
      continue;
    }

    if (*i == ' ')
    {
      // Just leave a gap, no tris
      left += spaceWidth;
      continue;
    }

    Real horiz_height = mpFont->getGlyphAspectRatio(*i);
    Real u1, u2, v1, v2;
    Ogre::Font::UVRect utmp;
    utmp = mpFont->getGlyphTexCoords(*i);
    u1 = utmp.left;
    u2 = utmp.right;
    v1 = utmp.top;
    v2 = utmp.bottom;

    // each vert is (x, y, z, u, v)
    //-------------------------------------------------------------------------------------
    // First tri
    //
    // Upper left
    currPos = Ogre::Vector3(left, top, 0.0);

    *pPCBuff++ = currPos.x;
    *pPCBuff++ = currPos.y;
    *pPCBuff++ = currPos.z;
    *pPCBuff++ = u1;
    *pPCBuff++ = v1;

    // Deal with bounds


    min.makeFloor(currPos);
    max.makeCeil(currPos);
    maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());

    top -= mCharHeight * 2.0;

    // Bottom left
    currPos = Ogre::Vector3(left, top, 0.0);
    *pPCBuff++ = currPos.x;
    *pPCBuff++ = currPos.y;
    *pPCBuff++ = currPos.z;
    *pPCBuff++ = u1;
    *pPCBuff++ = v2;

    // Deal with bounds
    min.makeFloor(currPos);
    max.makeCeil(currPos);
    maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());

    top += mCharHeight * 2.0;
    left += horiz_height * mCharHeight * 2.0;

    // Top right
    currPos = Ogre::Vector3(left, top, 0.0);
    *pPCBuff++ = currPos.x;
    *pPCBuff++ = currPos.y;
    *pPCBuff++ = currPos.z;
    *pPCBuff++ = u2;
    *pPCBuff++ = v1;
    //-------------------------------------------------------------------------------------

    // Deal with bounds
    min.makeFloor(currPos);
    max.makeCeil(currPos);
    maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());

    //-------------------------------------------------------------------------------------
    // Second tri
    //
    // Top right (again)
    currPos = Ogre::Vector3(left, top, 0.0);
    *pPCBuff++ = currPos.x;
    *pPCBuff++ = currPos.y;
    *pPCBuff++ = currPos.z;
    *pPCBuff++ = u2;
    *pPCBuff++ = v1;

    min.makeFloor(currPos);
    max.makeCeil(currPos);
    maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());

    top -= mCharHeight * 2.0;
    left -= horiz_height * mCharHeight * 2.0;

    // Bottom left (again)
    currPos = Ogre::Vector3(left, top, 0.0);
    *pPCBuff++ = currPos.x;
    *pPCBuff++ = currPos.y;
    *pPCBuff++ = currPos.z;
    *pPCBuff++ = u1;
    *pPCBuff++ = v2;

    min.makeFloor(currPos);
    max.makeCeil(currPos);
    maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());

    left += horiz_height * mCharHeight * 2.0;

    // Bottom right
    currPos = Ogre::Vector3(left, top, 0.0);
    *pPCBuff++ = currPos.x;
    *pPCBuff++ = currPos.y;
    *pPCBuff++ = currPos.z;
    *pPCBuff++ = u2;
    *pPCBuff++ = v2;
    //-------------------------------------------------------------------------------------
    min.makeFloor(currPos);
    max.makeCeil(currPos);
    maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());

    // Go back up with top
    top += mCharHeight * 2.0;

    float currentWidth = (left + 1) / 2 - 0;
    if (currentWidth > largestWidth)
      largestWidth = currentWidth;
  }

  // Unlock vertex buffer
  ptbuf->unlock();

  // update AABB/Sphere radius
  mAABB = Ogre::AxisAlignedBox(min, max);
  mRadius = Ogre::Math::Sqrt(maxSquaredRadius);

  if (mUpdateColors)
    this->_updateColors();

  mNeedUpdate = false;
}
Exemple #26
0
	void _prepareMesh()
	{
		int i,lvl ;

		mesh = MeshManager::getSingleton().createManual(name,
            ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME) ;
		subMesh = mesh->createSubMesh();
		subMesh->useSharedVertices=false;

		int numVertices = 4 ;

		if (first) { // first Circle, create some static common data
			first = false ;

			// static buffer for position and normals
			posnormVertexBuffer =
				HardwareBufferManager::getSingleton().createVertexBuffer(
					6*sizeof(float), // size of one vertex data
					4, // number of vertices
					HardwareBuffer::HBU_STATIC_WRITE_ONLY, // usage
					false); // no shadow buffer
			float *posnormBufData = (float*) posnormVertexBuffer->
				lock(HardwareBuffer::HBL_DISCARD);
			for(i=0;i<numVertices;i++) {
				posnormBufData[6*i+0]=((Real)(i%2)-0.5f)*CIRCLE_SIZE; // pos X
				posnormBufData[6*i+1]=0; // pos Y
				posnormBufData[6*i+2]=((Real)(i/2)-0.5f)*CIRCLE_SIZE; // pos Z
				posnormBufData[6*i+3]=0 ; // normal X
				posnormBufData[6*i+4]=1 ; // normal Y
				posnormBufData[6*i+5]=0 ; // normal Z
			}
			posnormVertexBuffer->unlock();

			// static buffers for 16 sets of texture coordinates
			texcoordsVertexBuffers = new HardwareVertexBufferSharedPtr[16];
			for(lvl=0;lvl<16;lvl++) {
				texcoordsVertexBuffers[lvl] =
					HardwareBufferManager::getSingleton().createVertexBuffer(
						2*sizeof(float), // size of one vertex data
						numVertices, // number of vertices
						HardwareBuffer::HBU_STATIC_WRITE_ONLY, // usage
						false); // no shadow buffer
				float *texcoordsBufData = (float*) texcoordsVertexBuffers[lvl]->
					lock(HardwareBuffer::HBL_DISCARD);
				float x0 = (Real)(lvl % 4) * 0.25 ;
				float y0 = (Real)(lvl / 4) * 0.25 ;
				y0 = 0.75-y0 ; // upside down
				for(i=0;i<4;i++) {
					texcoordsBufData[i*2 + 0]=
						x0 + 0.25 * (Real)(i%2) ;
					texcoordsBufData[i*2 + 1]=
						y0 + 0.25 * (Real)(i/2) ;
				}
				texcoordsVertexBuffers[lvl]->unlock();
			}

			// Index buffer for 2 faces
			unsigned short faces[6] = {2,1,0,  2,3,1};
			indexBuffer =
				HardwareBufferManager::getSingleton().createIndexBuffer(
					HardwareIndexBuffer::IT_16BIT,
					6,
					HardwareBuffer::HBU_STATIC_WRITE_ONLY);
			indexBuffer->writeData(0,
				indexBuffer->getSizeInBytes(),
				faces,
				true); // true?
		}

		// Initialize vertex data
		subMesh->vertexData = new VertexData();
		subMesh->vertexData->vertexStart = 0;
		subMesh->vertexData->vertexCount = 4;
		// first, set vertex buffer bindings
		VertexBufferBinding *vbind = subMesh->vertexData->vertexBufferBinding ;
		vbind->setBinding(0, posnormVertexBuffer);
		vbind->setBinding(1, texcoordsVertexBuffers[0]);
		// now, set vertex buffer declaration
		VertexDeclaration *vdecl = subMesh->vertexData->vertexDeclaration ;
		vdecl->addElement(0, 0, VET_FLOAT3, VES_POSITION);
		vdecl->addElement(0, 3*sizeof(float), VET_FLOAT3, VES_NORMAL);
		vdecl->addElement(1, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES);

		// Initialize index data
		subMesh->indexData->indexBuffer = indexBuffer;
		subMesh->indexData->indexStart = 0;
		subMesh->indexData->indexCount = 6;

		// set mesh bounds
		AxisAlignedBox circleBounds(-CIRCLE_SIZE/2.0f, 0, -CIRCLE_SIZE/2.0f,
			CIRCLE_SIZE/2.0f, 0, CIRCLE_SIZE/2.0f);
		mesh->_setBounds(circleBounds);
        mesh->load();
        mesh->touch();
	}
/* *******************************************************************************
 | implement of CGrassSticks
 ******************************************************************************* */
void 
CGrassSticks::createGrassMesh()
{    
	MeshPtr mesh = MeshManager::getSingleton().createManual(GRASS_MESH_NAME, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);

	// create a submesh with the grass material
	SubMesh* sm = mesh->createSubMesh();
	sm->setMaterialName("Examples/GrassBlades");
	sm->useSharedVertices = false;
	sm->vertexData = OGRE_NEW VertexData();
	sm->vertexData->vertexStart = 0;
	sm->vertexData->vertexCount = 12;
	sm->indexData->indexCount = 18;

	// specify a vertex format declaration for our mesh: 3 floats for position, 3 floats for normal, 2 floats for UV
	VertexDeclaration* decl = sm->vertexData->vertexDeclaration;
    decl->addElement(0, 0, VET_FLOAT3, VES_POSITION);
    decl->addElement(0, sizeof(float) * 3, VET_FLOAT3, VES_NORMAL);
    decl->addElement(0, sizeof(float) * 6, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);

	// create a vertex buffer
	HardwareVertexBufferSharedPtr vb = HardwareBufferManager::getSingleton().createVertexBuffer
		(decl->getVertexSize(0), sm->vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY);

	GrassVertex* verts = (GrassVertex*)vb->lock(HardwareBuffer::HBL_DISCARD);  // start filling in vertex data

	for (unsigned int i = 0; i < 3; i++)  // each grass mesh consists of 3 planes
	{
		// planes intersect along the Y axis with 60 degrees between them
		Real x = Math::Cos(Degree(i * 60)) * GRASS_WIDTH / 2;
		Real z = Math::Sin(Degree(i * 60)) * GRASS_WIDTH / 2;

		for (unsigned int j = 0; j < 4; j++)  // each plane has 4 vertices
		{
			GrassVertex& vert = verts[i * 4 + j];

			vert.x = j < 2 ? -x : x;
			vert.y = j % 2 ? 0 : GRASS_HEIGHT;
			vert.z = j < 2 ? -z : z;

			// all normals point straight up
			vert.nx = 0;
			vert.ny = 1;
			vert.nz = 0;

			vert.u = j < 2 ? 0 : 1;
			vert.v = j % 2;
		}
	}

	vb->unlock();  // commit vertex changes

	sm->vertexData->vertexBufferBinding->setBinding(0, vb);  // bind vertex buffer to our submesh

	// create an index buffer
	sm->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer
		(HardwareIndexBuffer::IT_16BIT, sm->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY);

	// start filling in index data
	Ogre::uint16* indices = (Ogre::uint16*)sm->indexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD);

	for (unsigned int i = 0; i < 3; i++)  // each grass mesh consists of 3 planes
	{
		unsigned int off = i * 4;  // each plane consists of 2 triangles

		*indices++ = 0 + off;
		*indices++ = 3 + off;
		*indices++ = 1 + off;

		*indices++ = 0 + off;
		*indices++ = 2 + off;
		*indices++ = 3 + off;
	}

	sm->indexData->indexBuffer->unlock();  // commit index changes

    // update mesh AABB
    Ogre::AxisAlignedBox aabb;
    aabb.setExtents(-1,-1,-1,1,1,1);
    mesh->_setBounds(aabb);

    // Ogre::MeshSerializer serial;
    // serial.exportMesh(mesh.getPointer(), "grass.mesh");
}
void MovableText::_setupGeometry()
{
    assert(mpFont);
    assert(!mpMaterial.isNull());
 
    unsigned int vertexCount = static_cast<unsigned int>(mCaption.size() * 6);
 
    if (mRenderOp.vertexData)
    {
        // Removed this test as it causes problems when replacing a caption
        // of the same size: replacing "Hello" with "hello"
        // as well as when changing the text alignment
        //if (mRenderOp.vertexData->vertexCount != vertexCount)
        {
            delete mRenderOp.vertexData;
            mRenderOp.vertexData = NULL;
            mUpdateColors = true;
        }
    }
 
    if (!mRenderOp.vertexData)
        mRenderOp.vertexData = new VertexData();
 
    mRenderOp.indexData = 0;
    mRenderOp.vertexData->vertexStart = 0;
    mRenderOp.vertexData->vertexCount = vertexCount;
    mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST; 
    mRenderOp.useIndexes = false; 
 
    VertexDeclaration  *decl = mRenderOp.vertexData->vertexDeclaration;
    VertexBufferBinding   *bind = mRenderOp.vertexData->vertexBufferBinding;
    size_t offset = 0;
 
    // create/bind positions/tex.ccord. buffer
    if (!decl->findElementBySemantic(VES_POSITION))
        decl->addElement(POS_TEX_BINDING, offset, VET_FLOAT3, VES_POSITION);
 
    offset += VertexElement::getTypeSize(VET_FLOAT3);
 
    if (!decl->findElementBySemantic(VES_TEXTURE_COORDINATES))
        decl->addElement(POS_TEX_BINDING, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0);
 
    HardwareVertexBufferSharedPtr ptbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(POS_TEX_BINDING),
        mRenderOp.vertexData->vertexCount,
        HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
    bind->setBinding(POS_TEX_BINDING, ptbuf);
 
    // Colours - store these in a separate buffer because they change less often
    if (!decl->findElementBySemantic(VES_DIFFUSE))
        decl->addElement(COLOUR_BINDING, 0, VET_COLOUR, VES_DIFFUSE);
 
    HardwareVertexBufferSharedPtr cbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(COLOUR_BINDING),
        mRenderOp.vertexData->vertexCount,
        HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
    bind->setBinding(COLOUR_BINDING, cbuf);
 
    size_t charlen = mCaption.size();
    float *pPCBuff = static_cast<float*>(ptbuf->lock(HardwareBuffer::HBL_DISCARD));
 
    float largestWidth = 0;
    float left = 0 * 2.0 - 1.0;
    float top = -((0 * 2.0) - 1.0);
 
    Real spaceWidth = mSpaceWidth;
    // Derive space width from a capital A
    if (spaceWidth == 0)
        spaceWidth = mpFont->getGlyphAspectRatio('A') * mCharHeight * 2.0;
 
    // for calculation of AABB
    Ogre::Vector3 min, max, currPos;
    Ogre::Real maxSquaredRadius;
    bool first = true;
 
    // Use iterator
    String::iterator i, iend;
    iend = mCaption.end();
    bool newLine = true;
    Real len = 0.0f;
 
    Real verticalOffset = 0;
    switch (mVerticalAlignment)
    {
    case MovableText::V_ABOVE:
        verticalOffset = mCharHeight;
        break;
    case MovableText::V_CENTER:
        verticalOffset = 0.5*mCharHeight;
        break;
    case MovableText::V_BELOW:
        verticalOffset = 0;
        break;
    }
    // Raise the first line of the caption
    top += verticalOffset;
    for (i = mCaption.begin(); i != iend; ++i)
    {
        if (*i == '\n')
            top += verticalOffset * 2.0;
    }
 
    for (i = mCaption.begin(); i != iend; ++i)
    {
        if (newLine)
        {
            len = 0.0f;
            for (String::iterator j = i; j != iend && *j != '\n'; j++)
            {
                if (*j == ' ')
                    len += spaceWidth;
                else 
                    len += mpFont->getGlyphAspectRatio((unsigned char)*j) * mCharHeight * 2.0;
            }
            newLine = false;
        }
 
        if (*i == '\n')
        {
            left = 0 * 2.0 - 1.0;
            top -= mCharHeight * 2.0;
            newLine = true;
 
            // Bugfix by Wladimir Lukutin - thanks :)
            // Also reduce tri count
            mRenderOp.vertexData->vertexCount -= 6;
            // Bugfix end.
 
            continue;
        }
 
        if (*i == ' ')
        {
            // Just leave a gap, no tris
            left += spaceWidth;
            // Also reduce tri count
            mRenderOp.vertexData->vertexCount -= 6;
            continue;
        }
 
        Real horiz_height = mpFont->getGlyphAspectRatio((unsigned char)*i);
        Real u1, u2, v1, v2; 
        Ogre::Font::UVRect utmp;
        utmp = mpFont->getGlyphTexCoords((unsigned char)*i);
        u1 = utmp.left;
        u2 = utmp.right;
        v1 = utmp.top;
        v2 = utmp.bottom;
 
        // each vert is (x, y, z, u, v)
        //-------------------------------------------------------------------------------------
        // First tri
        //
        // Upper left
        if(mHorizontalAlignment == MovableText::H_LEFT)
            *pPCBuff++ = left;
        else
            *pPCBuff++ = left - (len / 2);
        *pPCBuff++ = top;
        *pPCBuff++ = -1.0;
        *pPCBuff++ = u1;
        *pPCBuff++ = v1;
 
        // Deal with bounds
        if(mHorizontalAlignment == MovableText::H_LEFT)
            currPos = Ogre::Vector3(left, top, -1.0);
        else
            currPos = Ogre::Vector3(left - (len / 2), top, -1.0);
        if (first)
        {
            min = max = currPos;
            maxSquaredRadius = currPos.squaredLength();
            first = false;
        }
        else
        {
            min.makeFloor(currPos);
            max.makeCeil(currPos);
            maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());
        }
 
        top -= mCharHeight * 2.0;
 
        // Bottom left
        if(mHorizontalAlignment == MovableText::H_LEFT)
            *pPCBuff++ = left;
        else
            *pPCBuff++ = left - (len / 2);
        *pPCBuff++ = top;
        *pPCBuff++ = -1.0;
        *pPCBuff++ = u1;
        *pPCBuff++ = v2;
 
        // Deal with bounds
        if(mHorizontalAlignment == MovableText::H_LEFT)
            currPos = Ogre::Vector3(left, top, -1.0);
        else
            currPos = Ogre::Vector3(left - (len / 2), top, -1.0);
        min.makeFloor(currPos);
        max.makeCeil(currPos);
        maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());
 
        top += mCharHeight * 2.0;
        left += horiz_height * mCharHeight * 2.0;
 
        // Top right
        if(mHorizontalAlignment == MovableText::H_LEFT)
            *pPCBuff++ = left;
        else
            *pPCBuff++ = left - (len / 2);
        *pPCBuff++ = top;
        *pPCBuff++ = -1.0;
        *pPCBuff++ = u2;
        *pPCBuff++ = v1;
        //-------------------------------------------------------------------------------------
 
        // Deal with bounds
        if(mHorizontalAlignment == MovableText::H_LEFT)
            currPos = Ogre::Vector3(left, top, -1.0);
        else
            currPos = Ogre::Vector3(left - (len / 2), top, -1.0);
        min.makeFloor(currPos);
        max.makeCeil(currPos);
        maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());
 
        //-------------------------------------------------------------------------------------
        // Second tri
        //
        // Top right (again)
        if(mHorizontalAlignment == MovableText::H_LEFT)
            *pPCBuff++ = left;
        else
            *pPCBuff++ = left - (len / 2);
        *pPCBuff++ = top;
        *pPCBuff++ = -1.0;
        *pPCBuff++ = u2;
        *pPCBuff++ = v1;
 
        currPos = Ogre::Vector3(left, top, -1.0);
        min.makeFloor(currPos);
        max.makeCeil(currPos);
        maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());
 
        top -= mCharHeight * 2.0;
        left -= horiz_height  * mCharHeight * 2.0;
 
        // Bottom left (again)
        if(mHorizontalAlignment == MovableText::H_LEFT)
            *pPCBuff++ = left;
        else
            *pPCBuff++ = left - (len / 2);
        *pPCBuff++ = top;
        *pPCBuff++ = -1.0;
        *pPCBuff++ = u1;
        *pPCBuff++ = v2;
 
        currPos = Ogre::Vector3(left, top, -1.0);
        min.makeFloor(currPos);
        max.makeCeil(currPos);
        maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());
 
        left += horiz_height  * mCharHeight * 2.0;
 
        // Bottom right
        if(mHorizontalAlignment == MovableText::H_LEFT)
            *pPCBuff++ = left;
        else
            *pPCBuff++ = left - (len / 2);
        *pPCBuff++ = top;
        *pPCBuff++ = -1.0;
        *pPCBuff++ = u2;
        *pPCBuff++ = v2;
        //-------------------------------------------------------------------------------------
 
        currPos = Ogre::Vector3(left, top, -1.0);
        min.makeFloor(currPos);
        max.makeCeil(currPos);
        maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());
 
        // Go back up with top
        top += mCharHeight * 2.0;
 
        float currentWidth = (left + 1)/2 - 0;
        if (currentWidth > largestWidth)
            largestWidth = currentWidth;
    }
 
    // Unlock vertex buffer
    ptbuf->unlock();
 
    // update AABB/Sphere radius
    mAABB = Ogre::AxisAlignedBox(min, max);
    mRadius = Ogre::Math::Sqrt(maxSquaredRadius);
 
    if (mUpdateColors)
        this->_updateColors();
 
    mNeedUpdate = false;
}
Exemple #29
0
void ThingRenderable::initialise()
{
    // Fill array with randomly oriented quads
    Vector3 ax, ay, az;

    Quaternion q;
    things.clear(); orbits.clear();
    for(size_t x=0; x<mCount; x++)
    {
        ax = Vector3(Math::SymmetricRandom(), Math::SymmetricRandom(), Math::SymmetricRandom());
        ay = Vector3(Math::SymmetricRandom(), Math::SymmetricRandom(), Math::SymmetricRandom());
        az = ax.crossProduct(ay);
        ay = az.crossProduct(ax);
        ax.normalise(); ay.normalise(); az.normalise();
        q.FromAxes(ax, ay, az);
        //std::cerr << ax.dotProduct(ay) << " " << ay.dotProduct(az) << " " << az.dotProduct(ax) << std::endl;
        things.push_back(q);
        
        ax = Vector3(Math::SymmetricRandom(), Math::SymmetricRandom(), Math::SymmetricRandom());
        ay = Vector3(Math::SymmetricRandom(), Math::SymmetricRandom(), Math::SymmetricRandom());
        az = ax.crossProduct(ay);
        ay = az.crossProduct(ax);
        ax.normalise(); ay.normalise(); az.normalise();
        q.FromAxes(ax, ay, az);
        orbits.push_back(q);
    }
    
    // Create buffers
    size_t nvertices = mCount*4; // n+1 planes
    //size_t elemsize = 2*3; // position, normal
    //size_t dsize = elemsize*nvertices;
    
    Ogre::IndexData *idata = new Ogre::IndexData();
    Ogre::VertexData *vdata = new Ogre::VertexData();

    // Quads
    unsigned short *faces = new unsigned short[mCount*6];
    for(uint16 x=0; x<uint16(mCount); 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+0;
        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);

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

    bind->setBinding(0, vbuf);

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

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

    // Delete temporary buffers
    delete [] faces;
    
    // Now make the render operation
    mRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
    mRenderOp.indexData = idata;
    mRenderOp.vertexData = vdata;
    mRenderOp.useIndexes = true;
}
Exemple #30
0
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

	// Remove pre-created technique from defaults
	material->removeAllTechniques();
	
	// Create a techinique and a pass and a texture unit
 	Technique * technique = material->createTechnique();
	Pass * pass = technique->createPass();
	TextureUnitState * textureUnit = pass->createTextureUnitState();
	
	// Set pass parameters
	pass->setSceneBlending(SBT_TRANSPARENT_ALPHA);
	pass->setDepthWriteEnabled(false);
	pass->setCullingMode(CULL_NONE);
	pass->setLightingEnabled(false);
	
	// Set texture unit parameters
	textureUnit->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
	textureUnit->setTextureName(mTexture, TEX_TYPE_3D);
	textureUnit->setTextureFiltering(TFO_TRILINEAR);
	
	mUnit = textureUnit;
	m_pMaterial = material;
}