Exemple #1
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 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 TextAreaOverlayElement::_restoreManualHardwareResources()
    {
        if(!mInitialised)
            return;

        // 6 verts per char since we're doing tri lists without indexes
        // Allocate space for positions & texture coords
        // Note - mRenderOp.vertexData->vertexCount will be less than allocatedVertexCount
        size_t allocatedVertexCount = mAllocSize * 6;
        VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
        VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;

        // Create dynamic since text tends to change a lot
        // positions & texcoords
        HardwareVertexBufferSharedPtr vbuf = 
            HardwareBufferManager::getSingleton().
                createVertexBuffer(
                    decl->getVertexSize(POS_TEX_BINDING), 
                    allocatedVertexCount,
                    HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
        bind->setBinding(POS_TEX_BINDING, vbuf);

        // colours
        vbuf = HardwareBufferManager::getSingleton().
                createVertexBuffer(
                    decl->getVertexSize(COLOUR_BINDING), 
                    allocatedVertexCount,
                    HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
        bind->setBinding(COLOUR_BINDING, vbuf);

        // Buffers are restored, but with trash within
        mGeomPositionsOutOfDate = true;
        mGeomUVsOutOfDate = true;
        mColoursChanged = true;
    }
Exemple #4
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);
}
    //---------------------------------------------------------------------
    void TextAreaOverlayElement::_releaseManualHardwareResources()
    {
        if(!mInitialised)
            return;

        VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;
        bind->unsetBinding(POS_TEX_BINDING);
        bind->unsetBinding(COLOUR_BINDING);
    }
