Exemplo n.º 1
0
	//-----------------------------------------------------------------------
	void BaseInstanceBatchVTF::createVertexTexture( const SubMesh* baseSubMesh )
	{
		/*
		TODO: Find a way to retrieve max texture resolution,
		http://www.ogre3d.org/forums/viewtopic.php?t=38305

		Currently assuming it's 4096x4096, which is a safe bet for any hardware with decent VTF*/
		
		size_t uniqueAnimations = mInstancesPerBatch;
		if (useBoneMatrixLookup())
		{
			uniqueAnimations = std::min<size_t>(getMaxLookupTableInstances(), uniqueAnimations);
		}
		mMatricesPerInstance = std::max<size_t>( 1, baseSubMesh->blendIndexToBoneIndexMap.size() );

		if(mUseBoneDualQuaternions && !mTempTransformsArray3x4)
		{
			mTempTransformsArray3x4 = OGRE_ALLOC_T(float, mMatricesPerInstance * 3 * 4, MEMCATEGORY_GENERAL);
		}
Exemplo n.º 2
0
    //-----------------------------------------------------------------------
    size_t InstanceBatchHW_VTF::calculateMaxNumInstances( 
                    const SubMesh *baseSubMesh, uint16 flags ) const
    {
        size_t retVal = 0;

        RenderSystem *renderSystem = Root::getSingleton().getRenderSystem();
        const RenderSystemCapabilities *capabilities = renderSystem->getCapabilities();

        //VTF & HW Instancing must be supported
        if( capabilities->hasCapability( RSC_VERTEX_BUFFER_INSTANCE_DATA ) &&
            capabilities->hasCapability( RSC_VERTEX_TEXTURE_FETCH ) )
        {
            //TODO: Check PF_FLOAT32_RGBA is supported (should be, since it was the 1st one)
            const size_t numBones = std::max<size_t>( 1, baseSubMesh->blendIndexToBoneIndexMap.size() );

            const size_t maxUsableWidth = c_maxTexWidthHW - (c_maxTexWidthHW % (numBones * mRowLength));

            //See InstanceBatchHW::calculateMaxNumInstances for the 65535
            retVal = std::min<size_t>( 65535, maxUsableWidth * c_maxTexHeightHW / mRowLength / numBones );

            if( flags & IM_VTFBESTFIT )
            {
                size_t numUsedSkeletons = mInstancesPerBatch;
                if (flags & IM_VTFBONEMATRIXLOOKUP)
                    numUsedSkeletons = std::min<size_t>(getMaxLookupTableInstances(), numUsedSkeletons);
                const size_t instancesPerBatch = std::min( retVal, numUsedSkeletons );
                //Do the same as in createVertexTexture(), but changing c_maxTexWidthHW for maxUsableWidth
                const size_t numWorldMatrices = instancesPerBatch * numBones;

                size_t texWidth  = std::min<size_t>( numWorldMatrices * mRowLength, maxUsableWidth );
                size_t texHeight = numWorldMatrices * mRowLength / maxUsableWidth;

                const size_t remainder = (numWorldMatrices * mRowLength) % maxUsableWidth;

                if( remainder && texHeight > 0 )
                    retVal = static_cast<size_t>(texWidth * texHeight / (float)mRowLength / (float)(numBones));
            }
        }

        return retVal;
    }
Exemplo n.º 3
0
    //-----------------------------------------------------------------------
    size_t InstanceBatchHW_VTF::updateVertexTexture( Camera *camera, const Camera *lodCamera )
    {
        MovableObjectArray *visibleObjects = 0;
        if( mManager->getInstancingThreadedCullingMethod() == INSTANCING_CULLING_SINGLETHREAD )
        {
            //Perform the culling now
            ObjectData objData;
            const size_t numObjs = mLocalObjectMemoryManager.getFirstObjectData( objData, 0 );

            visibleObjects = &mManager->_getTmpVisibleObjectsList()[0][mRenderQueueID];
            visibleObjects->clear();

            //TODO: Static batches aren't yet supported (camera ptr will be null and crash)
            MovableObject::cullFrustum( numObjs, objData, camera,
                        camera->getLastViewport()->getVisibilityMask()&mManager->getVisibilityMask(),
                        *visibleObjects, lodCamera );
        }
        else
        {
            //Get the results from the time the threaded version ran.
            visibleObjects = &mCulledInstances;
        }

        bool useMatrixLookup = useBoneMatrixLookup();
        if (useMatrixLookup)
        {
            //if we are using bone matrix look up we have to update the instance buffer for the 
            //vertex texture to be relevant
            fillVertexBufferLUT( visibleObjects );
        }

        //Now lock the texture and copy the 4x3 matrices!
        size_t floatsPerEntity = mMatricesPerInstance * mRowLength * 4;
        size_t entitiesPerPadding = (size_t)(mMaxFloatsPerLine / floatsPerEntity);

        mMatrixTexture->getBuffer()->lock( HardwareBuffer::HBL_DISCARD );
        const PixelBox &pixelBox = mMatrixTexture->getBuffer()->getCurrentLock();

        float *pDest = static_cast<float*>(pixelBox.data);

        if( mMeshReference->getSkeleton().isNull() )
        {
            //No animations, no anything (perhaps HW Basic is a better technique for this case)
            std::for_each( visibleObjects->begin(), visibleObjects->end(),
                            SendAllSingleTransformsToTexture( pDest, floatsPerEntity,
                                                entitiesPerPadding, mWidthFloatsPadding ) );
        }
        else
        {
            if( !useMatrixLookup && !mUseBoneDualQuaternions )
            {
                // Animations, normal
                std::for_each( visibleObjects->begin(), visibleObjects->end(),
                                SendAllAnimatedTransformsToTexture( pDest, floatsPerEntity,
                                                        entitiesPerPadding, mWidthFloatsPadding,
                                                        mIndexToBoneMap ) );
            }
            else if( mUseBoneDualQuaternions )
            {
                // Animations, Dual Quaternion Skinning
                std::for_each( visibleObjects->begin(), visibleObjects->end(),
                                SendAllDualQuatTexture( pDest, floatsPerEntity,
                                                        entitiesPerPadding,
                                                        mWidthFloatsPadding,
                                                        mIndexToBoneMap ) );
            }
            else
            {
                // Animations, LUT (lookup table)
                std::for_each( visibleObjects->begin(), visibleObjects->end(),
                                SendAllLUTToTexture( pDest, floatsPerEntity,
                                                     entitiesPerPadding, mWidthFloatsPadding,
                                                     mIndexToBoneMap,
                                                     getMaxLookupTableInstances() ) );
            }
        }

        mMatrixTexture->getBuffer()->unlock();

        return visibleObjects->size();
    }