Пример #1
0
	// 创建定点缓冲区
	void CCustomShape::CreateAreaVertexBuffer()
	{
		
		if(0 == m_planePointArray.size())
		{
			return;
		}

        // 先把上次创建的缓冲区删掉
        ClearVertexBuffer();

        mRenderOp.vertexData = new Ogre::VertexData;

        mRenderOp.vertexData->vertexCount = m_planePointArray.size();
        mRenderOp.vertexData->vertexStart = 0;
      
		Ogre::VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration;

		// 声明定点格式
        size_t offset = 0;
      	decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
        offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
        decl->addElement(0, offset, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);

	     m_vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
            decl->getVertexSize(0),
            mRenderOp.vertexData->vertexCount,
            Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);

         mRenderOp.vertexData->vertexBufferBinding->setBinding(0, m_vbuf);
	}
void LIRenImageOverlay::initialise ()
{
	if (mInitialised)
		return;
	mInitialised = true;

	/* Initialize the render operation. */
	render_op.vertexData = new Ogre::VertexData ();
	render_op.vertexData->vertexStart = 0;
	render_op.vertexData->vertexCount = 0;

	/* Setup the vertex format. */
	size_t offset = 0;
	Ogre::VertexDeclaration* format = render_op.vertexData->vertexDeclaration;
	format->addElement (0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
	offset += Ogre::VertexElement::getTypeSize (Ogre::VET_FLOAT3);
	format->addElement (0, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES);
	offset += Ogre::VertexElement::getTypeSize (Ogre::VET_FLOAT2);
	format->addElement (0, offset, Ogre::VET_COLOUR_ABGR, Ogre::VES_DIFFUSE);
	offset += Ogre::VertexElement::getTypeSize (Ogre::VET_COLOUR_ABGR);
	lisys_assert (offset == VERTEX_SIZE);

	/* Create the vertex buffer. */
	vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer (
		offset, VERTEX_COUNT_INIT, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);

	/* Bind the vertex buffer. */
	render_op.vertexData->vertexBufferBinding->setBinding (0, vbuf);
	render_op.useIndexes = false;
	render_op.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
}
Пример #3
0
void OgreImGui::ImGUIRenderable::initImGUIRenderable(void)
{
    // use identity projection and view matrices
    mUseIdentityProjection  = true;
    mUseIdentityView        = true;

    mRenderOp.vertexData = OGRE_NEW Ogre::VertexData();
    mRenderOp.indexData  = OGRE_NEW Ogre::IndexData();

    mRenderOp.vertexData->vertexCount = 0;
    mRenderOp.vertexData->vertexStart = 0;

    mRenderOp.indexData->indexCount = 0;
    mRenderOp.indexData->indexStart = 0;
    mRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
    mRenderOp.useIndexes  = true; 
    mRenderOp.useGlobalInstancingVertexBufferIsAvailable = false;

    Ogre::VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
        
    // vertex declaration
    size_t offset = 0;
    decl->addElement(0,offset,Ogre::VET_FLOAT2,Ogre::VES_POSITION);
    offset += Ogre::VertexElement::getTypeSize( Ogre::VET_FLOAT2 );
    decl->addElement(0,offset,Ogre::VET_FLOAT2,Ogre::VES_TEXTURE_COORDINATES,0);
    offset += Ogre::VertexElement::getTypeSize( Ogre::VET_FLOAT2 );
    decl->addElement(0,offset,Ogre::VET_COLOUR,Ogre::VES_DIFFUSE);

        
        // set basic white material
    this->setMaterial( "imgui/material" );
}
Пример #4
0
        Line3D::Line3D()
        {
            mRenderOp.vertexData = new Ogre::VertexData();
            this->SelfNode = Entresol::GetSingletonPtr()->GetSceneManager()->GetGraphicsWorldPointer()->getRootSceneNode()->createChildSceneNode();

            // Initialization stuff
            mRenderOp.indexData = 0;
            mRenderOp.vertexData->vertexCount = 1024;
            mRenderOp.vertexData->vertexStart = 0;
            mRenderOp.operationType = Ogre::RenderOperation::OT_LINE_LIST;
            mRenderOp.useIndexes = false;

            Ogre::VertexDeclaration* VDecl = mRenderOp.vertexData->vertexDeclaration;
            Ogre::VertexBufferBinding* VBind = mRenderOp.vertexData->vertexBufferBinding;

            size_t Offset = 0;
            // Position.
            VDecl->addElement(0,0,Ogre::VET_FLOAT3,Ogre::VES_POSITION);
            Offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);

            // Colour
            VDecl->addElement(0,Offset,Ogre::VET_FLOAT4,Ogre::VES_DIFFUSE);
            Offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT4);

            this->VertexBuffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
                    VDecl->getVertexSize(0),
                    mRenderOp.vertexData->vertexCount,
                    Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE,
                    false);

            VBind->setBinding(0,this->VertexBuffer);

            this->setMaterial("BaseWhiteNoLighting");
        }
Пример #5
0
    void
    IntersectGrid::_createBuffer()
    {
        // 先把上次创建的缓冲区删掉
        if ( mRenderOp.vertexData )
        {
            delete mRenderOp.vertexData;
            mRenderOp.vertexData = 0;
        }

        if ( mCurrentVertexCount <= 0 )
            return;

        mRenderOp.vertexData = new Ogre::VertexData;

        mRenderOp.vertexData->vertexCount = mCurrentVertexCount;
        mRenderOp.vertexData->vertexStart = 0;
        Ogre::VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration;

        size_t offset = 0;

        decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);

        offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
        decl->addElement(0, offset, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);
        
        vbuf = 
            Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
            decl->getVertexSize(0),
            mRenderOp.vertexData->vertexCount,
            Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);

        mRenderOp.vertexData->vertexBufferBinding->setBinding(0, vbuf);
    }
Пример #6
0
   AxisRenderable::AxisRenderable(int lineCount,Ogre::Camera* camera,Ogre::Viewport* viewport) 
   {
        // Disable cast shadows by default
        mCastShadows = false;

      mPrevAxisGizmoSelAxis = -1;
      mCamera = camera;
      mViewport = viewport;

      m_max_line_count = m_line_count  = lineCount;
      m_line_count = 0;

      mLength = 200;
      mProjectDistance = mCamera->getFarClipDistance();
      m_local = false;
      m_locked_data = 0;
      //m_locked_buffer = 0;
      mRenderOp.vertexData = new Ogre::VertexData();
      m_radius = 0;

      mRenderOp.indexData = 0;
      mRenderOp.vertexData->vertexCount = m_line_count*2;
      mRenderOp.vertexData->vertexStart = 0;

      mRenderOp.operationType = Ogre::RenderOperation::OT_LINE_LIST; 
      mRenderOp.useIndexes = false; 

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

      decl->addElement(0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
      decl->addElement(0, 3*sizeof(Ogre::Real), Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);

      Ogre::HardwareVertexBufferSharedPtr vbuf = 
         Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
         decl->getVertexSize(0),
         2*m_max_line_count,
         Ogre::HardwareBuffer::HBU_WRITE_ONLY);

      bind->setBinding(0, vbuf);

      // Obtain the pure colour material
      Ogre::MaterialPtr pureColourMaterial = createPureColourMaterial(Ogre::ColourValue(1,1,0));

      Ogre::String realName = pureColourMaterial->getName() + "_NoDepthBuffer";
      Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().getByName(realName);
      if (material.isNull())
      {
          // Clone to avoid confuse somewhere else that using the same material
          material = pureColourMaterial->clone(realName);
          material->setDepthCheckEnabled(false);
          material->setDepthWriteEnabled(false);
      }

      setMaterial(material->getName());

      mBox.setExtents(-10,-10,-10,10,10,10);
      setQueryFlags(0);
   }