Exemple #6
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();
}
	//---------------------------------------------------------------------
	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));
	}
    //---------------------------------------------------------------------
    void BorderPanelOverlayElement::_releaseManualHardwareResources()
    {
        if(!mInitialised)
            return;

        VertexBufferBinding* bind = mRenderOp2.vertexData->vertexBufferBinding;
        bind->unsetBinding(POSITION_BINDING);
        bind->unsetBinding(TEXCOORD_BINDING);

        mRenderOp2.indexData->indexBuffer.setNull();

        PanelOverlayElement::_releaseManualHardwareResources();
    }
	//---------------------------------------------------------------------
	void TangentSpaceCalc::extendBuffers(VertexSplits& vertexSplits)
	{
		if (!vertexSplits.empty())
		{
			// ok, need to increase the vertex buffer size, and alter some indexes

			// vertex buffers first
			VertexBufferBinding* newBindings = HardwareBufferManager::getSingleton().createVertexBufferBinding();
			const VertexBufferBinding::VertexBufferBindingMap& bindmap = 
				mVData->vertexBufferBinding->getBindings();
			for (VertexBufferBinding::VertexBufferBindingMap::const_iterator i = 
				bindmap.begin(); i != bindmap.end(); ++i)
			{
				HardwareVertexBufferSharedPtr srcbuf = i->second;
				// Derive vertex count from buffer not vertex data, in case using
				// the vertexStart option in vertex data
				size_t newVertexCount = srcbuf->getNumVertices() + vertexSplits.size();
				// Create new buffer & bind
				HardwareVertexBufferSharedPtr newBuf = 
					HardwareBufferManager::getSingleton().createVertexBuffer(
					srcbuf->getVertexSize(), newVertexCount, srcbuf->getUsage(), 
					srcbuf->hasShadowBuffer());
				newBindings->setBinding(i->first, newBuf);

				// Copy existing contents (again, entire buffer, not just elements referenced)
				newBuf->copyData(*(srcbuf.get()), 0, 0, srcbuf->getNumVertices() * srcbuf->getVertexSize(), true);

				// Split vertices, read / write from new buffer
				char* pBase = static_cast<char*>(newBuf->lock(HardwareBuffer::HBL_NORMAL));
				for (VertexSplits::iterator spliti = vertexSplits.begin(); 
					spliti != vertexSplits.end(); ++spliti)
				{
					const char* pSrcBase = pBase + spliti->first * newBuf->getVertexSize();
					char* pDstBase = pBase + spliti->second * newBuf->getVertexSize();
					memcpy(pDstBase, pSrcBase, newBuf->getVertexSize());
				}
				newBuf->unlock();

			}

			// Update vertex data
			// Increase vertex count according to num splits
			mVData->vertexCount += vertexSplits.size();
			// Flip bindings over to new buffers (old buffers released)
			HardwareBufferManager::getSingleton().destroyVertexBufferBinding(mVData->vertexBufferBinding);
			mVData->vertexBufferBinding = newBindings;
			
		}

	}
    //-----------------------------------------------------------------------------
    void TempBlendedBufferInfo::extractFrom(const VertexData* sourceData)
    {
        // Release old buffer copies first
        if (!destPositionBuffer.isNull())
        {
            destPositionBuffer->getManager()->releaseVertexBufferCopy(destPositionBuffer);
            assert(destPositionBuffer.isNull());
        }
        if (!destNormalBuffer.isNull())
        {
            destNormalBuffer->getManager()->releaseVertexBufferCopy(destNormalBuffer);
            assert(destNormalBuffer.isNull());
        }

        VertexDeclaration* decl = sourceData->vertexDeclaration;
        VertexBufferBinding* bind = sourceData->vertexBufferBinding;
        const VertexElement *posElem = decl->findElementBySemantic(VES_POSITION);
        const VertexElement *normElem = decl->findElementBySemantic(VES_NORMAL);

        assert(posElem && "Positions are required");

        posBindIndex = posElem->getSource();
        srcPositionBuffer = bind->getBuffer(posBindIndex);

        if (!normElem)
        {
            posNormalShareBuffer = false;
            srcNormalBuffer.setNull();
        }
        else
        {
            normBindIndex = normElem->getSource();
            if (normBindIndex == posBindIndex)
            {
                posNormalShareBuffer = true;
                srcNormalBuffer.setNull();
            }
            else
            {
                posNormalShareBuffer = false;
                srcNormalBuffer = bind->getBuffer(normBindIndex);
            }
        }
    }
  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");
  }
   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);
   }
    //---------------------------------------------------------------------
    void PanelOverlayElement::_releaseManualHardwareResources()
    {
        if(!mInitialised)
            return;

        VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;
        bind->unsetBinding(POSITION_BINDING);

        // Remove all texcoord element declarations
        if(mNumTexCoordsInBuffer > 0)
        {
            bind->unsetBinding(TEXCOORD_BINDING);

            VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
            for(size_t i = mNumTexCoordsInBuffer; i > 0; --i)
            {
                decl->removeElement(VES_TEXTURE_COORDINATES,
                    static_cast<unsigned short>(i - 1));
            }
            mNumTexCoordsInBuffer = 0;
        }
    }
    void TextAreaOverlayElement::checkMemoryAllocation( size_t numChars )
    {
        if( mAllocSize < numChars)
        {
            // Create and bind new buffers
            // Note that old buffers will be deleted automatically through reference counting
            
            // 6 verts per char since we're doing tri lists without indexes
            // Allocate space for positions & texture coords
            VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
            VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;

            mRenderOp.vertexData->vertexCount = numChars * 6;

            // Create dynamic since text tends to change a lot
            // positions & texcoords
            HardwareVertexBufferSharedPtr vbuf = 
                HardwareBufferManager::getSingleton().
                    createVertexBuffer(
                        decl->getVertexSize(POS_TEX_BINDING), 
                        mRenderOp.vertexData->vertexCount,
                        HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
            bind->setBinding(POS_TEX_BINDING, vbuf);

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

            mAllocSize = numChars;
            mColoursChanged = true; // force colour buffer regeneration
        }

    }
	//---------------------------------------------------------------------
	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 #16
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 #17
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 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;
}
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 #20
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;
}
Exemple #21
0
void OgreMesh::syncFromOgreMesh(Ogre::Entity *entity,Ogre::SubMesh*subMesh)
{
  const Ogre::Vector3 &position = entity->getParentNode()->_getDerivedPosition();
  const Ogre::Quaternion &orient = entity->getParentNode()->_getDerivedOrientation();
  const Ogre::Vector3 &scale = entity->getParentNode()->_getDerivedScale();

  VertexData *vertexData = subMesh->vertexData;
  if (vertexData) {
      VertexDeclaration *vertexDecl = vertexData->vertexDeclaration;
      
      // find the element for position
      const VertexElement *element = vertexDecl->findElementBySemantic(Ogre::VES_POSITION);
      
      // find and lock the buffer containing position information
      VertexBufferBinding *bufferBinding = vertexData->vertexBufferBinding;
      HardwareVertexBuffer *buffer = bufferBinding->getBuffer(element->getSource()).get();
      unsigned char *pVert = static_cast<unsigned char*>(buffer->lock(HardwareBuffer::HBL_READ_ONLY));
      std::vector<Ogre::Vector3> lvertices;
      for (size_t vert = 0; vert < vertexData->vertexCount; vert++) {
          Real *vertex = 0;
          Real x, y, z;
          element->baseVertexPointerToElement(pVert, &vertex);
          x = *vertex++;
          y = *vertex++;
          z = *vertex++;
          Ogre::Vector3 vec(x, y, z);
          vec = (orient * (vec * scale)) + position;
          
          lvertices.push_back(vec);
          
          pVert += buffer->getVertexSize();
      }
      buffer->unlock();
      
      // find and lock buffer containg vertex indices
      IndexData * indexData = subMesh->indexData;
      HardwareIndexBuffer *indexBuffer = indexData->indexBuffer.get();
      void *pIndex = static_cast<unsigned char *>(indexBuffer->lock(HardwareBuffer::HBL_READ_ONLY));
      if (indexBuffer->getType() == HardwareIndexBuffer::IT_16BIT) {
          for (size_t index = indexData->indexStart; index < indexData->indexCount; ) {
              uint16 *uint16Buffer = (uint16 *) pIndex;
              uint16 v1 = uint16Buffer[index++];
              uint16 v2 = uint16Buffer[index++];
              uint16 v3 = uint16Buffer[index++];
              
              mTriangles.push_back(Triangle(lvertices[v1], lvertices[v2], lvertices[v3]));
          }
      } else if (indexBuffer->getType() == HardwareIndexBuffer::IT_32BIT) {
          for (size_t index = indexData->indexStart; index < indexData->indexCount; ) {
              uint32 *uint16Buffer = (uint32 *) pIndex;
              uint32 v1 = uint16Buffer[index++];
              uint32 v2 = uint16Buffer[index++];
              uint32 v3 = uint16Buffer[index++];
              
              mTriangles.push_back(Triangle(lvertices[v1], lvertices[v2], lvertices[v3]));
          }
      } else {
          assert(0);
      }
      indexBuffer->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 TangentSpaceCalc::populateVertexArray(unsigned short sourceTexCoordSet)
	{
		// Just pull data out into more friendly structures
		VertexDeclaration *dcl = mVData->vertexDeclaration;
		VertexBufferBinding *bind = mVData->vertexBufferBinding;

		// Get the incoming UV element
		const VertexElement* uvElem = dcl->findElementBySemantic(
			VES_TEXTURE_COORDINATES, sourceTexCoordSet);

		if (!uvElem || uvElem->getType() != VET_FLOAT2)
		{
			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
				"No 2D texture coordinates with selected index, cannot calculate tangents.",
				"TangentSpaceCalc::build");
		}

		HardwareVertexBufferSharedPtr uvBuf, posBuf, normBuf;
		unsigned char *pUvBase, *pPosBase, *pNormBase;
		size_t uvInc, posInc, normInc;

		uvBuf = bind->getBuffer(uvElem->getSource());
		pUvBase = static_cast<unsigned char*>(
			uvBuf->lock(HardwareBuffer::HBL_READ_ONLY));
		uvInc = uvBuf->getVertexSize();
		// offset for vertex start
		pUvBase += mVData->vertexStart * uvInc;

		// find position
		const VertexElement *posElem = dcl->findElementBySemantic(VES_POSITION);
		if (posElem->getSource() == uvElem->getSource())
		{
			pPosBase = pUvBase;
			posInc = uvInc;
		}
		else
		{
			// A different buffer
			posBuf = bind->getBuffer(posElem->getSource());
			pPosBase = static_cast<unsigned char*>(
				posBuf->lock(HardwareBuffer::HBL_READ_ONLY));
			posInc = posBuf->getVertexSize();
			// offset for vertex start
			pPosBase += mVData->vertexStart * posInc;
		}
		// find a normal buffer
		const VertexElement *normElem = dcl->findElementBySemantic(VES_NORMAL);
		if (!normElem)
			OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 
			"No vertex normals found", 
			"TangentSpaceCalc::build");

		if (normElem->getSource() == uvElem->getSource())
		{
			pNormBase = pUvBase;
			normInc = uvInc;
		}
		else if (normElem->getSource() == posElem->getSource())
		{
			// normals are in the same buffer as position
			// this condition arises when an animated(skeleton) mesh is not built with 
			// an edge list buffer ie no shadows being used.
			pNormBase = pPosBase;
			normInc = posInc;
		}
		else
		{
			// A different buffer
			normBuf = bind->getBuffer(normElem->getSource());
			pNormBase = static_cast<unsigned char*>(
				normBuf->lock(HardwareBuffer::HBL_READ_ONLY));
			normInc = normBuf->getVertexSize();
			// offset for vertex start
			pNormBase += mVData->vertexStart * normInc;
		}

		// Preinitialise vertex info
		mVertexArray.clear();
		mVertexArray.resize(mVData->vertexCount);

		float* pFloat;
		VertexInfo* vInfo = &(mVertexArray[0]);
		for (size_t v = 0; v < mVData->vertexCount; ++v, ++vInfo)
		{
			posElem->baseVertexPointerToElement(pPosBase, &pFloat);
			vInfo->pos.x = *pFloat++;
			vInfo->pos.y = *pFloat++;
			vInfo->pos.z = *pFloat++;
			pPosBase += posInc;

			normElem->baseVertexPointerToElement(pNormBase, &pFloat);
			vInfo->norm.x = *pFloat++;
			vInfo->norm.y = *pFloat++;
			vInfo->norm.z = *pFloat++;
			pNormBase += normInc;

			uvElem->baseVertexPointerToElement(pUvBase, &pFloat);
			vInfo->uv.x = *pFloat++;
			vInfo->uv.y = *pFloat++;
			pUvBase += uvInc;


		}

		// unlock buffers
		uvBuf->unlock();
		if (!posBuf.isNull())
		{
			posBuf->unlock();
		}
		if (!normBuf.isNull())
		{
			normBuf->unlock();
		}

	}
