Ejemplo n.º 1
0
    //------------------------------------------------------------------------
    void TerrainBatch::createGpuVertexData()
    {
        if ( !mGpuVertexData )
        {
            DefaultTerrainTilesGpuBufferAllocator& gpuBufferAllocator 
                                                = mSurfaceManager->getDefaultTerrainTilesGpuBufferAllocator();
            mOneVertexSize                      = mTileRender->getOneVertexSize();
            Ogre::VertexData* tileVertexData    = mTileRender->getCpuVertexData();

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

            mGpuVertexData  = OGRE_NEW VertexData();


            // copy vertex buffers
            // get new buffers
            HardwareVertexBufferSharedPtr destPosBuf;
            gpuBufferAllocator.allocateVertexBuffers(mOneVertexSize, mVertexTotalNum, destPosBuf);

            // set bindings
            mGpuVertexData->vertexBufferBinding->setBinding( TerrainTileRender::POSITION_BUFFER, destPosBuf);

            // Basic vertex info
            mGpuVertexData->vertexStart = 0;
            mGpuVertexData->vertexCount = mVertexTotalNum;

            // Copy elements
            const VertexDeclaration::VertexElementList elems = 
                tileVertexData->vertexDeclaration->getElements();
            VertexDeclaration::VertexElementList::const_iterator ei, eiend;
            eiend = elems.end();
            for (ei = elems.begin(); ei != eiend; ++ei)
            {
                mGpuVertexData->vertexDeclaration->addElement(
                    ei->getSource(),
                    ei->getOffset(),
                    ei->getType(),
                    ei->getSemantic(),
                    ei->getIndex() );
            }
        }
    }
Ejemplo n.º 2
0
void displayVertexBuffers(VertexDeclaration::VertexElementList& elemList)
{
    // Iterate per buffer
    unsigned short currentBuffer = 999;
    unsigned short elemNum = 0;
    VertexDeclaration::VertexElementList::iterator i, iend;
    iend = elemList.end();
    for (i = elemList.begin(); i != iend; ++i) {
        if (i->getSource() != currentBuffer) {
            currentBuffer = i->getSource();
            cout << "> Buffer " << currentBuffer << ":" << endl;
        }
        cout << "   - Element " << elemNum++ << ": " << describeSemantic(i->getSemantic());
        if (i->getSemantic() == VES_TEXTURE_COORDINATES) {
            cout << " (index " << i->getIndex() << ")"; 
        }
        cout << endl;

    }
}
	//-----------------------------------------------------------------------
	void InstanceBatchShader::setupHardwareSkinned( const SubMesh* baseSubMesh, VertexData *thisVertexData,
													VertexData *baseVertexData )
	{
		const size_t numBones = baseSubMesh->blendIndexToBoneIndexMap.size();
		mNumWorldMatrices = mInstancesPerBatch * numBones;

		for( size_t i=0; i<=thisVertexData->vertexDeclaration->getMaxSource(); ++i )
		{
			//Create our own vertex buffer
			HardwareVertexBufferSharedPtr vertexBuffer =
											HardwareBufferManager::getSingleton().createVertexBuffer(
											thisVertexData->vertexDeclaration->getVertexSize(i),
											thisVertexData->vertexCount,
											HardwareBuffer::HBU_STATIC_WRITE_ONLY );
			thisVertexData->vertexBufferBinding->setBinding( i, vertexBuffer );

			VertexDeclaration::VertexElementList veList =
											thisVertexData->vertexDeclaration->findElementsBySource(i);

			//Grab the base submesh data
			HardwareVertexBufferSharedPtr baseVertexBuffer =
													baseVertexData->vertexBufferBinding->getBuffer(i);

			char* thisBuf = static_cast<char*>(vertexBuffer->lock(HardwareBuffer::HBL_DISCARD));
			char* baseBuf = static_cast<char*>(baseVertexBuffer->lock(HardwareBuffer::HBL_READ_ONLY));
			char *startBuf = baseBuf;

			//Copy and repeat
			for( size_t j=0; j<mInstancesPerBatch; ++j )
			{
				//Repeat source
				baseBuf = startBuf;

				for( size_t k=0; k<baseVertexData->vertexCount; ++k )
				{
					VertexDeclaration::VertexElementList::const_iterator it = veList.begin();
					VertexDeclaration::VertexElementList::const_iterator en = veList.end();

					while( it != en )
					{
						switch( it->getSemantic() )
						{
						case VES_BLEND_INDICES:
						*(thisBuf + it->getOffset() + 0) = *(baseBuf + it->getOffset() + 0) + j * numBones;
						*(thisBuf + it->getOffset() + 1) = *(baseBuf + it->getOffset() + 1) + j * numBones;
						*(thisBuf + it->getOffset() + 2) = *(baseBuf + it->getOffset() + 2) + j * numBones;
						*(thisBuf + it->getOffset() + 3) = *(baseBuf + it->getOffset() + 3) + j * numBones;
							break;
						default:
							memcpy( thisBuf + it->getOffset(), baseBuf + it->getOffset(), it->getSize() );
							break;
						}
						++it;
					}
					thisBuf += baseVertexData->vertexDeclaration->getVertexSize(i);
					baseBuf += baseVertexData->vertexDeclaration->getVertexSize(i);
				}
			}

			baseVertexBuffer->unlock();
			vertexBuffer->unlock();
		}
	}