Пример #7
0
void Canvas::resizeBuffers()
{
	if(bufferSize < quadList.size())
	{
		bufferSize = quadList.size() * 2;
		destroyBuffers();
	}

	if(!vertexData)
	{
		vertexData = new Ogre::VertexData();
		vertexData->vertexStart = 0;
		vertexData->vertexCount = bufferSize * 4;

		Ogre::VertexDeclaration* decl = vertexData->vertexDeclaration;
		Ogre::VertexBufferBinding* binding = vertexData->vertexBufferBinding;

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

		buffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
			decl->getVertexSize(0), vertexData->vertexCount, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
		binding->setBinding(0, buffer);
	}

	if(!indexData)
	{
		indexData = new Ogre::IndexData();
		indexData->indexStart = 0;
		indexData->indexCount = bufferSize * 6;

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

		unsigned short* indexBuffer = (unsigned short*)indexData->indexBuffer->lock(0, indexData->indexBuffer->getSizeInBytes(), Ogre::HardwareBuffer::HBL_DISCARD);

		// Indexes are generated here because we know that we will only be rendering quads
		// This means that we only have to handle updating the vertex buffer in Canvas::updateGeometry
		for(size_t indexIdx, vertexIdx, quadIdx = 0; quadIdx < bufferSize; quadIdx++)
		{
			indexIdx = quadIdx * 6;
			vertexIdx = quadIdx * 4;

			indexBuffer[indexIdx++] = (unsigned short)(vertexIdx + 0);
			indexBuffer[indexIdx++] = (unsigned short)(vertexIdx + 2);
			indexBuffer[indexIdx++] = (unsigned short)(vertexIdx + 1);
			indexBuffer[indexIdx++] = (unsigned short)(vertexIdx + 1);
			indexBuffer[indexIdx++] = (unsigned short)(vertexIdx + 2);
			indexBuffer[indexIdx++] = (unsigned short)(vertexIdx + 3);
		}

		indexData->indexBuffer->unlock();
	}
}
Пример #8
0
void CDynamicLineDrawer::CreateVertexDeclaration()
{
	// Points
	Ogre::VertexDeclaration *Decl = mRenderOp.vertexData->vertexDeclaration;
	Decl->addElement(POSITION_BINDING, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);

	// Colour
	Decl->addElement(COLOUR_BINDING, 0, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);
}
void NxTriangles::createVertexDeclaration()
{
	Ogre::VertexDeclaration* vdecl =  mRenderOp.vertexData-> vertexDeclaration;
	vdecl->addElement(0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
	vdecl->addElement(1, 0, Ogre::VET_FLOAT3, Ogre::VES_NORMAL);
	if(mUseVertexColour) {
		vdecl->addElement( 2, 0, VET_COLOUR, VES_DIFFUSE );
	}
	else {
	 
		vdecl->addElement( 2, 0, mUVW ? VET_FLOAT3 : VET_FLOAT2, VES_TEXTURE_COORDINATES );
	}
	 
}
Пример #10
0
    Selection2D::Selection2D(bool includeTextureCoords) 
    {
        // use identity projection and view matrices
        mUseIdentityProjection = true;
        mUseIdentityView = true;

        mRenderOp.vertexData = OGRE_NEW Ogre::VertexData();
        mRenderOp.indexData = 0;
        mRenderOp.vertexData->vertexCount = 5;
        mRenderOp.vertexData->vertexStart = 0;
        mRenderOp.operationType = Ogre::RenderOperation::OT_LINE_STRIP;
        mRenderOp.useIndexes = false;
        Ogre::VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
        Ogre::VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;
        decl->addElement(0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
        Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
            decl->getVertexSize(0), mRenderOp.vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
        // Bind buffer
        bind->setBinding(0, vbuf);

        this->setCastShadows(false);
        this->setQueryFlags(0); // set a query flag to exlude from queries (if necessary).

        // set basic white material
        this->setMaterial("BaseWhiteNoLighting");
    }
PortalOutlineRenderable::PortalOutlineRenderable(Ogre::String matname, Ogre::ColourValue colour)
{

	mRenderOp.vertexData = OGRE_NEW Ogre::VertexData();
	mRenderOp.indexData = 0;
	mRenderOp.vertexData->vertexCount = 10;//8
	mRenderOp.vertexData->vertexStart = 0;
	mRenderOp.operationType = Ogre::RenderOperation::OT_LINE_LIST;
	mRenderOp.useIndexes = false;
	Ogre::VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
	Ogre::VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;
	decl->addElement(0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
	Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
		decl->getVertexSize(0), mRenderOp.vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
	// Bind buffer
	bind->setBinding(0, vbuf);
	// setup material
	createPortalMaterials();
	//Ogre::ResourceManager::ResourceCreateOrRetrieveResult result = Ogre::MaterialManager::getSingleton().createOrRetrieve(matname, "General");
	//if(result.second)
	//{
	//	Ogre::MaterialPtr matptrOBBoxManualMaterial = result.first;
	//    matptrOBBoxManualMaterial->setReceiveShadows(false);
	//    matptrOBBoxManualMaterial->getTechnique(0)->setLightingEnabled(true);
	//    matptrOBBoxManualMaterial->getTechnique(0)->getPass(0)->setDiffuse(colour);
	//    matptrOBBoxManualMaterial->getTechnique(0)->getPass(0)->setAmbient(colour);
	//    matptrOBBoxManualMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(colour);
	//}


    this->setCastShadows(false);
    this->setQueryFlags(0); // set a query flag to exlude from queries (if necessary).
	this->setMaterial("PortalOutlineMaterial");
}
Пример #12
0
void DebugLines::draw()
{
   if(_drawn) return;
   else _drawn = true;

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

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

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

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

   bind->setBinding(0, vbuf);

   // Drawing stuff
   size_t size = _points.size();
   Vector3 vaabMin = _points[0];
   Vector3 vaabMax = _points[0];

   Real *prPos = static_cast<Real*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));

   for(size_t i = 0; i < size; i++)
   {
      *prPos++ = _points[i].x;
      *prPos++ = _points[i].y;
      *prPos++ = _points[i].z;

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

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

   vbuf->unlock();

   mBox.setExtents(vaabMin, vaabMax);
}
Пример #13
0
void ESKOgre::createFakeEntity(Ogre::SceneManager *mSceneMgr) {
	Ogre::MeshPtr msh = Ogre::MeshManager::getSingleton().createManual(name + "_skeleton", XENOVIEWER_RESOURCE_GROUP);
	msh->setSkeletonName(name);

	Ogre::SubMesh* sub = msh->createSubMesh();
	const size_t nVertices = 3;
	const size_t nVertCount = 3;
	const size_t vbufCount = nVertCount*nVertices;
	float *vertices = (float *)malloc(sizeof(float)*vbufCount);

	for (size_t i = 0; i < nVertices; i++) {
		vertices[i*nVertCount] = 0.0;
		vertices[i*nVertCount + 1] = 0.0;
		vertices[i*nVertCount + 2] = 0.0;
	}

	const size_t ibufCount = 3;
	unsigned short *faces = (unsigned short *)malloc(sizeof(unsigned short) * ibufCount);

	for (size_t i = 0; i < ibufCount; i++) {
		faces[i] = i;
	}

	msh->sharedVertexData = new Ogre::VertexData();
	msh->sharedVertexData->vertexCount = nVertices;

	Ogre::VertexDeclaration* decl = msh->sharedVertexData->vertexDeclaration;
	size_t offset = 0;

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

	Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(offset, msh->sharedVertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
	vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);
	Ogre::VertexBufferBinding* bind = msh->sharedVertexData->vertexBufferBinding;
	bind->setBinding(0, vbuf);
	Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(Ogre::HardwareIndexBuffer::IT_16BIT, ibufCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
	ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true);
	sub->useSharedVertices = true;
	sub->indexData->indexBuffer = ibuf;
	sub->indexData->indexCount = ibufCount;
	sub->indexData->indexStart = 0;

	msh->_setBounds(Ogre::AxisAlignedBox(-100, -100, -100, 100, 100, 100));
	msh->_setBoundingSphereRadius(100);
	msh->load();

	free(faces);
	free(vertices);

	skeleton_entity = mSceneMgr->createEntity(name + "_skeleton");
	skeleton_node = mSceneMgr->getRootSceneNode()->createChildSceneNode();
	skeleton_node->attachObject(skeleton_entity);
	skeleton_node->setVisible(false);
}
Пример #14
0
    void
        TerrainGridRenderable::initTerrainGrid(int vertexCount)
    {
        m_locked_data = 0;

        mRenderOp.vertexData = new Ogre::VertexData();
        mRenderOp.indexData = 0;

        mRenderOp.vertexData->vertexCount = mVertexCount;
        mRenderOp.vertexData->vertexStart = 0;

        mRenderOp.operationType = Ogre::RenderOperation::OT_LINE_LIST; 
        mRenderOp.useIndexes = false; 

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

        decl->addElement(0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
        decl->addElement(0, 3*sizeof(Ogre::Real), Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);

        Ogre::HardwareVertexBufferSharedPtr vbuf = 
            Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
            decl->getVertexSize(0),
            vertexCount,
            Ogre::HardwareBuffer::HBU_WRITE_ONLY);

        bind->setBinding(0, vbuf);

        // set basic white material
        this->setMaterial("BaseWhiteNoLighting");
        mBox.setExtents(-10,-10,-10,10,10,10);

        lock();
        drawGridLines();
        unlock();
        
	//	getMaterial()->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
        setQueryFlags(0);
    }
Пример #15
0
    void DynamicLines::createVertexDeclaration()
    {
        // we define the meaning of each batch of vertices added to the buffer
        //http://grahamedgecombe.com/blog/custom-meshes-in-ogre3d
        Ogre::VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration;
        size_t offset = 0;

        decl->addElement(POSITION_BINDING, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
        offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
        // dynamic renderable only has 1 buffer
//         decl->addElement(POSITION_BINDING, offset, Ogre::VET_FLOAT4, Ogre::VES_POSITION);
//         offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT4);
    }
Пример #16
0
//----------------------------------------------------------------------------//
void OgreGeometryBuffer::finaliseVertexAttributes(MANUALOBJECT_TYPE type)
{
    d_expectedData = type;

    // basic initialisation of render op
    d_renderOp.vertexData = OGRE_NEW Ogre::VertexData();
    d_renderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
    d_renderOp.useIndexes = false;

    // Setup our render operation to match the type
    Ogre::VertexDeclaration* vd = d_renderOp.vertexData->vertexDeclaration;

    switch(d_expectedData)
    {
    case MT_COLOURED: 
    {
        vd->addElement(0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);

        vd->addElement(0, sizeof(float)*3, Ogre::VET_COLOUR, 
            Ogre::VES_DIFFUSE);
        break;
    }
    case MT_TEXTURED: 
    {
        vd->addElement(0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);

        vd->addElement(0, sizeof(float)*3, Ogre::VET_FLOAT4, 
            Ogre::VES_DIFFUSE);

        vd->addElement(0, sizeof(float)*(3+4), Ogre::VET_FLOAT2, 
            Ogre::VES_TEXTURE_COORDINATES);
        break;
    }
    default:
        throw RendererException(
            "Unknown d_expectedData type.");
    }

}
Пример #17
0
void gkDebugger::growBuffer(UTsize newSize)
{
	// expand vertex buffer size
	if (newSize <= m_bufSize)
		return;

	if (mRenderOp.vertexData)
	{
		delete mRenderOp.vertexData;
		mRenderOp.vertexData = 0;
		m_buffer.setNull();
	}

	m_bufSize = newSize;

	mRenderOp.vertexData = new Ogre::VertexData();
	Ogre::VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;

	size_t offs = 0;
	decl->addElement(0, offs, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
	offs += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
	decl->addElement(0, offs, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);
	offs += Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR_ABGR);


	mRenderOp.vertexData->vertexStart = 0;
	mRenderOp.vertexData->vertexCount = m_bufSize;
	mRenderOp.operationType = Ogre::RenderOperation::OT_LINE_LIST;

	m_buffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
	               offs, mRenderOp.vertexData->vertexCount,
	               Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, false);


	mRenderOp.vertexData->vertexBufferBinding->setBinding(0, m_buffer);
	mRenderOp.useIndexes = false;
	mRenderOp.indexData = 0;
}
Пример #18
0
	void VertexBuffer::createVertexBuffer()
	{
		mRenderOperation.vertexData = new Ogre::VertexData();
		mRenderOperation.vertexData->vertexStart = 0;

		Ogre::VertexDeclaration* vd = mRenderOperation.vertexData->vertexDeclaration;
		vd->addElement( 0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION );
		vd->addElement( 0, Ogre::VertexElement::getTypeSize( Ogre::VET_FLOAT3 ), Ogre::VET_COLOUR, Ogre::VES_DIFFUSE );
		vd->addElement( 0, Ogre::VertexElement::getTypeSize( Ogre::VET_FLOAT3 ) +
			Ogre::VertexElement::getTypeSize( Ogre::VET_COLOUR ),
			Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES );

		// Create the Vertex Buffer, using the Vertex Structure we previously declared in _declareVertexStructure.
		mVertexBuffer = Ogre::HardwareBufferManager::getSingleton( ).createVertexBuffer(
			mRenderOperation.vertexData->vertexDeclaration->getVertexSize(0), // declared Vertex used
			mVertexCount,
			Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE,
			false );

		// Bind the created buffer to the renderOperation object.  Now we can manipulate the buffer, and the RenderOp keeps the changes.
		mRenderOperation.vertexData->vertexBufferBinding->setBinding( 0, mVertexBuffer );
		mRenderOperation.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
		mRenderOperation.useIndexes = false;
	}
Пример #19
0
void Ogre2dManager::createHardwareBuffer(unsigned int size)
{
   Ogre::VertexDeclaration* vd;
 
   renderOp.vertexData=new Ogre::VertexData;
   renderOp.vertexData->vertexStart=0;
 
   vd=renderOp.vertexData->vertexDeclaration;
   vd->addElement(0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
   vd->addElement(0, Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3),
      Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES);
 
   hardwareBuffer=Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
      vd->getVertexSize(0),
      size,// buffer size
      Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE,
      false);// use shadow buffer? no
 
   renderOp.vertexData->vertexBufferBinding->setBinding(0, hardwareBuffer);
 
   renderOp.operationType=Ogre::RenderOperation::OT_TRIANGLE_LIST;
   renderOp.useIndexes=false;
 
}
Пример #20
0
    BufferType*
    ManualObject::createBuffer( const BufferBinding binding
                               ,Ogre::VertexElementType type
                               ,Ogre::VertexElementSemantic semantic )
    {
        Ogre::VertexDeclaration* decl = m_section->vertexData->vertexDeclaration;
        Ogre::VertexBufferBinding* bind = m_section->vertexData->vertexBufferBinding;

        decl->addElement( binding, 0, type, semantic );
        size_t vertex_size( decl->getVertexSize( binding ) );

        VertexBuffer buffer = Ogre::HardwareBufferManager::getSingleton()
            .createVertexBuffer( vertex_size
                                ,m_section->vertexData->vertexCount
                                ,Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
        bind->setBinding( binding, buffer );
        m_vertex_buffers[binding] = buffer;
        return static_cast<BufferType*>( buffer->lock( Ogre::HardwareBuffer::HBL_DISCARD ) );
    }
Пример #21
0
//------------------------------------------------------------------------------
void
Background2D::CreateVertexBuffers()
{
    m_AlphaMaxVertexCount = 2048 * TILE_VERTEX_COUNT;
    m_AlphaRenderOp.vertexData = new Ogre::VertexData;
    m_AlphaRenderOp.vertexData->vertexStart = 0;

    Ogre::VertexDeclaration* vDecl = m_AlphaRenderOp.vertexData->vertexDeclaration;

    size_t offset = 0;
    vDecl->addElement( 0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION );
    offset += Ogre::VertexElement::getTypeSize( Ogre::VET_FLOAT3 );
    vDecl->addElement( 0, offset, Ogre::VET_FLOAT4, Ogre::VES_DIFFUSE );
    offset += Ogre::VertexElement::getTypeSize( Ogre::VET_FLOAT4 );
    vDecl->addElement( 0, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES );

    m_AlphaVertexBuffer = Ogre::HardwareBufferManager::getSingletonPtr()->createVertexBuffer( vDecl->getVertexSize( 0 ), m_AlphaMaxVertexCount, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY, false );

    m_AlphaRenderOp.vertexData->vertexBufferBinding->setBinding( 0, m_AlphaVertexBuffer );
    m_AlphaRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
    m_AlphaRenderOp.useIndexes = false;



    m_AddMaxVertexCount = 256 * TILE_VERTEX_COUNT;
    m_AddRenderOp.vertexData = new Ogre::VertexData;
    m_AddRenderOp.vertexData->vertexStart = 0;

    vDecl = m_AddRenderOp.vertexData->vertexDeclaration;

    offset = 0;
    vDecl->addElement( 0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION );
    offset += Ogre::VertexElement::getTypeSize( Ogre::VET_FLOAT3 );
    vDecl->addElement( 0, offset, Ogre::VET_FLOAT4, Ogre::VES_DIFFUSE );
    offset += Ogre::VertexElement::getTypeSize( Ogre::VET_FLOAT4 );
    vDecl->addElement( 0, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES );

    m_AddVertexBuffer = Ogre::HardwareBufferManager::getSingletonPtr()->createVertexBuffer( vDecl->getVertexSize( 0 ), m_AddMaxVertexCount, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY, false );

    m_AddRenderOp.vertexData->vertexBufferBinding->setBinding( 0, m_AddVertexBuffer );
    m_AddRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
    m_AddRenderOp.useIndexes = false;
}
Пример #22
0
void
MeshExtractor( const MeshData& mesh_data, const Ogre::String& material_name, File* file, int offset_to_data, VectorTexForGen& textures, const Ogre::MeshPtr& mesh )
{
    File* file12 = new File( "./data/field/5/1b/1/12/1" );
    u32 offset_to_clut_tex = 4 + file12->GetU32LE( 4 + 4 ) & 0x00ffffff;
    LOGGER->Log( "offset_to_clut_tex = \"" + HexToString( offset_to_clut_tex, 8, '0' ) + "\".\n" );
    u32 offset_to_tx_ty = offset_to_clut_tex + file12->GetU8( 4 + 7 ) * 4;
    LOGGER->Log( "offset_to_tx_ty = \"" + HexToString( offset_to_tx_ty, 8, '0' ) + "\".\n" );



    int number_of_monochrome_textured_quads = file->GetU16LE( offset_to_data + 0x02 );
    int number_of_monochrome_textured_triangles = file->GetU16LE( offset_to_data + 0x04 );
    int number_of_shaded_textured_quads = file->GetU16LE( offset_to_data + 0x06 );
    int number_of_shaded_textured_triangles = file->GetU16LE( offset_to_data + 0x08 );
    int number_of_gradated_quads = file->GetU16LE( offset_to_data + 0x0a );
    int number_of_gradated_triangles = file->GetU16LE( offset_to_data + 0x0c );
    int number_of_monochrome_quads = file->GetU16LE( offset_to_data + 0x0e );
    int number_of_monochrome_triangles = file->GetU16LE( offset_to_data + 0x10 );

    u32 pointer_to_vertex_groups = file->GetU32LE( offset_to_data + 0x14 );
    u32 pointer_to_vertex_data = file->GetU32LE( offset_to_data + 0x18 );
    u32 pointer_to_mesh_data = file->GetU32LE( offset_to_data + 0x1c );
    u32 pointer_to_texture_data = file->GetU32LE( offset_to_data + 0x20 );



    Ogre::SubMesh* sub_mesh = mesh->createSubMesh(/* name */);
    sub_mesh->setMaterialName( material_name );
    sub_mesh->useSharedVertices = false;
    sub_mesh->operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;

    // Allocate and prepare vertex data
    sub_mesh->vertexData = new Ogre::VertexData();
    sub_mesh->vertexData->vertexStart = 0;
    sub_mesh->vertexData->vertexCount = static_cast< size_t >(
        number_of_monochrome_textured_quads * 6 +
        number_of_monochrome_textured_triangles * 3/* +
        number_of_shaded_textured_quads * 6 +
        number_of_shaded_textured_triangles * 3 +
        number_of_gradated_quads * 6 +
        number_of_gradated_triangles * 3 +
        number_of_monochrome_quads * 6 +
        number_of_monochrome_triangles * 3*/ );

    sub_mesh->indexData = new Ogre::IndexData();
    sub_mesh->indexData->indexStart = 0;
    sub_mesh->indexData->indexCount = sub_mesh->vertexData->vertexCount;
    sub_mesh->indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
        Ogre::HardwareIndexBuffer::IT_16BIT,
        sub_mesh->indexData->indexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    u16* idata = static_cast< u16* >( sub_mesh->indexData->indexBuffer->lock( Ogre::HardwareBuffer::HBL_DISCARD ) );
    u32 cur_index = 0;

    Ogre::VertexDeclaration* decl = sub_mesh->vertexData->vertexDeclaration;
    Ogre::VertexBufferBinding* bind = sub_mesh->vertexData->vertexBufferBinding;
    // 1st buffer
    decl->addElement( POSITION_BINDING, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION );
    Ogre::HardwareVertexBufferSharedPtr vbuf0 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
        decl->getVertexSize( POSITION_BINDING ),
        sub_mesh->vertexData->vertexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    bind->setBinding( POSITION_BINDING, vbuf0 );

    // 2nd buffer
    decl->addElement( COLOUR_BINDING, 0, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE );
    Ogre::HardwareVertexBufferSharedPtr vbuf1 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
        decl->getVertexSize( COLOUR_BINDING ),
        sub_mesh->vertexData->vertexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    // Set vertex buffer binding so buffer 1 is bound to our colour buffer
    bind->setBinding( COLOUR_BINDING, vbuf1 );

    // 3rd buffer
    decl->addElement( TEXTURE_BINDING, 0, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0 );
    Ogre::HardwareVertexBufferSharedPtr vbuf2 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
        decl->getVertexSize( TEXTURE_BINDING ),
        sub_mesh->vertexData->vertexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    bind->setBinding( TEXTURE_BINDING, vbuf2 );

    float* pPos   = static_cast< float* >( vbuf0->lock( Ogre::HardwareBuffer::HBL_DISCARD ) );
    float* tPos   = static_cast< float* >( vbuf2->lock( Ogre::HardwareBuffer::HBL_DISCARD ) );

    Ogre::RenderSystem* rs = Ogre::Root::getSingleton().getRenderSystem();
    
    std::vector<Ogre::RGBA> coloursVec(sub_mesh->vertexData->vertexCount);

    Ogre::RGBA* colours = coloursVec.data();



    for( int i = 0; i < number_of_monochrome_textured_quads; ++i )
    {
        int index_a = file->GetU16LE( pointer_to_mesh_data + 0x0 );
        int index_b = file->GetU16LE( pointer_to_mesh_data + 0x2 );
        int index_c = file->GetU16LE( pointer_to_mesh_data + 0x4 );
        int index_d = file->GetU16LE( pointer_to_mesh_data + 0x6 );

        Ogre::Vector3 a( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x0 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x2 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x4 ) );
        Ogre::Vector3 b( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x0 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x2 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x4 ) );
        Ogre::Vector3 c( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x0 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x2 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x4 ) );
        Ogre::Vector3 d( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_d * 0x8 + 0x0 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_d * 0x8 + 0x2 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_d * 0x8 + 0x4 ) );
        a /= 512;
        b /= 512;
        c /= 512;
        d /= 512;




        int image_id = file->GetU8( pointer_to_mesh_data + 0x13 );
        u16 blend = file12->GetU16LE( offset_to_clut_tex + image_id * 4 + 0 );
        u16 clut = file12->GetU16LE( offset_to_clut_tex + image_id * 4 + 2 );
        LOGGER->Log( "image_id = \"" + HexToString( image_id, 2, '0' ) + "\", clut = \"" + HexToString( clut, 4, '0' ) + "\", blend = \"" + HexToString( blend, 4, '0' ) + "\".\n" );