Exemple #24
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();
	}
Exemple #25
0
FlexMesh::FlexMesh(
    Ogre::String const & name, 
    RoR::GfxActor* gfx_actor,
    int n1, 
    int n2, 
    int nstart, 
    int nrays,
    Ogre::String const & face_material_name, 
    Ogre::String const & band_material_name, 
    bool rimmed, 
    float rim_ratio
) :
      m_is_rimmed(rimmed)
    , m_num_rays(nrays)
    , m_gfx_actor(gfx_actor)
{
    // Create the mesh via the MeshManager
    m_mesh = MeshManager::getSingleton().createManual(name, gfx_actor->GetResourceGroup());

    // Create submeshes
    m_submesh_wheelface = m_mesh->createSubMesh();
    m_submesh_tiretread = m_mesh->createSubMesh();

    //materials
    m_submesh_wheelface->setMaterialName(face_material_name);
    m_submesh_tiretread->setMaterialName(band_material_name);

    // Define the vertices
    size_t vertex_count = 4*nrays+2; // each ray needs 4 verts (2 for sidewalls and 2 for band). The axis needs an extra 2.
    if (m_is_rimmed) // For truckfile sections "[mesh]wheels2".
    {
        vertex_count+=2*nrays; // 1 extra vertex for each sidewall.
    }
    m_vertices = new FlexMeshVertex[vertex_count];
    m_vertex_nodes=(int*)malloc(vertex_count*sizeof(int));

    //define node ids
    m_vertex_nodes[0]=n1;
    m_vertex_nodes[1]=n2;
    int i;
    for (i=0; i<nrays; i++)
    {
        //face
        m_vertex_nodes[2+i*2]=nstart+i*2;
        m_vertex_nodes[2+i*2+1]=nstart+i*2+1;
        if (m_is_rimmed)
        {
            //band
            m_vertex_nodes[2+2*nrays+i*2]   = nstart+2*nrays+i*2;
            m_vertex_nodes[2+2*nrays+i*2+1] = nstart+2*nrays+i*2+1;
            //face2 (outer)
            m_vertex_nodes[2+4*nrays+i*2]   = nstart+2*nrays+i*2;
            m_vertex_nodes[2+4*nrays+i*2+1] = nstart+2*nrays+i*2+1;
        } else
        {
            //band
            m_vertex_nodes[2+2*nrays+i*2]   = nstart+i*2;
            m_vertex_nodes[2+2*nrays+i*2+1] = nstart+i*2+1;
        }
    }

    //textures coordinates
    m_vertices[0].texcoord=Vector2(0.5, 0.5); // Axis vertices - texcoord is middle of the wheelface texture.
    m_vertices[1].texcoord=Vector2(0.5, 0.5);
    const bool odd_num_rays = (nrays % 2 == 0);
    for (i=0; i<nrays; i++)
    {
        //band
        int band_vert = 2+2*nrays+i*2;
        if (i % 2 == 0) // Even index
        {
            if (odd_num_rays && ((i+1) == nrays))
            {
                // Finalize a wheel with odd number of rays like 'bombinette.load' in 'miniredmars' map.
                m_vertices[band_vert].texcoord=Vector2(0.5, 0.0); // Stretch the texture over 2 quads instead of 1... ugly, but best we can do here
                m_vertices[band_vert+1].texcoord=Vector2(0.5, 1.0);
            }
            else
            {
                m_vertices[band_vert].texcoord=Vector2(0.0, 0.0);
                m_vertices[band_vert+1].texcoord=Vector2(0.0, 1.0);
            }
        }
        else // Odd index
        {
            m_vertices[band_vert].texcoord=Vector2(1.0, 0.0);
            m_vertices[band_vert+1].texcoord=Vector2(1.0, 1.0);
        }

        //face
        if (m_is_rimmed)
        {
            m_vertices[2+i*2].texcoord=Vector2(0.5+0.5*rim_ratio*sin((float)i*2.0*3.14159/nrays), 0.5+0.5*rim_ratio*cos((float)i*2.0*3.14159/nrays));
            m_vertices[2+i*2+1].texcoord=m_vertices[2+i*2].texcoord;
            m_vertices[2+4*nrays+i*2].texcoord=Vector2(0.5+0.5*sin(((float)i+0.5)*2.0*3.14159/nrays), 0.5+0.5*cos(((float)i+0.5)*2.0*3.14159/nrays));
            m_vertices[2+4*nrays+i*2+1].texcoord=m_vertices[2+4*nrays+i*2].texcoord;
        } else
        {
            m_vertices[2+i*2].texcoord=Vector2(0.5+0.5*sin(i*2.0*3.14159/nrays), 0.5+0.5*cos(i*2.0*3.14159/nrays));
            m_vertices[2+i*2+1].texcoord=m_vertices[2+i*2].texcoord;
        }
    }

    // Define triangles
    // The values in this table refer to vertices in the above table
    size_t tiretread_num_indices = 3*2*nrays;
    size_t wheelface_num_indices = 3*2*nrays;
    if (m_is_rimmed) wheelface_num_indices=wheelface_num_indices*3;
    m_wheelface_indices=(unsigned short*)malloc(wheelface_num_indices*sizeof(unsigned short));
    m_tiretread_indices=(unsigned short*)malloc(tiretread_num_indices*sizeof(unsigned short));
    for (i=0; i<nrays; i++)
    {
        //wheel sides
        m_wheelface_indices[3*(i*2)]=0;   m_wheelface_indices[3*(i*2)+1]=2+i*2;     m_wheelface_indices[3*(i*2)+2]=2+((i+1)%nrays)*2;
        m_wheelface_indices[3*(i*2+1)]=1; m_wheelface_indices[3*(i*2+1)+2]=2+i*2+1; m_wheelface_indices[3*(i*2+1)+1]=2+((i+1)%nrays)*2+1;
        if (m_is_rimmed)
        {
            m_wheelface_indices[3*(i*4+0+2*nrays)]=2+i*2;           m_wheelface_indices[3*(i*4+0+2*nrays)+1]=2+4*nrays+i*2;               m_wheelface_indices[3*(i*4+0+2*nrays)+2]=2+((i+1)%nrays)*2;
            m_wheelface_indices[3*(i*4+1+2*nrays)]=2+4*nrays+i*2;   m_wheelface_indices[3*(i*4+1+2*nrays)+1]=2+4*nrays+((i+1)%nrays)*2;   m_wheelface_indices[3*(i*4+1+2*nrays)+2]=2+((i+1)%nrays)*2;
            m_wheelface_indices[3*(i*4+2+2*nrays)]=2+i*2+1;         m_wheelface_indices[3*(i*4+2+2*nrays)+2]=2+4*nrays+i*2+1;             m_wheelface_indices[3*(i*4+2+2*nrays)+1]=2+((i+1)%nrays)*2+1;
            m_wheelface_indices[3*(i*4+3+2*nrays)]=2+4*nrays+i*2+1; m_wheelface_indices[3*(i*4+3+2*nrays)+2]=2+4*nrays+((i+1)%nrays)*2+1; m_wheelface_indices[3*(i*4+3+2*nrays)+1]=2+((i+1)%nrays)*2+1;
        }
        //wheel band
        m_tiretread_indices[3*(i*2)]=2+2*nrays+i*2; m_tiretread_indices[3*(i*2)+1]=2+2*nrays+i*2+1; m_tiretread_indices[3*(i*2)+2]=2+2*nrays+((i+1)%nrays)*2;
        m_tiretread_indices[3*(i*2+1)]=2+2*nrays+((i+1)%nrays)*2; m_tiretread_indices[3*(i*2+1)+2]=2+2*nrays+((i+1)%nrays)*2+1; m_tiretread_indices[3*(i*2+1)+1]=2+2*nrays+i*2+1;
    }

    //update coords
    updateVertices();

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

    // Create declaration (memory format) of vertex data
    m_vertex_format = m_mesh->sharedVertexData->vertexDeclaration;
    size_t offset = 0;
    m_vertex_format->addElement(0, offset, VET_FLOAT3, VES_POSITION);
    offset += VertexElement::getTypeSize(VET_FLOAT3);
    m_vertex_format->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
    offset += VertexElement::getTypeSize(VET_FLOAT3);
//        m_vertex_format->addElement(0, offset, VET_FLOAT3, VES_DIFFUSE);
//        offset += VertexElement::getTypeSize(VET_FLOAT3);
    m_vertex_format->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)
    m_hw_vbuf =
        HardwareBufferManager::getSingleton().createVertexBuffer(
            offset, m_mesh->sharedVertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE);

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

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

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

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

    // Set parameters of the submesh
    m_submesh_wheelface->useSharedVertices = true;
    m_submesh_wheelface->indexData->indexBuffer = faceibuf;
    m_submesh_wheelface->indexData->indexCount = wheelface_num_indices;
    m_submesh_wheelface->indexData->indexStart = 0;

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

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

    // Set parameters of the submesh
    m_submesh_tiretread->useSharedVertices = true;
    m_submesh_tiretread->indexData->indexBuffer = bandibuf;
    m_submesh_tiretread->indexData->indexCount = tiretread_num_indices;
    m_submesh_tiretread->indexData->indexStart = 0;

    // Set bounding information (for culling)
    m_mesh->_setBounds(AxisAlignedBox(-1,-1,0,1,1,0), true);

    m_mesh->load();
}
Exemple #26
0
void createSphere(const std::string& strName, const float r, const int nRings = 16, const int nSegments = 16)
{
	MeshPtr pSphere = MeshManager::getSingleton().createManual(strName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
	SubMesh *pSphereVertex = pSphere->createSubMesh();

	pSphere->sharedVertexData = new VertexData();
	VertexData* vertexData = pSphere->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);
	currOffset += VertexElement::getTypeSize(VET_FLOAT2);

	// allocate the vertex buffer
	vertexData->vertexCount = (nRings + 1) * (nSegments + 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 * nRings * (nSegments + 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 / nRings);
	float fDeltaSegAngle = (2 * Math::PI / nSegments);
	unsigned short wVerticeIndex = 0;

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

		// Generate the group of segments for the current ring
		for (int seg = 0; seg <= nSegments; 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)nSegments;
			*pVertex++ = (float)ring / (float)nRings;

			if (ring != nRings) {
				// each vertex (except the last) has six indices pointing to it
				*pIndices++ = wVerticeIndex + nSegments + 1;
				*pIndices++ = wVerticeIndex;
				*pIndices++ = wVerticeIndex + nSegments;
				*pIndices++ = wVerticeIndex + nSegments + 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:
	pSphere->_setBounds(AxisAlignedBox(Vector3(-r, -r, -r), Vector3(r, r, r)), false);
	pSphere->_setBoundingSphereRadius(r);
	// this line makes clear the mesh is loaded (avoids memory leaks)
	pSphere->load();
}
	//---------------------------------------------------------------------
	void TangentSpaceCalc::insertTangents(Result& res,
		VertexElementSemantic targetSemantic, unsigned short sourceTexCoordSet, 
		unsigned short index)
	{
		// Make a new tangents semantic or find an existing one
		VertexDeclaration *vDecl = mVData->vertexDeclaration ;
		VertexBufferBinding *vBind = mVData->vertexBufferBinding ;

		const VertexElement *tangentsElem = vDecl->findElementBySemantic(targetSemantic, index);
		bool needsToBeCreated = false;
		VertexElementType tangentsType = mStoreParityInW ? VET_FLOAT4 : VET_FLOAT3;

		if (!tangentsElem)
		{ // no tex coords with index 1
			needsToBeCreated = true ;
		}
		else if (tangentsElem->getType() != tangentsType)
		{
			//  buffer exists, but not 3D
			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
				"Target semantic set already exists but is not of the right size, therefore "
				"cannot contain tangents. You should delete this existing entry first. ",
				"TangentSpaceCalc::insertTangents");
		}

		HardwareVertexBufferSharedPtr targetBuffer, origBuffer;
		unsigned char* pSrc = NULL;

		if (needsToBeCreated)
		{
			// To be most efficient with our vertex streams,
			// tack the new tangents onto the same buffer as the
			// source texture coord set
			const VertexElement* prevTexCoordElem =
				mVData->vertexDeclaration->findElementBySemantic(
				VES_TEXTURE_COORDINATES, sourceTexCoordSet);
			if (!prevTexCoordElem)
			{
				OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
					"Cannot locate the first texture coordinate element to "
					"which to append the new tangents.", 
					"Mesh::orgagniseTangentsBuffer");
			}
			// Find the buffer associated with  this element
			origBuffer = mVData->vertexBufferBinding->getBuffer(
				prevTexCoordElem->getSource());
			// Now create a new buffer, which includes the previous contents
			// plus extra space for the 3D coords
			targetBuffer = HardwareBufferManager::getSingleton().createVertexBuffer(
				origBuffer->getVertexSize() + VertexElement::getTypeSize(tangentsType),
				origBuffer->getNumVertices(),
				origBuffer->getUsage(),
				origBuffer->hasShadowBuffer() );
			// Add the new element
			tangentsElem = &(vDecl->addElement(
				prevTexCoordElem->getSource(),
				origBuffer->getVertexSize(),
				tangentsType,
				targetSemantic,
				index));
			// Set up the source pointer
			pSrc = static_cast<unsigned char*>(
				origBuffer->lock(HardwareBuffer::HBL_READ_ONLY));
			// Rebind the new buffer
			vBind->setBinding(prevTexCoordElem->getSource(), targetBuffer);
		}
		else
		{
			// space already there
			origBuffer = mVData->vertexBufferBinding->getBuffer(
				tangentsElem->getSource());
			targetBuffer = origBuffer;
		}


		unsigned char* pDest = static_cast<unsigned char*>(
			targetBuffer->lock(HardwareBuffer::HBL_DISCARD));
		size_t origVertSize = origBuffer->getVertexSize();
		size_t newVertSize = targetBuffer->getVertexSize();
		for (size_t v = 0; v < origBuffer->getNumVertices(); ++v)
		{
			if (needsToBeCreated)
			{
				// Copy original vertex data as well 
				memcpy(pDest, pSrc, origVertSize);
				pSrc += origVertSize;
			}
			// Write in the tangent
			float* pTangent;
			tangentsElem->baseVertexPointerToElement(pDest, &pTangent);
			VertexInfo& vertInfo = mVertexArray[v];
			*pTangent++ = vertInfo.tangent.x;
			*pTangent++ = vertInfo.tangent.y;
			*pTangent++ = vertInfo.tangent.z;
			if (mStoreParityInW)
				*pTangent++ = (float)vertInfo.parity;

			// Next target vertex
			pDest += newVertSize;

		}
		targetBuffer->unlock();

		if (needsToBeCreated)
		{
			origBuffer->unlock();
		}
	}