Ejemplo n.º 4
0
void ModelConverter::WriteSubMesh( DiSubMesh* subMod, const Ogre::SubMesh* s )
{
	switch(s->operationType)
	{
	case RenderOperation::OT_LINE_LIST:
		subMod->SetPrimitiveType(D3DPT_LINELIST);
		break;
	case RenderOperation::OT_LINE_STRIP:
		subMod->SetPrimitiveType(D3DPT_LINESTRIP);
		break;
	case RenderOperation::OT_POINT_LIST:
		subMod->SetPrimitiveType(D3DPT_POINTLIST);
		break;
	case RenderOperation::OT_TRIANGLE_FAN:
		subMod->SetPrimitiveType(D3DPT_TRIANGLEFAN);
		break;
	case RenderOperation::OT_TRIANGLE_LIST:
		subMod->SetPrimitiveType(PT_TRIANGLELIST);
		break;
	case RenderOperation::OT_TRIANGLE_STRIP:
		subMod->SetPrimitiveType(D3DPT_TRIANGLESTRIP);
		break;
	}

	VertexData* vertexData = nullptr;
	if (mMesh->sharedVertexData)
	{
		vertexData = mMesh->sharedVertexData;
	}
	else
	{
		vertexData = s->vertexData;
	}

	int numFaces = 0;
	switch(s->operationType)
	{
	case RenderOperation::OT_TRIANGLE_LIST:
		// triangle list
		numFaces = s->indexData->indexCount / 3;

		break;
	case RenderOperation::OT_LINE_LIST:
		numFaces = s->indexData->indexCount / 2;

		break;
	case RenderOperation::OT_TRIANGLE_FAN:
	case RenderOperation::OT_TRIANGLE_STRIP:
		// triangle fan or triangle strip
		numFaces = s->indexData->indexCount - 2;

		break;
	default:
		OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
			"Unsupported render operation type", 
			__FUNCTION__);
	}

	subMod->SetPrimitiveCount(numFaces);
	subMod->SetVerticeNum(vertexData->vertexCount);

	// material name
	DiString matName;
	matName.Format("%s_%d.mtl",subMod->GetParentMesh()->GetName().c_str(),subMod->GetIndex());
	subMod->SetMaterialName(matName);

	bool use32BitIndexes = (!s->indexData->indexBuffer.isNull() && 
		s->indexData->indexBuffer->getType() == HardwareIndexBuffer::IT_32BIT);

	// Write each face in turn
	unsigned int* pInt = 0;
	unsigned short* pShort = 0;
	HardwareIndexBufferSharedPtr ibuf = s->indexData->indexBuffer;

	// index data
	if (use32BitIndexes)
	{
		pInt = static_cast<unsigned int*>(
			ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); 
	}
	else
	{
		pShort = static_cast<unsigned short*>(
			ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); 
	}

	void* indata = subMod->CreateIndexData(s->indexData->indexCount,use32BitIndexes?TRUE:FALSE);
	if (use32BitIndexes)
	{
		memcpy(indata,pInt,sizeof(unsigned int)*s->indexData->indexCount);
	}
	else
	{
		memcpy(indata,pShort,sizeof(unsigned short)*s->indexData->indexCount);
	}

	ibuf->unlock();

	// vertex declaration
	VertexDeclaration* decl = vertexData->vertexDeclaration;
	VertexBufferBinding* bind = vertexData->vertexBufferBinding;

	VertexBufferBinding::VertexBufferBindingMap::const_iterator b, bend;
	bend = bind->getBindings().end();
	// iterate over buffers
	int bindCount = 0;
	for(b = bind->getBindings().begin(); b != bend; ++b,++bindCount)
	{
		const HardwareVertexBufferSharedPtr vbuf = b->second;
		unsigned short bufferIdx = b->first;
		// get all the elements that relate to this buffer			
		VertexDeclaration::VertexElementList elems = decl->findElementsBySource(bufferIdx);
		VertexDeclaration::VertexElementList::iterator i, iend;
		iend = elems.end();

		unsigned short nuDemiureCoords = 0;
		for (i = elems.begin(); i != iend; ++i)
		{
			VertexElement& elem = *i;

			D3DDECLTYPE type = ConverteVertType(elem.getType());
			D3DDECLUSAGE usage;
			bool texcoord = false;
			switch(elem.getSemantic())
			{
			case VES_POSITION:
				usage = D3DDECLUSAGE_POSITION;
				break;
			case VES_NORMAL:
				usage = D3DDECLUSAGE_NORMAL;
				break;
			case VES_TANGENT:
				usage = D3DDECLUSAGE_TANGENT;
				break;
			case VES_BINORMAL:
				usage = D3DDECLUSAGE_BINORMAL;
				break;
			case VES_DIFFUSE:
			case VES_SPECULAR:
				usage = D3DDECLUSAGE_COLOR;
				break;
			case VES_TEXTURE_COORDINATES:
				usage = D3DDECLUSAGE_TEXCOORD;
				++nuDemiureCoords;
				texcoord = true;
				break;
			default:
				DI_ERROR("Unsupported semantic");
			}

			subMod->GetVertexElements().AddElement(bindCount,type,usage,texcoord?nuDemiureCoords-1:0);
		}

		int stride = subMod->GetVertexElements().GetStreamElementsSize(bindCount);
		void* vertData = subMod->CreateSourceData(bindCount,vertexData->vertexCount,stride);

		unsigned char* pVert = static_cast<unsigned char*>(
			vbuf->lock(HardwareBuffer::HBL_READ_ONLY));
		memcpy(vertData,pVert,vertexData->vertexCount*stride);
		vbuf->unlock();
	}

	// vertex weight
	if (mMesh->hasSkeleton())
	{
		LogManager::getSingleton().logMessage("Exporting dedicated geometry bone assignments...");

		if(const_cast<SubMesh*>(s)->getBoneAssignments().empty())
		{
			SubMesh::BoneAssignmentIterator bi = mMesh->getBoneAssignmentIterator();
			while (bi.hasMoreElements())
			{
				const VertexBoneAssignment& assign = bi.getNext();
				if (assign.weight > 0.0f)
				{
					subMod->AddWeight(assign.vertexIndex,assign.boneIndex,assign.weight);
				}
			}
		}
		else
		{
			SubMesh::BoneAssignmentIterator bi = (const_cast<SubMesh*>(s))->getBoneAssignmentIterator();
			while (bi.hasMoreElements())
			{
				const VertexBoneAssignment& assign = bi.getNext();
				if (assign.weight > 0.0f)
				{
					subMod->AddWeight(assign.vertexIndex,assign.boneIndex,assign.weight);
				}
			}
		}
		
		subMod->RationaliseBoneWeights();
	}
}