/*
        int clut_x = (clut & 0x003f) << 3;
        int clut_y = (clut & 0xffc0) >> 6;
        int bpp    = (tpage >> 0x7) & 0x3;
        int vram_x = (tpage & 0xf) * 64;
        int vram_y = ((tpage & 0x10) >> 4) * 256;
*/
        TexForGen texture;
        texture.palette_x = 128/*clut_x*/;
        texture.palette_y = 224/*clut_y*/;
        if( image_id == 1 )
        {
            texture.texture_x = 768/*vram_x*/;
        }
        else
        {
            texture.texture_x = 832/*vram_x*/;
        }
        texture.texture_y = 256/*vram_y*/;
        texture.bpp = BPP_8/*bpp*/;
        AddTexture( texture, mesh_data, textures, LOGGER );

        Ogre::Vector2 at( 0, 0 );
        Ogre::Vector2 bt( 0, 0 );
        Ogre::Vector2 ct( 0, 0 );
        Ogre::Vector2 dt( 0, 0 );

        u16 vertex1_uv = file->GetU16LE( pointer_to_mesh_data + 0x8 );
        at.x = ( file->GetU8( pointer_to_texture_data + vertex1_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
        at.y = ( file->GetU8( pointer_to_texture_data + vertex1_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;

        u16 vertex2_uv = file->GetU16LE( pointer_to_mesh_data + 0xa );
        bt.x = ( file->GetU8( pointer_to_texture_data + vertex2_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
        bt.y = ( file->GetU8( pointer_to_texture_data + vertex2_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;

        u16 vertex3_uv = file->GetU16LE( pointer_to_mesh_data + 0xc );
        ct.x = ( file->GetU8( pointer_to_texture_data + vertex3_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
        ct.y = ( file->GetU8( pointer_to_texture_data + vertex3_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;

        u16 vertex4_uv = file->GetU16LE( pointer_to_mesh_data + 0xe );
        dt.x = ( file->GetU8( pointer_to_texture_data + vertex4_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
        dt.y = ( file->GetU8( pointer_to_texture_data + vertex4_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;

        *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = d.x; *pPos++ = d.y; *pPos++ = d.z;

        *tPos++ = at.x; *tPos++ = at.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = bt.x; *tPos++ = bt.y;
        *tPos++ = bt.x; *tPos++ = bt.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = dt.x; *tPos++ = dt.y;

        Ogre::ColourValue colour = Ogre::ColourValue( file->GetU8( pointer_to_mesh_data + 0x10 ) / 256.0f,
                                                      file->GetU8( pointer_to_mesh_data + 0x11 ) / 256.0f,
                                                      file->GetU8( pointer_to_mesh_data + 0x12 ) / 256.0f,
                                                      1.0f );

        rs->convertColourValue( colour, colours + cur_index + 0 );
        rs->convertColourValue( colour, colours + cur_index + 1 );
        rs->convertColourValue( colour, colours + cur_index + 2 );
        rs->convertColourValue( colour, colours + cur_index + 3 );
        rs->convertColourValue( colour, colours + cur_index + 4 );
        rs->convertColourValue( colour, colours + cur_index + 5 );

        idata[ cur_index + 0 ] = cur_index + 0;
        idata[ cur_index + 1 ] = cur_index + 1;
        idata[ cur_index + 2 ] = cur_index + 2;
        idata[ cur_index + 3 ] = cur_index + 3;
        idata[ cur_index + 4 ] = cur_index + 4;
        idata[ cur_index + 5 ] = cur_index + 5;

        Ogre::VertexBoneAssignment vba;
        vba.weight = 1.0f;

        vba.vertexIndex = cur_index + 0;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_a * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );
        vba.vertexIndex = cur_index + 1;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_c * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );
        vba.vertexIndex = cur_index + 2;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_b * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );
        vba.vertexIndex = cur_index + 3;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_b * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );
        vba.vertexIndex = cur_index + 4;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_c * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );
        vba.vertexIndex = cur_index + 5;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_d * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );



        cur_index += 6;
        pointer_to_mesh_data += 0x18;
    }



    for( int i = 0; i < number_of_monochrome_textured_triangles; ++i )
    {
        int index_a = file->GetU16LE( pointer_to_mesh_data + 0x0 );
        int index_b = file->GetU16LE( pointer_to_mesh_data + 0x2 );
        int index_c = file->GetU16LE( pointer_to_mesh_data + 0x4 );

        Ogre::Vector3 a( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x0 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x2 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x4 ) );
        Ogre::Vector3 b( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x0 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x2 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x4 ) );
        Ogre::Vector3 c( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x0 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x2 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x4 ) );
        a /= 512;
        b /= 512;
        c /= 512;

        int image_id = file->GetU8( pointer_to_mesh_data + 0x6 );
        u16 blend = file12->GetU16LE( offset_to_clut_tex + image_id * 4 + 0 );
        u16 clut = file12->GetU16LE( offset_to_clut_tex + image_id * 4 + 2 );
        LOGGER->Log( "image_id = \"" + HexToString( image_id, 2, '0' ) + "\", clut = \"" + HexToString( clut, 4, '0' ) + "\", blend = \"" + HexToString( blend, 4, '0' ) + "\".\n" );
/*
        int clut_x = (clut & 0x003f) << 3;
        int clut_y = (clut & 0xffc0) >> 6;
        int bpp    = (tpage >> 0x7) & 0x3;
        int vram_x = (tpage & 0xf) * 64;
        int vram_y = ((tpage & 0x10) >> 4) * 256;
*/

        TexForGen texture;
        texture.palette_x = 128/*clut_x*/;
        texture.palette_y = 224/*clut_y*/;
        if( image_id == 1 )
        {
            texture.texture_x = 768/*vram_x*/;
        }
        else
        {
            texture.texture_x = 832/*vram_x*/;
        }
        texture.texture_y = 256/*vram_y*/;
        texture.bpp = BPP_8/*bpp*/;
        AddTexture( texture, mesh_data, textures, LOGGER );

        Ogre::Vector2 at( 0, 0 );
        Ogre::Vector2 bt( 0, 0 );
        Ogre::Vector2 ct( 0, 0 );

        u16 vertex1_uv = file->GetU16LE( pointer_to_mesh_data + 0xc );
        at.x = ( file->GetU8( pointer_to_texture_data + vertex1_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
        at.y = ( file->GetU8( pointer_to_texture_data + vertex1_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;

        u16 vertex2_uv = file->GetU16LE( pointer_to_mesh_data + 0xe );
        bt.x = ( file->GetU8( pointer_to_texture_data + vertex2_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
        bt.y = ( file->GetU8( pointer_to_texture_data + vertex2_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;

        u16 vertex3_uv = file->GetU16LE( pointer_to_mesh_data + 0x10 );
        ct.x = ( file->GetU8( pointer_to_texture_data + vertex3_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
        ct.y = ( file->GetU8( pointer_to_texture_data + vertex3_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;

        *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;

        *tPos++ = at.x; *tPos++ = at.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = bt.x; *tPos++ = bt.y;

        Ogre::ColourValue colour = Ogre::ColourValue( file->GetU8( pointer_to_mesh_data + 0x08 ) / 256.0f,
                                                      file->GetU8( pointer_to_mesh_data + 0x09 ) / 256.0f,
                                                      file->GetU8( pointer_to_mesh_data + 0x0a ) / 256.0f,
                                                      1.0f );

        rs->convertColourValue( colour, colours + cur_index + 0 );
        rs->convertColourValue( colour, colours + cur_index + 1 );
        rs->convertColourValue( colour, colours + cur_index + 2 );

        idata[ cur_index + 0 ] = cur_index + 0;
        idata[ cur_index + 1 ] = cur_index + 1;
        idata[ cur_index + 2 ] = cur_index + 2;

        Ogre::VertexBoneAssignment vba;
        vba.weight = 1.0f;

        vba.vertexIndex = cur_index + 0;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_a * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );
        vba.vertexIndex = cur_index + 1;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_c * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );
        vba.vertexIndex = cur_index + 2;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_b * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );

        cur_index += 3;
        pointer_to_mesh_data += 0x14;
    }



    vbuf0->unlock();
    vbuf1->writeData( 0, vbuf1->getSizeInBytes(), colours, true );
    vbuf2->unlock();

    sub_mesh->indexData->indexBuffer->unlock();
    // Optimize index data
    sub_mesh->indexData->optimiseVertexCacheTriList();



    delete file12;
}
Пример #23
0
void MapView::createTerrain()
{
	unsigned int sizeX = mMap->getTerrainSize().x;
	unsigned int sizeZ = mMap->getTerrainSize().z;

	mTileX = 33;
	mTileZ = 33;

	unsigned int tileCount = ((sizeX - 1) / (mTileX - 1)) * ((sizeZ - 1) / (mTileZ - 1));
	unsigned int vertexPerTile = mTileX * mTileZ;
	unsigned int trianglesPerTile = (mTileX - 1) * (mTileZ - 1) * 2;

	mMeshes.resize(tileCount);
	mEntities.resize(tileCount);
	mSceneNodes.resize(tileCount);

	// vertexPerTile * 3 vertices * 2 texture coordinates * 3 colours * 3 normals
	VertexVector vertices(vertexPerTile * 11);

	// trianglesPerTile * 3 indices per each triangle
	IndexVector indices[3] =
	{
		IndexVector(trianglesPerTile * 3    ),
		IndexVector(trianglesPerTile * 3 / 4),
		IndexVector(trianglesPerTile * 3 / 8)
	};

	unsigned int vertexIndex, indexIndex = 0, tileIndex = 0;

	for (unsigned int zIndex = 0; zIndex < mTileZ - 1; ++zIndex)
	{
		for (unsigned int xIndex = 0; xIndex < mTileX - 1; ++xIndex)
		{
			indices[0][indexIndex++] =  zIndex      * mTileX + xIndex;
			indices[0][indexIndex++] = (zIndex + 1) * mTileX + xIndex;
			indices[0][indexIndex++] =  zIndex      * mTileX + xIndex + 1;

			indices[0][indexIndex++] = (zIndex + 1) * mTileX + xIndex;
			indices[0][indexIndex++] = (zIndex + 1) * mTileX + xIndex + 1;
			indices[0][indexIndex++] =  zIndex      * mTileX + xIndex + 1;
		}
	}

	indexIndex = 0;

	for (unsigned int zIndex = 0; zIndex < mTileZ - 1; zIndex += 2)
	{
		for (unsigned int xIndex = 0; xIndex < mTileX - 1; xIndex += 2)
		{
			indices[1][indexIndex++] =  zIndex      * mTileX + xIndex;
			indices[1][indexIndex++] = (zIndex + 2) * mTileX + xIndex;
			indices[1][indexIndex++] =  zIndex      * mTileX + xIndex + 2;

			indices[1][indexIndex++] = (zIndex + 2) * mTileX + xIndex;
			indices[1][indexIndex++] = (zIndex + 2) * mTileX + xIndex + 2;
			indices[1][indexIndex++] =  zIndex      * mTileX + xIndex + 2;
		}
	}

	indexIndex = 0;

	for (unsigned int zIndex = 0; zIndex < mTileZ - 1; zIndex += 4)
	{
		for (unsigned int xIndex = 0; xIndex < mTileX - 1; xIndex += 4)
		{
			indices[2][indexIndex++] =  zIndex      * mTileX + xIndex;
			indices[2][indexIndex++] = (zIndex + 4) * mTileX + xIndex;
			indices[2][indexIndex++] =  zIndex      * mTileX + xIndex + 4;

			indices[2][indexIndex++] = (zIndex + 4) * mTileX + xIndex;
			indices[2][indexIndex++] = (zIndex + 4) * mTileX + xIndex + 4;
			indices[2][indexIndex++] =  zIndex      * mTileX + xIndex + 4;
		}
	}

	float scaleX = mMap->getSize().x / (float)(sizeX - 1);
	float scaleZ = mMap->getSize().z / (float)(sizeZ - 1);

	for (unsigned int zTile = 0; zTile < (sizeZ - 1); zTile += (mTileZ - 1))
	{
		for (unsigned int xTile = 0; xTile < (sizeX - 1); xTile += (mTileX - 1))
		{
			vertexIndex = 0;

			for (unsigned int zVertex = zTile; zVertex < zTile + mTileZ; ++zVertex)
			{
				for (unsigned int xVertex = xTile; xVertex < xTile + mTileX; ++xVertex)
				{
					float yVertex = mMap->getTerrainData()[zVertex * sizeX + xVertex];

					vertices[vertexIndex++] = (float)xVertex * scaleX;
					vertices[vertexIndex++] = (float)yVertex;
					vertices[vertexIndex++] = (float)zVertex * scaleZ;

					vertices[vertexIndex++] = (float)xVertex / (float)(sizeX - 1);
					vertices[vertexIndex++] = (float)zVertex / (float)(sizeZ - 1);

					vertices[vertexIndex++] = 1.0f;
					vertices[vertexIndex++] = 1.0f;
					vertices[vertexIndex++] = 1.0f;

					vertices[vertexIndex++] = 0.0f;
					vertices[vertexIndex++] = 1.0f;
					vertices[vertexIndex++] = 0.0f;
				}
			}

			std::string name =
				"MapView_" + Convert::ToString(mID) +
				"_Tile_" + Convert::ToString(tileIndex);

			// Create mesh.
			mMeshes[tileIndex] = Ogre::MeshManager::getSingleton().createManual(
				name, "General").get();

			// Create one submesh.
			Ogre::SubMesh* subMesh = mMeshes[tileIndex]->createSubMesh();

			// Create vertex data structure for vertices shared between submeshes.
			mMeshes[tileIndex]->sharedVertexData = new Ogre::VertexData();
			mMeshes[tileIndex]->sharedVertexData->vertexCount = vertexPerTile;

			// Create declaration (memory format) of vertex data.
			Ogre::VertexDeclaration* decl =
				mMeshes[tileIndex]->sharedVertexData->vertexDeclaration;

			size_t offset = 0;

			// 1st buffer
			decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
			offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);

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

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

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

			// Allocate vertex buffer of the requested number of vertices (vertexPerTile)
			// and bytes per vertex (offset).
			Ogre::HardwareVertexBufferSharedPtr vbuf =
				Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
				offset, vertexPerTile, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);

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

			// Set vertex buffer binding so buffer 0 is bound to our vertex buffer.
			Ogre::VertexBufferBinding* bind =
				mMeshes[tileIndex]->sharedVertexData->vertexBufferBinding; 
			bind->setBinding(0, vbuf);

			// Allocate index buffer of the requested number of vertices .
			Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().
				createIndexBuffer(
				Ogre::HardwareIndexBuffer::IT_16BIT, 
				trianglesPerTile * 3,
				Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);

			// Upload the index data to the card.
			ibuf->writeData(0, ibuf->getSizeInBytes(), &(indices[0].front()), true);

			/// Set parameters of the submesh
			subMesh->useSharedVertices = true;
			subMesh->indexData->indexBuffer = ibuf;
			subMesh->indexData->indexCount = indices[0].size();
			subMesh->indexData->indexStart = 0;
			subMesh->setMaterialName("terrain");

			float xMin = vertices[0];
			float yMin = vertices[1];
			float zMin = vertices[2];

			float xMax = vertices[0];
			float yMax = vertices[1];
			float zMax = vertices[2];

			for (unsigned int i = 0; i < vertexPerTile * 11; i += 11)
			{
				if (vertices[i    ] < xMin) xMin = vertices[i    ]; else
				if (vertices[i    ] > xMax) xMax = vertices[i    ];

				if (vertices[i + 1] < yMin) yMin = vertices[i + 1]; else
				if (vertices[i + 1] > yMax) yMax = vertices[i + 1];

				if (vertices[i + 2] < zMin) zMin = vertices[i + 2]; else
				if (vertices[i + 2] > zMax) zMax = vertices[i + 2];
			}

			// Set bounding information (for culling).
			mMeshes[tileIndex]->_setBounds(Ogre::AxisAlignedBox(xMin, yMin, zMin, xMax, yMax, zMax));
			mMeshes[tileIndex]->_setBoundingSphereRadius(1.0f);

			// Notify Mesh object that it has been loaded.
			mMeshes[tileIndex]->load();

			// Create entity.
			mEntities[tileIndex] = createEntity(name, name);
			mEntities[tileIndex]->setCastShadows(false);
			mEntities[tileIndex]->setUserAny(Ogre::Any(this));

			// Create scene node.
			mSceneNodes[tileIndex] = createSceneNode();
			mSceneNodes[tileIndex]->attachObject(mEntities[tileIndex]);

			// Advance to next tile.
			tileIndex++;
		}
	}
}
Пример #24
0
void EMDOgre::createOgreMesh(EMDSubmesh *submesh, string mesh_name) {
	string ogre_mesh_name = mesh_name + "_" + submesh->getMaterialName();
	Ogre::MeshPtr ogre_mesh = Ogre::MeshManager::getSingleton().createManual(ogre_mesh_name, XENOVIEWER_RESOURCE_GROUP);

	LibXenoverse::AABB mesh_aabb;
	mesh_aabb.reset();

	if (skeleton) {
		ogre_mesh->setSkeletonName(skeleton->getName());
	}

	// Create Vertex Pool
	vector<EMDVertex> submesh_vertices = submesh->getVertices();
	const size_t nVertices = submesh_vertices.size();
	const size_t nVertCount = 8;
	const size_t vbufCount = nVertCount*nVertices;
	float *vertices = (float *)malloc(sizeof(float)*vbufCount);
	for (size_t i = 0; i < nVertices; i++) {
		vertices[i*nVertCount] = submesh_vertices[i].x;
		vertices[i*nVertCount + 1] = submesh_vertices[i].y;
		vertices[i*nVertCount + 2] = submesh_vertices[i].z;
		vertices[i*nVertCount + 3] = submesh_vertices[i].nx;
		vertices[i*nVertCount + 4] = submesh_vertices[i].ny;
		vertices[i*nVertCount + 5] = submesh_vertices[i].nz;
		vertices[i*nVertCount + 6] = submesh_vertices[i].u;
		vertices[i*nVertCount + 7] = submesh_vertices[i].v;
		mesh_aabb.addPoint(submesh_vertices[i].x, submesh_vertices[i].y, submesh_vertices[i].z);
	}

	// Create Submeshes for each Triangle List
	vector<EMDTriangles> submesh_triangles = submesh->getTriangles();
	for (size_t i = 0; i < submesh_triangles.size(); i++) {
		Ogre::SubMesh *sub = createOgreSubmesh(&submesh_triangles[i], ogre_mesh);
	}

	// Create Shared Vertex Data for all submeshes
	Ogre::VertexData *vertex_data = new Ogre::VertexData();
	ogre_mesh->sharedVertexData = vertex_data;
	vertex_data->vertexCount = nVertices;

	Ogre::VertexDeclaration* decl = vertex_data->vertexDeclaration;
	size_t offset = 0;

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

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

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

	Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(offset, nVertices, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
	vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);
	Ogre::VertexBufferBinding* bind = vertex_data->vertexBufferBinding;
	bind->setBinding(0, vbuf);


	// Create Bone Assignments if Skeleton name exists
	if (skeleton) {
		Ogre::Skeleton *ogre_skeleton = skeleton->getOgreSkeleton();
		if (ogre_skeleton) {
			for (size_t i = 0; i < submesh_triangles.size(); i++) {
				EMDTriangles *triangles = &submesh_triangles[i];
				vector<unsigned int> vertex_indices;
				size_t face_count = triangles->faces.size();

				// Make a list of all vertex indices being used in the submesh
				vertex_indices.reserve(face_count);
				for (size_t j = 0; j < face_count; j++) {
					bool found = false;

					for (size_t k = 0; k < vertex_indices.size(); k++) {
						if (vertex_indices[k] == triangles->faces[j]) {
							found = true;
							break;
						}
					}

					if (!found) vertex_indices.push_back(triangles->faces[j]);
				}

				// Build Bone Mapping Table
				vector<unsigned short> bone_table;
				bone_table.resize(triangles->bone_names.size());

				for (size_t j = 0; j < bone_table.size(); j++) {
					string bone_name = triangles->bone_names[j];

					LOG_DEBUG("Bone Skin Table %d: %s\n", j, bone_name.c_str());
					if (ogre_skeleton->hasBone(bone_name)) {
						Ogre::Bone *mBone = ogre_skeleton->getBone(bone_name);
						bone_table[j] = mBone->getHandle();
					}
					else {
						LOG_DEBUG("Couldn't find %s in ogre skeleton!\n", bone_name.c_str());
					}
				}

				// Add bone assignments to all the vertices that were found
				for (size_t j = 0; j < vertex_indices.size(); j++) {
					Ogre::VertexBoneAssignment vba;
					vba.vertexIndex = vertex_indices[j];
					EMDVertex *vertex = &submesh_vertices[vba.vertexIndex];

					for (size_t k = 0; k < 4; k++) {
						unsigned char bone_index = vertex->bone[3 - k];
						float bone_weight = vertex->bone_weight[k];

						if (bone_weight > 0.0f) {
							vba.boneIndex = bone_table[bone_index];
							vba.weight = bone_weight;
							ogre_mesh->addBoneAssignment(vba);
						}
					}
				}
			}

			// Apply changes, build the buffer
			ogre_mesh->_compileBoneAssignments();
			ogre_mesh->sharedVertexData->reorganiseBuffers(decl->getAutoOrganisedDeclaration(true, false, false));
		}
	}

	//ogre_mesh->_setBounds(Ogre::AxisAlignedBox(mesh_aabb.start_x, mesh_aabb.start_y, mesh_aabb.start_z, mesh_aabb.end_x, mesh_aabb.end_y, mesh_aabb.end_z));
	ogre_mesh->_setBounds(Ogre::AxisAlignedBox(-1000, -1000, -1000, 1000, 1000, 1000));
	ogre_mesh->_setBoundingSphereRadius(mesh_aabb.sizeMax());
	ogre_mesh->load();

	free(vertices);

	created_meshes.push_back(ogre_mesh_name);
}
Пример #25
0
void
MeshExtractor( const MeshData& mesh_data, const Ogre::String& material_name, File* file, int offset_to_data, VectorTexForGen& textures, const Ogre::MeshPtr& mesh, const Ogre::String& name, int bone_id )
{
    int offset_to_vertex     = offset_to_data;
    int offset_to_triangle_t = offset_to_vertex + 0x04 + file->GetU32LE( offset_to_vertex );
    int number_of_triangle_t = file->GetU16LE( offset_to_triangle_t );
    u16 tpage  = file->GetU16LE( offset_to_triangle_t + 0x02 );
    int offset_to_quad_t     = offset_to_triangle_t + 0x04 + number_of_triangle_t * 0x10;
    int number_of_quad_t     = file->GetU16LE( offset_to_quad_t );
    int offset_to_triangle   = offset_to_quad_t + 0x4 + number_of_quad_t * 0x14;
    int number_of_triangle   = file->GetU16LE( offset_to_triangle );
    int offset_to_quad       = offset_to_triangle + 0x4 + number_of_triangle * 0x14;
    int number_of_quad       = file->GetU16LE( offset_to_quad );

    Ogre::SubMesh* sub_mesh = mesh->createSubMesh( name );
    sub_mesh->setMaterialName( material_name );
    sub_mesh->useSharedVertices = false;
    sub_mesh->operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;

    // Allocate and prepare vertex data
    sub_mesh->vertexData = new Ogre::VertexData();
    sub_mesh->vertexData->vertexStart = 0;
    sub_mesh->vertexData->vertexCount = static_cast< size_t >( number_of_triangle_t * 3 + number_of_quad_t * 6 + number_of_triangle * 3 + number_of_quad * 6 );

    sub_mesh->indexData = new Ogre::IndexData();
    sub_mesh->indexData->indexStart = 0;
    sub_mesh->indexData->indexCount = sub_mesh->vertexData->vertexCount;
    sub_mesh->indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
        Ogre::HardwareIndexBuffer::IT_16BIT,
        sub_mesh->indexData->indexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    u16* idata = static_cast< u16* >( sub_mesh->indexData->indexBuffer->lock( Ogre::HardwareBuffer::HBL_DISCARD ) );
    u32 cur_index = 0;

    Ogre::VertexDeclaration* decl = sub_mesh->vertexData->vertexDeclaration;
    Ogre::VertexBufferBinding* bind = sub_mesh->vertexData->vertexBufferBinding;
    // 1st buffer
    decl->addElement( POSITION_BINDING, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION );
    Ogre::HardwareVertexBufferSharedPtr vbuf0 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
        decl->getVertexSize( POSITION_BINDING ),
        sub_mesh->vertexData->vertexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    bind->setBinding( POSITION_BINDING, vbuf0 );

    // 2nd buffer
    decl->addElement( COLOUR_BINDING, 0, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE );
    Ogre::HardwareVertexBufferSharedPtr vbuf1 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
        decl->getVertexSize( COLOUR_BINDING ),
        sub_mesh->vertexData->vertexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    // Set vertex buffer binding so buffer 1 is bound to our colour buffer
    bind->setBinding( COLOUR_BINDING, vbuf1 );

    // 3rd buffer
    decl->addElement( TEXTURE_BINDING, 0, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0 );
    Ogre::HardwareVertexBufferSharedPtr vbuf2 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
        decl->getVertexSize( TEXTURE_BINDING ),
        sub_mesh->vertexData->vertexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    bind->setBinding( TEXTURE_BINDING, vbuf2 );

    float* pPos   = static_cast< float* >( vbuf0->lock( Ogre::HardwareBuffer::HBL_DISCARD ) );
    float* tPos   = static_cast< float* >( vbuf2->lock( Ogre::HardwareBuffer::HBL_DISCARD ) );

    Ogre::RenderSystem* rs = Ogre::Root::getSingleton().getRenderSystem();
    Ogre::RGBA colours[ sub_mesh->vertexData->vertexCount ];



    // add textured triangle
    for (int j = 0; j < number_of_triangle_t; ++j)
    {
        int offset_a = file->GetU16LE(offset_to_triangle_t + 0x4 + j * 0x10 + 0x0);
        int offset_b = file->GetU16LE(offset_to_triangle_t + 0x4 + j * 0x10 + 0x2);
        int offset_c = file->GetU16LE(offset_to_triangle_t + 0x4 + j * 0x10 + 0x4);

        Ogre::Vector3 a((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 04));
        Ogre::Vector3 b((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 04));
        Ogre::Vector3 c((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 04));
        a /= 512;
        b /= 512;
        c /= 512;

        u16 clut = file->GetU16LE(offset_to_triangle_t + 0x4 + j * 0x10 + 0xa);
        int clut_x = (clut & 0x003f) << 3;
        int clut_y = (clut & 0xffc0) >> 6;
        int bpp    = (tpage >> 0x7) & 0x3;
        int vram_x = (tpage & 0xf) * 64;
        int vram_y = ((tpage & 0x10) >> 4) * 256;
        TexForGen texture;
        texture.palette_x = clut_x;
        texture.palette_y = clut_y;
        texture.texture_x = vram_x;
        texture.texture_y = vram_y;
        texture.bpp = ( BPP )bpp;
        AddTexture( texture, mesh_data, textures, LOGGER );

        Ogre::Vector2 at(0, 0);
        Ogre::Vector2 bt(0, 0);
        Ogre::Vector2 ct(0, 0);

        int x = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x8) + texture.start_x;
        at.x = x / (float)mesh_data.tex_width;
        int y = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x9) + texture.start_y;
        at.y = y / (float)mesh_data.tex_height;
        x = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0xc) + texture.start_x;
        bt.x = x / (float)mesh_data.tex_width;
        y = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0xd) + texture.start_y;
        bt.y = y / (float)mesh_data.tex_height;
        x = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0xe) + texture.start_x;
        ct.x = x / (float)mesh_data.tex_width;
        y = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0xf) + texture.start_y;
        ct.y = y / (float)mesh_data.tex_height;

        *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;

        *tPos++ = at.x; *tPos++ = at.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = bt.x; *tPos++ = bt.y;

        Ogre::ColourValue colour = Ogre::ColourValue(file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x6) / 256.0f,
                                                     file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x6) / 256.0f,
                                                     file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x6) / 256.0f,
                                                     1.0f);

        rs->convertColourValue(colour, colours + cur_index + 0);
        rs->convertColourValue(colour, colours + cur_index + 1);
        rs->convertColourValue(colour, colours + cur_index + 2);

        idata[cur_index + 0] = cur_index + 0;
        idata[cur_index + 1] = cur_index + 1;
        idata[cur_index + 2] = cur_index + 2;

        cur_index += 3;
    }



    // add textured quad
    for (int j = 0; j < number_of_quad_t; ++j)
    {
        int offset_a = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0x0);
        int offset_b = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0x2);
        int offset_c = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0x4);
        int offset_d = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0x6);

        Ogre::Vector3 a((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 04));
        Ogre::Vector3 b((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 04));
        Ogre::Vector3 c((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 04));
        Ogre::Vector3 d((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 04));
        a /= 512;
        b /= 512;
        c /= 512;
        d /= 512;

        u16 clut = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0xa);
        int clut_x = (clut & 0x003f) << 3;
        int clut_y = (clut & 0xffc0) >> 6;
        int bpp    = (tpage >> 0x7) & 0x3;
        int vram_x = (tpage & 0xf) * 64;
        int vram_y = ((tpage & 0x10) >> 4) * 256;
        TexForGen texture;
        texture.palette_x = clut_x;
        texture.palette_y = clut_y;
        texture.texture_x = vram_x;
        texture.texture_y = vram_y;
        texture.bpp = ( BPP )bpp;
        AddTexture( texture, mesh_data, textures, LOGGER );

        Ogre::Vector2 at(0, 0);
        Ogre::Vector2 bt(0, 0);
        Ogre::Vector2 ct(0, 0);
        Ogre::Vector2 dt(0, 0);

        int x = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x8) + texture.start_x;
        at.x = x / (float)mesh_data.tex_width;
        int y = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x9) + texture.start_y;
        at.y = y / (float)mesh_data.tex_height;

        x = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0xc) + texture.start_x;
        bt.x = x / (float)mesh_data.tex_width;
        y = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0xd) + texture.start_y;
        bt.y = y / (float)mesh_data.tex_height;

        x = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0xe) + texture.start_x;
        ct.x = x / (float)mesh_data.tex_width;
        y = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0xf) + texture.start_y;
        ct.y = y / (float)mesh_data.tex_height;

        x = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x10) + texture.start_x;
        dt.x = x / (float)mesh_data.tex_width;
        y = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x11) + texture.start_y;
        dt.y = y / (float)mesh_data.tex_height;

        *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = d.x; *pPos++ = d.y; *pPos++ = d.z;

        *tPos++ = at.x; *tPos++ = at.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = bt.x; *tPos++ = bt.y;
        *tPos++ = bt.x; *tPos++ = bt.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = dt.x; *tPos++ = dt.y;

        Ogre::ColourValue colour = Ogre::ColourValue(file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x12) / 256.0f,
                                                     file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x12) / 256.0f,
                                                     file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x12) / 256.0f,
                                                     1.0f);

        rs->convertColourValue(colour, colours + cur_index + 0);
        rs->convertColourValue(colour, colours + cur_index + 1);
        rs->convertColourValue(colour, colours + cur_index + 2);
        rs->convertColourValue(colour, colours + cur_index + 3);
        rs->convertColourValue(colour, colours + cur_index + 4);
        rs->convertColourValue(colour, colours + cur_index + 5);

        idata[cur_index + 0] = cur_index + 0;
        idata[cur_index + 1] = cur_index + 1;
        idata[cur_index + 2] = cur_index + 2;
        idata[cur_index + 3] = cur_index + 3;
        idata[cur_index + 4] = cur_index + 4;
        idata[cur_index + 5] = cur_index + 5;

        cur_index += 6;
    }



    // add color triangle
    for (int j = 0; j < number_of_triangle; ++j)
    {
        int offset_a = file->GetU16LE(offset_to_triangle + 0x4 + j * 0x14 + 0x0);
        int offset_b = file->GetU16LE(offset_to_triangle + 0x4 + j * 0x14 + 0x2);
        int offset_c = file->GetU16LE(offset_to_triangle + 0x4 + j * 0x14 + 0x4);

        Ogre::Vector3 a((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 04));
        Ogre::Vector3 b((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 04));
        Ogre::Vector3 c((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 04));
        a /= 512;
        b /= 512;
        c /= 512;

        TexForGen texture;
        texture.palette_x = 0;
        texture.palette_y = 0;
        texture.texture_x = 0;
        texture.texture_y = 0;
        texture.bpp = BPP_BLACK;
        AddTexture( texture, mesh_data, textures, LOGGER );

        Ogre::Vector2 at(0, 0);
        Ogre::Vector2 bt(0, 0);
        Ogre::Vector2 ct(0, 0);

        at.x = bt.x = ct.x = texture.start_x / (float)mesh_data.tex_width;
        at.y = bt.y = ct.y = texture.start_y / (float)mesh_data.tex_height;

        *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;

        *tPos++ = at.x; *tPos++ = at.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = bt.x; *tPos++ = bt.y;

        Ogre::ColourValue a_colour = Ogre::ColourValue(file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x08) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x09) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0a) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0b) / 256.0f);
        Ogre::ColourValue b_colour = Ogre::ColourValue(file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0c) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0d) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0e) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0f) / 256.0f);
        Ogre::ColourValue c_colour = Ogre::ColourValue(file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x10) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x11) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x12) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x13) / 256.0f);

        rs->convertColourValue(a_colour, colours + cur_index + 0);
        rs->convertColourValue(c_colour, colours + cur_index + 1);
        rs->convertColourValue(b_colour, colours + cur_index + 2);

        idata[cur_index + 0] = cur_index + 0;
        idata[cur_index + 1] = cur_index + 1;
        idata[cur_index + 2] = cur_index + 2;

        cur_index += 3;
    }



    // add color quad
    for (int j = 0; j < number_of_quad; ++j)
    {
        int offset_a = file->GetU16LE(offset_to_quad + 0x4 + j * 0x18 + 0x0);
        int offset_b = file->GetU16LE(offset_to_quad + 0x4 + j * 0x18 + 0x2);
        int offset_c = file->GetU16LE(offset_to_quad + 0x4 + j * 0x18 + 0x4);
        int offset_d = file->GetU16LE(offset_to_quad + 0x4 + j * 0x18 + 0x6);

        Ogre::Vector3 a((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 04));
        Ogre::Vector3 b((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 04));
        Ogre::Vector3 c((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 04));
        Ogre::Vector3 d((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 04));
        a /= 512;
        b /= 512;
        c /= 512;
        d /= 512;

        TexForGen texture;
        texture.palette_x = 0;
        texture.palette_y = 0;
        texture.texture_x = 0;
        texture.texture_y = 0;
        texture.bpp = BPP_BLACK;
        AddTexture( texture, mesh_data, textures, LOGGER );

        Ogre::Vector2 at(0, 0);
        Ogre::Vector2 bt(0, 0);
        Ogre::Vector2 ct(0, 0);
        Ogre::Vector2 dt(0, 0);

        at.x = bt.x = ct.x = dt.x = texture.start_x / (float)mesh_data.tex_width;
        at.y = bt.y = ct.y = dt.y = texture.start_y / (float)mesh_data.tex_height;

        *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = d.x; *pPos++ = d.y; *pPos++ = d.z;

        *tPos++ = at.x; *tPos++ = at.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = bt.x; *tPos++ = bt.y;
        *tPos++ = bt.x; *tPos++ = bt.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = dt.x; *tPos++ = dt.y;

        Ogre::ColourValue a_colour = Ogre::ColourValue(file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x08) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x09) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0a) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0b) / 256.0f);
        Ogre::ColourValue b_colour = Ogre::ColourValue(file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0c) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0d) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0e) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0f) / 256.0f);
        Ogre::ColourValue c_colour = Ogre::ColourValue(file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x10) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x11) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x12) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x13) / 256.0f);
        Ogre::ColourValue d_colour = Ogre::ColourValue(file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x14) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x15) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x16) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x17) / 256.0f);

        rs->convertColourValue(a_colour, colours + cur_index + 0);
        rs->convertColourValue(c_colour, colours + cur_index + 1);
        rs->convertColourValue(b_colour, colours + cur_index + 2);
        rs->convertColourValue(b_colour, colours + cur_index + 3);
        rs->convertColourValue(c_colour, colours + cur_index + 4);
        rs->convertColourValue(d_colour, colours + cur_index + 5);

        idata[cur_index + 0] = cur_index + 0;
        idata[cur_index + 1] = cur_index + 1;
        idata[cur_index + 2] = cur_index + 2;
        idata[cur_index + 3] = cur_index + 3;
        idata[cur_index + 4] = cur_index + 4;
        idata[cur_index + 5] = cur_index + 5;

        cur_index += 6;
    }

    vbuf0->unlock();
    vbuf1->writeData(0, vbuf1->getSizeInBytes(), colours, true);
    vbuf2->unlock();

    sub_mesh->indexData->indexBuffer->unlock();
    // Optimize index data
    sub_mesh->indexData->optimiseVertexCacheTriList();

    if (bone_id != -1)
    {
        LOGGER->Log("Assign bones to vertexes\n");

        int vertex_number = sub_mesh->vertexData->vertexCount;
        for( int i = 0; i < vertex_number; ++i )
        {
            Ogre::VertexBoneAssignment vba;
            vba.vertexIndex = i;
            vba.boneIndex = bone_id;
            vba.weight = 1.0f;
            sub_mesh->addBoneAssignment( vba );
        }
    }
}
Пример #26
0
  void MeshManager::_createGeometry()
  {
    int numVertices = mSteps * mCircles + 1;
    int numEle = 6 * mSteps * (mCircles - 1) + 3 * mSteps;
    // Vertex buffers
    mSubMesh->vertexData = new Ogre::VertexData();
    mSubMesh->vertexData->vertexStart = 0;
    mSubMesh->vertexData->vertexCount = numVertices;
    Ogre::VertexDeclaration* vdecl = mSubMesh->vertexData->vertexDeclaration;
    Ogre::VertexBufferBinding* vbind = mSubMesh->vertexData->vertexBufferBinding;
    size_t offset = 0;
    vdecl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
    offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
    vdecl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_TEXTURE_COORDINATES, 0);
    offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
    vdecl->addElement(0, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 1);
    offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2);
    vdecl->addElement(0, offset, Ogre::VET_FLOAT1, Ogre::VES_TEXTURE_COORDINATES, 2);
    mVertexBuffer = Ogre::HardwareBufferManager::getSingleton().
                    createVertexBuffer(sizeof(POS_UV_VERTEX),
                                       numVertices,
                                       Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
    vbind->setBinding(0, mVertexBuffer);
    unsigned int *indexbuffer = new unsigned int[numEle];

    for(int k = 0; k < mSteps; k++)
    {
      indexbuffer[k * 3] = 0;
      indexbuffer[k * 3 + 1] = k + 1;

      if(k != mSteps - 1)
      {
        indexbuffer[k * 3 + 2] = k + 2;
      }
      else
      {
        indexbuffer[k * 3 + 2] = 1;
      }
    }

    for(int y = 0; y < mCircles - 1; y++)
    {
      for(int x = 0; x < mSteps; x++)
      {
        unsigned int *twoface = indexbuffer + (y * mSteps + x) * 6 + 3 * mSteps;
        int p0 = 1 + y * mSteps + x ;
        int p1 = 1 + y * mSteps + x + 1 ;
        int p2 = 1 + (y + 1) * mSteps + x ;
        int p3 = 1 + (y + 1) * mSteps + x + 1 ;

        if(x == mSteps - 1)
        {
          p1 -= x + 1;
          p3 -= x + 1;
        }

        // First triangle
        twoface[2] = p0;
        twoface[1] = p1;
        twoface[0] = p2;
        // Second triangle
        twoface[5] = p1;
        twoface[4] = p3;
        twoface[3] = p2;
      }
    }

    // Prepare buffer for indices
    mIndexBuffer =
      Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
        Ogre::HardwareIndexBuffer::IT_32BIT,
        numEle,
        Ogre::HardwareBuffer::HBU_STATIC, true);
    mIndexBuffer->
    writeData(0,
              mIndexBuffer->getSizeInBytes(),
              indexbuffer,
              true);
    delete []indexbuffer;
    // Set index buffer for this submesh
    mSubMesh->indexData->indexBuffer = mIndexBuffer;
    mSubMesh->indexData->indexStart = 0;
    mSubMesh->indexData->indexCount = numEle;
    // Create our internal buffer for manipulations
    mVertices = new POS_UV_VERTEX[1 + mSteps * mCircles];
  }