Exemple #28
0
FlexMeshWheel::FlexMeshWheel(
	Ogre::String const & name,
	node_t *nds, 
	int axis_node_1_index, 
	int axis_node_2_index, 
	int nstart, 
	int nrays, 
	Ogre::String const & mesh_name,
	Ogre::String const & material_name,//char* texband, 
	float rimradius, 
	bool rimreverse, 
	MaterialFunctionMapper *material_function_mapper, // *mfm
	Skin *used_skin, // *usedSkin, 
	MaterialReplacer *material_replacer // *mr
) :
	  id0(axis_node_1_index)
	, id1(axis_node_2_index)
	, idstart(nstart)
	, mr(material_replacer)
	, nbrays(nrays)
	, nodes(nds)
	, revrim(rimreverse)
	, rim_radius(rimradius)
{

	//the rim object
	std::stringstream rim_name;
	rim_name << "rim-" << name;
	rimEnt = gEnv->sceneManager->createEntity(rim_name.str(), mesh_name);
	MaterialFunctionMapper::replaceSimpleMeshMaterials(rimEnt, ColourValue(0, 0.5, 0.8));
	if (material_function_mapper != nullptr)
	{
		material_function_mapper->replaceMeshMaterials(rimEnt);
	}
	if (material_replacer != nullptr)
	{
		material_replacer->replaceMeshMaterials(rimEnt);
	}
	if (used_skin != nullptr)
	{
		used_skin->replaceMeshMaterials(rimEnt);
	}
	rnode=gEnv->sceneManager->getRootSceneNode()->createChildSceneNode();
	rnode->attachObject(rimEnt);

	/// Create the mesh via the MeshManager
	msh = MeshManager::getSingleton().createManual(name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,new ResourceBuffer());

	/// Create submeshes
	sub = msh->createSubMesh();

	//materials
	sub->setMaterialName(material_name);

	/// Define the vertices
	nVertices = 6*(nrays+1);
	vbufCount = (2*3+2)*nVertices;
	vertices=(float*)malloc(vbufCount*sizeof(float));
	//shadow
	shadownorvertices=(float*)malloc(nVertices*(3+2)*sizeof(float));
	shadowposvertices=(float*)malloc(nVertices*3*2*sizeof(float));

	int i;
	//textures coordinates
	for (i=0; i<nrays+1; i++)
	{
		covertices[i*6   ].texcoord=Vector2((float)i/(float)nrays, 0.00f);
		covertices[i*6+1 ].texcoord=Vector2((float)i/(float)nrays, 0.23f);
		covertices[i*6+2 ].texcoord=Vector2((float)i/(float)nrays, 0.27f);
		covertices[i*6+3 ].texcoord=Vector2((float)i/(float)nrays, 0.73f);
		covertices[i*6+4 ].texcoord=Vector2((float)i/(float)nrays, 0.77f);
		covertices[i*6+5 ].texcoord=Vector2((float)i/(float)nrays, 1.00f);
	}

	/// Define triangles
	/// The values in this table refer to vertices in the above table
	ibufCount = 3*10*nrays;
	faces=(unsigned short*)malloc(ibufCount*sizeof(unsigned short));
	for (i=0; i<nrays; i++)
	{
		faces[3*(i*10  )]=i*6;   faces[3*(i*10  )+1]=i*6+1;     faces[3*(i*10  )+2]=(i+1)*6;
		faces[3*(i*10+1)]=i*6+1; faces[3*(i*10+1)+1]=(i+1)*6+1; faces[3*(i*10+1)+2]=(i+1)*6;

		faces[3*(i*10+2)]=i*6+1; faces[3*(i*10+2)+1]=i*6+2;     faces[3*(i*10+2)+2]=(i+1)*6+1;
		faces[3*(i*10+3)]=i*6+2; faces[3*(i*10+3)+1]=(i+1)*6+2; faces[3*(i*10+3)+2]=(i+1)*6+1;

		faces[3*(i*10+4)]=i*6+2; faces[3*(i*10+4)+1]=i*6+3;     faces[3*(i*10+4)+2]=(i+1)*6+2;
		faces[3*(i*10+5)]=i*6+3; faces[3*(i*10+5)+1]=(i+1)*6+3; faces[3*(i*10+5)+2]=(i+1)*6+2;

		faces[3*(i*10+6)]=i*6+3; faces[3*(i*10+6)+1]=i*6+4;     faces[3*(i*10+6)+2]=(i+1)*6+3;
		faces[3*(i*10+7)]=i*6+4; faces[3*(i*10+7)+1]=(i+1)*6+4; faces[3*(i*10+7)+2]=(i+1)*6+3;

		faces[3*(i*10+8)]=i*6+4; faces[3*(i*10+8)+1]=i*6+5;     faces[3*(i*10+8)+2]=(i+1)*6+4;
		faces[3*(i*10+9)]=i*6+5; faces[3*(i*10+9)+1]=(i+1)*6+5; faces[3*(i*10+9)+2]=(i+1)*6+4;
	}

	normy=1.0;
	//update coords
	updateVertices();
	//compute normy;
	normy=((covertices[0].vertex-covertices[1].vertex).crossProduct(covertices[1].vertex-covertices[6+1].vertex)).length();
	//recompute for normals
	updateVertices();

	/// 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
	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)
	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);

	//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(), faces, true);

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


	/// Set bounding information (for culling)
	msh->_setBounds(AxisAlignedBox(-1,-1,0,1,1,0), true);
	//msh->_setBoundingSphereRadius(Math::Sqrt(1*1+1*1));

	/// Notify Mesh object that it has been loaded
	//msh->buildTangentVectors();
	/*unsigned short src, dest;
	if (!msh->suggestTangentVectorBuildParams(src, dest))
	{
		msh->buildTangentVectors(src, dest);
	}
	*/

	msh->load();
	//msh->touch();
	//        msh->load();

			//msh->buildEdgeList();
}
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;
}
	//---------------------------------------------------------------------
	void TangentSpaceCalc::extendBuffers(VertexSplits& vertexSplits)
	{
		if (!vertexSplits.empty())
		{
			// ok, need to increase the vertex buffer size, and alter some indexes

			// vertex buffers first
			VertexBufferBinding* newBindings = HardwareBufferManager::getSingleton().createVertexBufferBinding();
			const VertexBufferBinding::VertexBufferBindingMap& bindmap = 
				mVData->vertexBufferBinding->getBindings();
			for (VertexBufferBinding::VertexBufferBindingMap::const_iterator i = 
				bindmap.begin(); i != bindmap.end(); ++i)
			{
				HardwareVertexBufferSharedPtr srcbuf = i->second;
				// Derive vertex count from buffer not vertex data, in case using
				// the vertexStart option in vertex data
				size_t newVertexCount = srcbuf->getNumVertices() + vertexSplits.size();
				// Create new buffer & bind
				HardwareVertexBufferSharedPtr newBuf = 
					HardwareBufferManager::getSingleton().createVertexBuffer(
					srcbuf->getVertexSize(), newVertexCount, srcbuf->getUsage(), 
					srcbuf->hasShadowBuffer());
				newBindings->setBinding(i->first, newBuf);

				// Copy existing contents (again, entire buffer, not just elements referenced)
				newBuf->copyData(*(srcbuf.get()), 0, 0, srcbuf->getNumVertices() * srcbuf->getVertexSize(), true);

				// Split vertices, read / write from new buffer
				char* pBase = static_cast<char*>(newBuf->lock(HardwareBuffer::HBL_NORMAL));
				for (VertexSplits::iterator spliti = vertexSplits.begin(); 
					spliti != vertexSplits.end(); ++spliti)
				{
					const char* pSrcBase = pBase + spliti->first * newBuf->getVertexSize();
					char* pDstBase = pBase + spliti->second * newBuf->getVertexSize();
					memcpy(pDstBase, pSrcBase, newBuf->getVertexSize());
				}
				newBuf->unlock();

			}

			// Update vertex data
			// Increase vertex count according to num splits
			mVData->vertexCount += vertexSplits.size();
			// Flip bindings over to new buffers (old buffers released)
			HardwareBufferManager::getSingleton().destroyVertexBufferBinding(mVData->vertexBufferBinding);
			mVData->vertexBufferBinding = newBindings;

			// If vertex size requires 32bit index buffer
			if (mVData->vertexCount > 65536)
			{
				for (size_t i = 0; i < mIDataList.size(); ++i)
				{
					// check index size
					IndexData* idata = mIDataList[i];
					HardwareIndexBufferSharedPtr srcbuf = idata->indexBuffer;
					if (srcbuf->getType() == HardwareIndexBuffer::IT_16BIT)
					{
						size_t indexCount = srcbuf->getNumIndexes();

						// convert index buffer to 32bit.
						HardwareIndexBufferSharedPtr newBuf =
							HardwareBufferManager::getSingleton().createIndexBuffer(
							HardwareIndexBuffer::IT_32BIT, indexCount,
							srcbuf->getUsage(), srcbuf->hasShadowBuffer());

						uint16* pSrcBase = static_cast<uint16*>(srcbuf->lock(HardwareBuffer::HBL_NORMAL));
						uint32* pBase = static_cast<uint32*>(newBuf->lock(HardwareBuffer::HBL_NORMAL));

						size_t j = 0;
						while (j < indexCount)
						{
							*pBase++ = *pSrcBase++;
							++j;
						}

						srcbuf->unlock();
						newBuf->unlock();

						// assign new index buffer.
						idata->indexBuffer = newBuf;
					}
				}
			}
		}

	}