Пример #27
0
void NIFMeshLoader::createSubMesh(Ogre::Mesh *mesh, const Nif::NiTriShape *shape)
{
    const Nif::NiTriShapeData *data = shape->data.getPtr();
    const Nif::NiSkinInstance *skin = (shape->skin.empty() ? NULL : shape->skin.getPtr());
    std::vector<Ogre::Vector3> srcVerts = data->vertices;
    std::vector<Ogre::Vector3> srcNorms = data->normals;
    Ogre::HardwareBuffer::Usage vertUsage = Ogre::HardwareBuffer::HBU_STATIC;
    bool vertShadowBuffer = false;

    bool geomMorpherController = false;
    if(!shape->controller.empty())
    {
        Nif::ControllerPtr ctrl = shape->controller;
        do {
            if(ctrl->recType == Nif::RC_NiGeomMorpherController)
            {
                vertUsage = Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY;
                vertShadowBuffer = true;
                geomMorpherController = true;
                break;
            }
        } while(!(ctrl=ctrl->next).empty());
    }

    if(skin != NULL)
    {
        vertUsage = Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY;
        vertShadowBuffer = true;

        // Only set a skeleton when skinning. Unskinned meshes with a skeleton will be
        // explicitly attached later.
        mesh->setSkeletonName(mName);

        // Convert vertices and normals to bone space from bind position. It would be
        // better to transform the bones into bind position, but there doesn't seem to
        // be a reliable way to do that.
        std::vector<Ogre::Vector3> newVerts(srcVerts.size(), Ogre::Vector3(0.0f));
        std::vector<Ogre::Vector3> newNorms(srcNorms.size(), Ogre::Vector3(0.0f));

        const Nif::NiSkinData *data = skin->data.getPtr();
        const Nif::NodeList &bones = skin->bones;
        for(size_t b = 0;b < bones.length();b++)
        {
            Ogre::Matrix4 mat;
            mat.makeTransform(data->bones[b].trafo.trans, Ogre::Vector3(data->bones[b].trafo.scale),
                              Ogre::Quaternion(data->bones[b].trafo.rotation));
            mat = bones[b]->getWorldTransform() * mat;

            const std::vector<Nif::NiSkinData::VertWeight> &weights = data->bones[b].weights;
            for(size_t i = 0;i < weights.size();i++)
            {
                size_t index = weights[i].vertex;
                float weight = weights[i].weight;

                newVerts.at(index) += (mat*srcVerts[index]) * weight;
                if(newNorms.size() > index)
                {
                    Ogre::Vector4 vec4(srcNorms[index][0], srcNorms[index][1], srcNorms[index][2], 0.0f);
                    vec4 = mat*vec4 * weight;
                    newNorms[index] += Ogre::Vector3(&vec4[0]);
                }
            }
        }

        srcVerts = newVerts;
        srcNorms = newNorms;
    }
    else
    {
        Ogre::SkeletonManager *skelMgr = Ogre::SkeletonManager::getSingletonPtr();
        if(skelMgr->getByName(mName).isNull())
        {
            // No skinning and no skeleton, so just transform the vertices and
            // normals into position.
            Ogre::Matrix4 mat4 = shape->getWorldTransform();
            for(size_t i = 0;i < srcVerts.size();i++)
            {
                Ogre::Vector4 vec4(srcVerts[i].x, srcVerts[i].y, srcVerts[i].z, 1.0f);
                vec4 = mat4*vec4;
                srcVerts[i] = Ogre::Vector3(&vec4[0]);
            }
            for(size_t i = 0;i < srcNorms.size();i++)
            {
                Ogre::Vector4 vec4(srcNorms[i].x, srcNorms[i].y, srcNorms[i].z, 0.0f);
                vec4 = mat4*vec4;
                srcNorms[i] = Ogre::Vector3(&vec4[0]);
            }
        }
    }

    // Set the bounding box first
    BoundsFinder bounds;
    bounds.add(&srcVerts[0][0], srcVerts.size());
    if(!bounds.isValid())
    {
        float v[3] = { 0.0f, 0.0f, 0.0f };
        bounds.add(&v[0], 1);
    }

    mesh->_setBounds(Ogre::AxisAlignedBox(bounds.minX()-0.5f, bounds.minY()-0.5f, bounds.minZ()-0.5f,
                                          bounds.maxX()+0.5f, bounds.maxY()+0.5f, bounds.maxZ()+0.5f));
    mesh->_setBoundingSphereRadius(bounds.getRadius());

    // This function is just one long stream of Ogre-barf, but it works
    // great.
    Ogre::HardwareBufferManager *hwBufMgr = Ogre::HardwareBufferManager::getSingletonPtr();
    Ogre::HardwareVertexBufferSharedPtr vbuf;
    Ogre::HardwareIndexBufferSharedPtr ibuf;
    Ogre::VertexBufferBinding *bind;
    Ogre::VertexDeclaration *decl;
    int nextBuf = 0;

    Ogre::SubMesh *sub = mesh->createSubMesh();

    // Add vertices
    sub->useSharedVertices = false;
    sub->vertexData = new Ogre::VertexData();
    sub->vertexData->vertexStart = 0;
    sub->vertexData->vertexCount = srcVerts.size();

    decl = sub->vertexData->vertexDeclaration;
    bind = sub->vertexData->vertexBufferBinding;
    if(srcVerts.size())
    {
        vbuf = hwBufMgr->createVertexBuffer(Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3),
                                            srcVerts.size(), vertUsage, vertShadowBuffer);
        vbuf->writeData(0, vbuf->getSizeInBytes(), &srcVerts[0][0], true);

        decl->addElement(nextBuf, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
        bind->setBinding(nextBuf++, vbuf);
    }

    // Vertex normals
    if(srcNorms.size())
    {
        vbuf = hwBufMgr->createVertexBuffer(Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3),
                                            srcNorms.size(), vertUsage, vertShadowBuffer);
        vbuf->writeData(0, vbuf->getSizeInBytes(), &srcNorms[0][0], true);

        decl->addElement(nextBuf, 0, Ogre::VET_FLOAT3, Ogre::VES_NORMAL);
        bind->setBinding(nextBuf++, vbuf);
    }

    // Vertex colors
    const std::vector<Ogre::Vector4> &colors = data->colors;
    if(colors.size())
    {
        Ogre::RenderSystem *rs = Ogre::Root::getSingleton().getRenderSystem();
        std::vector<Ogre::RGBA> colorsRGB(colors.size());
        for(size_t i = 0;i < colorsRGB.size();i++)
        {
            Ogre::ColourValue clr(colors[i][0], colors[i][1], colors[i][2], colors[i][3]);
            rs->convertColourValue(clr, &colorsRGB[i]);
        }
        vbuf = hwBufMgr->createVertexBuffer(Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR),
                                            colorsRGB.size(), Ogre::HardwareBuffer::HBU_STATIC);
        vbuf->writeData(0, vbuf->getSizeInBytes(), &colorsRGB[0], true);
        decl->addElement(nextBuf, 0, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);
        bind->setBinding(nextBuf++, vbuf);
    }

    // Texture UV coordinates
    size_t numUVs = data->uvlist.size();
    if (numUVs)
    {
        size_t elemSize = Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2);

        for(size_t i = 0; i < numUVs; i++)
            decl->addElement(nextBuf, elemSize*i, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, i);

        vbuf = hwBufMgr->createVertexBuffer(decl->getVertexSize(nextBuf), srcVerts.size(),
                                            Ogre::HardwareBuffer::HBU_STATIC);

        std::vector<Ogre::Vector2> allUVs;
        allUVs.reserve(srcVerts.size()*numUVs);
        for (size_t vert = 0; vert<srcVerts.size(); ++vert)
            for(size_t i = 0; i < numUVs; i++)
                allUVs.push_back(data->uvlist[i][vert]);

        vbuf->writeData(0, elemSize*srcVerts.size()*numUVs, &allUVs[0], true);

        bind->setBinding(nextBuf++, vbuf);
    }

    // Triangle faces
    const std::vector<short> &srcIdx = data->triangles;
    if(srcIdx.size())
    {
        ibuf = hwBufMgr->createIndexBuffer(Ogre::HardwareIndexBuffer::IT_16BIT, srcIdx.size(),
                                           Ogre::HardwareBuffer::HBU_STATIC);
        ibuf->writeData(0, ibuf->getSizeInBytes(), &srcIdx[0], true);
        sub->indexData->indexBuffer = ibuf;
        sub->indexData->indexCount = srcIdx.size();
        sub->indexData->indexStart = 0;
    }

    // Assign bone weights for this TriShape
    if(skin != NULL)
    {
        Ogre::SkeletonPtr skel = Ogre::SkeletonManager::getSingleton().getByName(mName);

        const Nif::NiSkinData *data = skin->data.getPtr();
        const Nif::NodeList &bones = skin->bones;
        for(size_t i = 0;i < bones.length();i++)
        {
            Ogre::VertexBoneAssignment boneInf;
            boneInf.boneIndex = skel->getBone(bones[i]->name)->getHandle();

            const std::vector<Nif::NiSkinData::VertWeight> &weights = data->bones[i].weights;
            for(size_t j = 0;j < weights.size();j++)
            {
                boneInf.vertexIndex = weights[j].vertex;
                boneInf.weight = weights[j].weight;
                sub->addBoneAssignment(boneInf);
            }
        }
    }

    const Nif::NiTexturingProperty *texprop = NULL;
    const Nif::NiMaterialProperty *matprop = NULL;
    const Nif::NiAlphaProperty *alphaprop = NULL;
    const Nif::NiVertexColorProperty *vertprop = NULL;
    const Nif::NiZBufferProperty *zprop = NULL;
    const Nif::NiSpecularProperty *specprop = NULL;
    const Nif::NiWireframeProperty *wireprop = NULL;
    bool needTangents = false;

    shape->getProperties(texprop, matprop, alphaprop, vertprop, zprop, specprop, wireprop);
    std::string matname = NIFMaterialLoader::getMaterial(data, mesh->getName(), mGroup,
                                                         texprop, matprop, alphaprop,
                                                         vertprop, zprop, specprop,
                                                         wireprop, needTangents);
    if(matname.length() > 0)
        sub->setMaterialName(matname);

    // build tangents if the material needs them
    if (needTangents)
    {
        unsigned short src,dest;
        if (!mesh->suggestTangentVectorBuildParams(Ogre::VES_TANGENT, src,dest))
            mesh->buildTangentVectors(Ogre::VES_TANGENT, src,dest);
    }

    // Create a dummy vertex animation track if there's a geom morpher controller
    // This is required to make Ogre create the buffers we will use for software vertex animation
    if (srcVerts.size() && geomMorpherController)
        mesh->createAnimation("dummy", 0)->createVertexTrack(1, sub->vertexData, Ogre::VAT_MORPH);
}
Пример #28
0
void MilkshapePlugin::doExportMesh(msModel* pModel)
{


    // Create singletons
    Ogre::SkeletonManager skelMgr;
    Ogre::DefaultHardwareBufferManager defHWBufMgr;
	Ogre::LogManager& logMgr = Ogre::LogManager::getSingleton();
	Ogre::MeshManager meshMgr;


    //
    // choose filename
    //
    OPENFILENAME ofn;
    memset (&ofn, 0, sizeof (OPENFILENAME));

    char szFile[MS_MAX_PATH];
    char szFileTitle[MS_MAX_PATH];
    char szDefExt[32] = "mesh";
    char szFilter[128] = "OGRE .mesh Files (*.mesh)\0*.mesh\0All Files (*.*)\0*.*\0\0";
    szFile[0] = '\0';
    szFileTitle[0] = '\0';

    ofn.lStructSize = sizeof (OPENFILENAME);
    ofn.lpstrDefExt = szDefExt;
    ofn.lpstrFilter = szFilter;
    ofn.lpstrFile = szFile;
    ofn.nMaxFile = MS_MAX_PATH;
    ofn.lpstrFileTitle = szFileTitle;
    ofn.nMaxFileTitle = MS_MAX_PATH;
    ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
    ofn.lpstrTitle = "Export to OGRE Mesh";

    if (!::GetSaveFileName (&ofn))
        return /*0*/;

    logMgr.logMessage("Creating Mesh object...");
    Ogre::MeshPtr ogreMesh = Ogre::MeshManager::getSingleton().create("export", 
        Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
    logMgr.logMessage("Mesh object created.");

    bool foundBoneAssignment = false;

    // No shared geometry
    int i;
	int wh, numbones;
	int intweight[3], intbones[3];
    size_t j;
    Ogre::Vector3 min, max, currpos;
    Ogre::Real maxSquaredRadius;
    bool first = true;
    for (i = 0; i < msModel_GetMeshCount (pModel); i++)
    {
        msMesh *pMesh = msModel_GetMeshAt (pModel, i);

        logMgr.logMessage("Creating SubMesh object...");
        Ogre::SubMesh* ogreSubMesh = ogreMesh->createSubMesh();
        logMgr.logMessage("SubMesh object created.");
        // Set material
        logMgr.logMessage("Getting SubMesh Material...");
        int matIdx = msMesh_GetMaterialIndex(pMesh);

        if (matIdx == -1)
        {
            // No material, use blank
            ogreSubMesh->setMaterialName("BaseWhite");
            logMgr.logMessage("No Material, using default 'BaseWhite'.");
        }
        else
        {

            msMaterial *pMat = msModel_GetMaterialAt(pModel, matIdx);
            ogreSubMesh->setMaterialName(pMat->szName);
            logMgr.logMessage("SubMesh Material Done.");
        }


        logMgr.logMessage("Setting up geometry...");
        // Set up mesh geometry
        ogreSubMesh->vertexData = new Ogre::VertexData();
        ogreSubMesh->vertexData->vertexCount = msMesh_GetVertexCount (pMesh);
        ogreSubMesh->vertexData->vertexStart = 0;
        Ogre::VertexBufferBinding* bind = ogreSubMesh->vertexData->vertexBufferBinding;
        Ogre::VertexDeclaration* decl = ogreSubMesh->vertexData->vertexDeclaration;
        // Always 1 texture layer, 2D coords
        #define POSITION_BINDING 0
        #define NORMAL_BINDING 1
        #define TEXCOORD_BINDING 2
        decl->addElement(POSITION_BINDING, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
        decl->addElement(NORMAL_BINDING, 0, Ogre::VET_FLOAT3, Ogre::VES_NORMAL);
        decl->addElement(TEXCOORD_BINDING, 0, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES);
        // Create buffers
        Ogre::HardwareVertexBufferSharedPtr pbuf = Ogre::HardwareBufferManager::getSingleton().
            createVertexBuffer(decl->getVertexSize(POSITION_BINDING), ogreSubMesh->vertexData->vertexCount,
                Ogre::HardwareBuffer::HBU_DYNAMIC, false);
        Ogre::HardwareVertexBufferSharedPtr nbuf = Ogre::HardwareBufferManager::getSingleton().
            createVertexBuffer(decl->getVertexSize(NORMAL_BINDING), ogreSubMesh->vertexData->vertexCount,
                Ogre::HardwareBuffer::HBU_DYNAMIC, false);
        Ogre::HardwareVertexBufferSharedPtr tbuf = Ogre::HardwareBufferManager::getSingleton().
            createVertexBuffer(decl->getVertexSize(TEXCOORD_BINDING), ogreSubMesh->vertexData->vertexCount,
                Ogre::HardwareBuffer::HBU_DYNAMIC, false);
        bind->setBinding(POSITION_BINDING, pbuf);
        bind->setBinding(NORMAL_BINDING, nbuf);
        bind->setBinding(TEXCOORD_BINDING, tbuf);

        ogreSubMesh->useSharedVertices = false;

        float* pPos = static_cast<float*>(
            pbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));

        logMgr.logMessage("Doing positions and texture coords...");
        for (j = 0; j < ogreSubMesh->vertexData->vertexCount; ++j)
        {
            logMgr.logMessage("Doing vertex " + Ogre::StringConverter::toString(j));
            msVertex *pVertex = msMesh_GetVertexAt (pMesh, (int)j);
			msVertexEx *pVertexEx=msMesh_GetVertexExAt(pMesh, (int)j);
            msVec3 Vertex;
            msVertex_GetVertex (pVertex, Vertex);

            *pPos++ = Vertex[0];
            *pPos++ = Vertex[1];
            *pPos++ = Vertex[2];
            // Deal with bounds
            currpos = Ogre::Vector3(Vertex[0], Vertex[1], Vertex[2]);
            if (first)
            {
                min = max = currpos;
                maxSquaredRadius = currpos.squaredLength();
                first = false;
            }
            else
            {
                min.makeFloor(currpos);
                max.makeCeil(currpos);
                maxSquaredRadius = std::max(maxSquaredRadius, currpos.squaredLength());
            }

            int boneIdx = msVertex_GetBoneIndex(pVertex);
            if (boneIdx != -1)
            {
				foundBoneAssignment = true;
				numbones = 1;
				intbones[0] = intbones[1] = intbones[2] = -1;
				intweight[0] = intweight[1] = intweight[2] = 0;
				for(wh = 0; wh < 3; ++wh) 
				{
					intbones[wh] = msVertexEx_GetBoneIndices(pVertexEx, wh);
					if(intbones[wh] == -1) 
						break;

					++numbones;
					intweight[wh] = msVertexEx_GetBoneWeights(pVertexEx, wh);

				} // for(k)
				Ogre::VertexBoneAssignment vertAssign;
				vertAssign.boneIndex = boneIdx;
				vertAssign.vertexIndex = (unsigned int)j;
				if(numbones == 1) 
				{
					vertAssign.weight = 1.0;
				} // single assignment
				else 
				{
					vertAssign.weight=(Ogre::Real)intweight[0]/100.0;
				}
				ogreSubMesh->addBoneAssignment(vertAssign);
				if(numbones > 1) 
				{
					// this somewhat contorted logic is because the first weight [0] matches to the bone assignment
					// located with pVertex. The next two weights [1][2] match up to the first two bones found
					// with pVertexEx [0][1]. The weight for the fourth bone, if present, is the unassigned weight
					for(wh = 0; wh < 3; wh++) 
					{
						boneIdx = intbones[wh];
						if(boneIdx == -1) 
							break;
						vertAssign.boneIndex = boneIdx;
						vertAssign.vertexIndex = (unsigned int)j;
						if(wh == 2) 
						{ 
							// fourth weight is 1.0-(sumoffirstthreeweights)
							vertAssign.weight = 1.0-(((Ogre::Real)intweight[0]/100.0)+
								((Ogre::Real)intweight[1]/100.0)+((Ogre::Real)intweight[2]/100.0));
						}
						else 
						{
							vertAssign.weight=(Ogre::Real)intweight[wh+1];
						}
						ogreSubMesh->addBoneAssignment(vertAssign);
					} // for(k)
				} // if(numbones)
			}

        }
        pbuf->unlock();

        float* pTex = static_cast<float*>(
            tbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
        logMgr.logMessage("Doing uvs, normals and indexes (v2)...");

        // Aargh, Milkshape uses stupid separate normal indexes for the same vertex like 3DS
        // Normals aren't described per vertex but per triangle vertex index
        // Pain in the arse, we have to do vertex duplication again if normals differ at a vertex (non smooth)
        // WHY don't people realise this format is a pain for passing to 3D APIs in vertex buffers?
        float* pNorm = static_cast<float*>(
            nbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
        ogreSubMesh->indexData->indexCount = msMesh_GetTriangleCount (pMesh) * 3;
        // Always use 16-bit buffers, Milkshape can't handle more anyway
        Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().
            createIndexBuffer(Ogre::HardwareIndexBuffer::IT_16BIT,
            ogreSubMesh->indexData->indexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
        ogreSubMesh->indexData->indexBuffer = ibuf;
        unsigned short *pIdx = static_cast<unsigned short*>(
            ibuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
        for (j = 0; j < ogreSubMesh->indexData->indexCount; j+=3)
        {
            msTriangle *pTriangle = msMesh_GetTriangleAt (pMesh, (int)j/3);
			msTriangleEx *pTriangleEx=msMesh_GetTriangleExAt(pMesh, (int)j/3);
            word nIndices[3];
            msTriangle_GetVertexIndices (pTriangle, nIndices);
            msVec3 Normal;
            msVec2 uv;
            int k, vertIdx;

            for (k = 0; k < 3; ++k)
            {
                vertIdx = nIndices[k];
                // Face index
                pIdx[j+k] = vertIdx;

                // Vertex normals
                // For the moment, ignore any discrepancies per vertex
				msTriangleEx_GetNormal(pTriangleEx, k, &Normal[0]);
				msTriangleEx_GetTexCoord(pTriangleEx, k, &uv[0]);
				pTex[(vertIdx*2)]=uv[0];
				pTex[(vertIdx*2)+1]=uv[1];
                pNorm[(vertIdx*3)] = Normal[0];
                pNorm[(vertIdx*3)+1] = Normal[1];
                pNorm[(vertIdx*3)+2] = Normal[2];
            }

        } // Faces
        nbuf->unlock();
        ibuf->unlock();
        tbuf->unlock();

        // Now use Ogre's ability to reorganise the vertex buffers the best way
        Ogre::VertexDeclaration* newDecl = 
            ogreSubMesh->vertexData->vertexDeclaration->getAutoOrganisedDeclaration(
                foundBoneAssignment, false);
        Ogre::BufferUsageList bufferUsages;
        for (size_t u = 0; u <= newDecl->getMaxSource(); ++u)
            bufferUsages.push_back(Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
        ogreSubMesh->vertexData->reorganiseBuffers(newDecl, bufferUsages);


        logMgr.logMessage("Geometry done.");
    } // SubMesh

    // Set bounds
    ogreMesh->_setBoundingSphereRadius(Ogre::Math::Sqrt(maxSquaredRadius));
    ogreMesh->_setBounds(Ogre::AxisAlignedBox(min, max), false);


    // Keep hold of a Skeleton pointer for deletion later
    // Mesh uses Skeleton pointer for skeleton name
    Ogre::SkeletonPtr pSkel;

    if (exportSkeleton && foundBoneAssignment)
    {
        // export skeleton, also update mesh to point to it
        pSkel = doExportSkeleton(pModel, ogreMesh);
    }
    else if (!exportSkeleton && foundBoneAssignment)
    {
        // We've found bone assignments, but skeleton is not to be exported
        // Prompt the user to find the skeleton
        if (!locateSkeleton(ogreMesh))
            return;

    }

    // Export
    logMgr.logMessage("Creating MeshSerializer..");
    Ogre::MeshSerializer serializer;
    logMgr.logMessage("MeshSerializer created.");

    // Generate LODs if required
    if (generateLods)
    {
        // Build LOD depth list
        Ogre::Mesh::LodDistanceList distList;
        float depth = 0;
        for (unsigned short depthidx = 0; depthidx < numLods; ++depthidx)
        {
            depth += lodDepthIncrement;
            distList.push_back(depth);
        }

        ogreMesh->generateLodLevels(distList, lodReductionMethod, lodReductionAmount);
    }

    if (generateEdgeLists)
    {
        ogreMesh->buildEdgeList();
    }

    if (generateTangents)
    {
		unsigned short src, dest;
		ogreMesh->suggestTangentVectorBuildParams(tangentSemantic, src, dest);
		ogreMesh->buildTangentVectors(tangentSemantic, src, dest, tangentsSplitMirrored, tangentsSplitRotated, tangentsUseParity);
    }

    // Export
    Ogre::String msg;
	msg  = "Exporting mesh data to file '" + Ogre::String(szFile) + "'";
    logMgr.logMessage(msg);
    serializer.exportMesh(ogreMesh.getPointer(), szFile);
    logMgr.logMessage("Export successful");

    Ogre::MeshManager::getSingleton().remove(ogreMesh->getHandle());
    if (!pSkel.isNull())
        Ogre::SkeletonManager::getSingleton().remove(pSkel->getHandle());

	if (exportMaterials && msModel_GetMaterialCount(pModel) > 0)
	{
		doExportMaterials(pModel);
	}
}
void GPUBillboardSet::createVertexDataForVertexAndGeometryShaders(const std::vector<PhotoSynth::Vertex>& vertices)
{
	// Setup render operation
	mRenderOp.operationType = Ogre::RenderOperation::OT_POINT_LIST; 
	mRenderOp.vertexData = OGRE_NEW Ogre::VertexData();
	mRenderOp.vertexData->vertexCount = vertices.size(); 
	mRenderOp.vertexData->vertexStart = 0; 
	mRenderOp.useIndexes = false; 
	mRenderOp.indexData = 0;

	// Vertex format declaration
	unsigned short sourceBufferIdx = 0;
    Ogre::VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
    size_t currOffset = 0;
	decl->addElement(sourceBufferIdx, currOffset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
	currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
	decl->addElement(sourceBufferIdx, currOffset, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);
	currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR);

	// Create vertex buffer
	Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
		decl->getVertexSize(sourceBufferIdx),
		mRenderOp.vertexData->vertexCount,
		Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);

    // Bind vertex buffer
    Ogre::VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;
	bind->setBinding(sourceBufferIdx, vbuf);

	// Fill vertex buffer (see http://www.ogre3d.org/docs/manual/manual_59.html#SEC287)
	Ogre::RenderSystem* renderSystem = Ogre::Root::getSingletonPtr()->getRenderSystem();
	unsigned char* pVert = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
	Ogre::Real* pReal;
	Ogre::RGBA* pRGBA;
	Ogre::VertexDeclaration::VertexElementList elems = decl->findElementsBySource(sourceBufferIdx);
	Ogre::VertexDeclaration::VertexElementList::iterator itr;
	for (unsigned int i=0; i<vertices.size(); ++i )
	{
		const PhotoSynth::Vertex& vertex = vertices[i];
		for (itr=elems.begin(); itr!=elems.end(); ++itr)
		{
			Ogre::VertexElement& elem = *itr;
			if (elem.getSemantic() == Ogre::VES_POSITION)
			{
				elem.baseVertexPointerToElement(pVert, &pReal);
				*pReal = vertex.position.x; *pReal++;
				*pReal = vertex.position.y; *pReal++;
				*pReal = vertex.position.z; *pReal++;
			}
			else if (elem.getSemantic() == Ogre::VES_DIFFUSE)
			{
				elem.baseVertexPointerToElement(pVert, &pRGBA);
				renderSystem->convertColourValue(vertex.color, pRGBA);
			}
		}
		// Go to next vertex 
		pVert += vbuf->getVertexSize();
	}
	vbuf->unlock();

    // Set material
    this->setMaterial("GPUBillboardWithGS");
}
void GPUBillboardSet::createVertexDataForVertexShaderOnly(const std::vector<PhotoSynth::Vertex>& vertices)
{
	// Setup render operation
	mRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST; 
	mRenderOp.vertexData = OGRE_NEW Ogre::VertexData();
	mRenderOp.vertexData->vertexCount = vertices.size() * 4; 
	mRenderOp.vertexData->vertexStart = 0; 
	mRenderOp.useIndexes = true; 
	mRenderOp.indexData = OGRE_NEW Ogre::IndexData();
	mRenderOp.indexData->indexCount = vertices.size() * 6;
	mRenderOp.indexData->indexStart = 0;

	// Vertex format declaration
	unsigned short sourceBufferIdx = 0;
	Ogre::VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
    size_t currOffset = 0;
	decl->addElement(sourceBufferIdx, currOffset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
	currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
	decl->addElement(sourceBufferIdx, currOffset, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);
	currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR);
	decl->addElement(sourceBufferIdx, currOffset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0);
	currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2);

	// Create vertex buffer
    Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
		decl->getVertexSize(sourceBufferIdx),
        mRenderOp.vertexData->vertexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);

    // Bind vertex buffer
    Ogre::VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;
	bind->setBinding(sourceBufferIdx, vbuf);

	// Fill vertex buffer (see http://www.ogre3d.org/docs/manual/manual_59.html#SEC287)
	Ogre::RenderSystem* renderSystem = Ogre::Root::getSingletonPtr()->getRenderSystem();
	unsigned char* pVert = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
	Ogre::Real* pReal;
	Ogre::RGBA* pRGBA;
	Ogre::VertexDeclaration::VertexElementList elems = decl->findElementsBySource(sourceBufferIdx);
	Ogre::VertexDeclaration::VertexElementList::iterator itr;

	const Ogre::Vector2 uvs[4] = {	Ogre::Vector2( -1.f, 1.f ),
									Ogre::Vector2( -1.f, -1.f ),
									Ogre::Vector2( 1.f, -1.f ),
									Ogre::Vector2( 1.f, 1.f ) };
	for (unsigned int i=0; i<vertices.size(); ++i )
	{
		const PhotoSynth::Vertex& vertex = vertices[i];
		for ( unsigned int j=0; j<4; j++ )
		{
			for (itr=elems.begin(); itr!=elems.end(); ++itr)
			{
				Ogre::VertexElement& elem = *itr;
				if (elem.getSemantic() == Ogre::VES_POSITION)
				{
					elem.baseVertexPointerToElement(pVert, &pReal);
					*pReal = vertex.position.x; *pReal++;
					*pReal = vertex.position.y; *pReal++;
					*pReal = vertex.position.z; *pReal++;
				}
				else if (elem.getSemantic() == Ogre::VES_DIFFUSE)
				{
					elem.baseVertexPointerToElement(pVert, &pRGBA);
					renderSystem->convertColourValue(vertex.color, pRGBA);
				}
				else if (elem.getSemantic() == Ogre::VES_TEXTURE_COORDINATES && elem.getIndex() == 0)
				{
					elem.baseVertexPointerToElement(pVert, &pReal);
					*pReal = uvs[j].x; *pReal++;
					*pReal = uvs[j].y; *pReal++;
				}
			}
			// Go to next vertex 
			pVert += vbuf->getVertexSize();
		}
	}
	vbuf->unlock();

	// Create index buffer
	if (mRenderOp.indexData->indexCount>=65536)
	{
		Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer( 
			Ogre::HardwareIndexBuffer::IT_32BIT, 
			mRenderOp.indexData->indexCount, 
			Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);

		mRenderOp.indexData->indexBuffer = ibuf;
		Ogre::uint32* indices = static_cast<Ogre::uint32*>(ibuf->lock( Ogre::HardwareBuffer::HBL_DISCARD));

		Ogre::uint32 indexFirstVertex = 0;
		const Ogre::uint32 inds[6] = {	0, 1, 2, 3, 0, 2 };
		for (unsigned int i=0; i<vertices.size(); ++i)
		{
			for (unsigned int j=0; j<6; ++j)
			{
				*indices = indexFirstVertex + inds[j];
				indices++;
			}
			indexFirstVertex +=4;
		}
		ibuf->unlock();
	}
	else
	{
		Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
			Ogre::HardwareIndexBuffer::IT_16BIT, 
			mRenderOp.indexData->indexCount, 
			Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);

		mRenderOp.indexData->indexBuffer = ibuf;
		Ogre::uint16* indices = static_cast<Ogre::uint16*>( ibuf->lock( Ogre::HardwareBuffer::HBL_DISCARD ) );

		Ogre::uint32 indexFirstVertex = 0;
		const Ogre::uint16 inds[6] = {	0, 1, 2, 3, 0, 2 };
		for ( unsigned int i=0; i<vertices.size(); ++i )
		{
			for ( unsigned int j=0; j<6; ++j )
			{
				*indices = indexFirstVertex + inds[j];
				indices++;
			}
			indexFirstVertex +=4;
		}
		ibuf->unlock();
	}

    // Set material
    this->setMaterial("GPUBillboard");
}