Exemplo n.º 1
0
bool tdnMesh::CreateIndexes( unsigned int numIndexes, const DWORD *indexArray )
{
	HRESULT hr( S_OK );

	this->numIndexes = numIndexes;

	// インデックス配列のサイズ計算
	unsigned int indexesSize = sizeof( DWORD ) * numIndexes;
	// インデックスnew
	hr = tdnSystem::GetDevice()->CreateIndexBuffer(
		indexesSize,     // インデックス配列のバイト数
		0,               // 使用方法 D3DUSAGE
		D3DFMT_INDEX32,  // フォーマット
		D3DPOOL_MANAGED, // ?
		&indexBuffer,    // インデックスバッファ <out>
		NULL );          // ?
	if ( FAILED( hr ) )
		return false;

	// バッファにコピー
	DWORD* workIndex( nullptr );
	hr = indexBuffer->Lock( 0, 0, ( void** ) &workIndex, 0 );    // バッファロック (バファのポインター取得)
	if ( FAILED( hr ) )
		return false;
	memcpy_s( workIndex, indexesSize, indexArray, indexesSize ); // バッファにインデックス情報をコピー
	hr = indexBuffer->Unlock();                                  // バッファロックを解除
	if ( FAILED( hr ) )
		return false;

	return true;
}
Exemplo n.º 2
0
	void RenderingContext::DrawInParallel( StlVector<std::shared_ptr<RenderingContext>>& contexts, const StlVector<std::shared_ptr<IMesh>>& meshes, int meshCount, FuncPreRender funcPreRender )
	{
		if ( meshes.empty() )
		{
			return;
		}

		if ( contexts.empty() )
		{
			LOG_WARNING( "no contexts" );
			return;
		}

		// Validate the specified rendering contexts.
		for ( auto context : contexts )
		{
			if ( context == nullptr )
			{
				LOG_WARNING( "forbidden null context usage" );
				return;
			}
		}

		if ( meshes.size() < static_cast<size_t>( meshCount ) )
		{
			LOG_WARNING( "invalid mesh count" );
			return;
		}

		// If the number of meshes is less than 4, 
		// draw all meshes on the first context without parallel processing.
		if ( meshCount < Thread::HardwareConcurrency() )
		{
			auto context = contexts[0];
			for ( const auto& mesh : meshes )
			{
				context->Draw( mesh );
			}
			return;
		}


		RenderingDevice* pDevice = RenderingDevice::GetInstance();
		Assert( pDevice );

		size_t numContexts = contexts.size();

		// Note that the world matrix would be multiplied just before drawing a mesh
		// because the world matrix of a mesh is different each other.
		// So premultiply view-projection matrices only.
		Matrix4 viewProj = pDevice->GetViewMatrix() * pDevice->GetProjectionMatrix();

		// Thread objects.
		ThreadPool* threadPool = ThreadPool::GetInstance();
		Atomic<int> workIndex( 0 );

		for ( size_t c = 0; c < numContexts; ++c )
		{
			auto context = contexts[c];
			Assert( context );

			auto task = std::bind(
				[=, &workIndex]( std::shared_ptr<RenderingContext> context, Matrix4 viewProj, FuncPreRender funcPreRender )
				{
					SCOPE_PROFILE_BEGIN( "RenderTask" );

					ConstantBuffer& cbuffer = context->GetSharedConstantBuffer();

					// Until the last index...
					while ( workIndex.Value() < meshCount )
					{
						// Prefech the workIndex to avoid changing the value on other thread, and then increment the workIndex.
						int index = workIndex.FetchAndIncrement();

						// Check the index again to guarantee atomic.
						// FIXME: Is this necessary?
						if ( index >= meshCount )
						{
							return;
						}

						// Call the PreRender functor.
						funcPreRender( context, index );

						// Now compute the final WVP matrix of this mesh.
						Matrix4 wvp = cbuffer.GetMatrix4( ConstantBuffer::WorldMatrix ) * viewProj;
						cbuffer.SetMatrix4( ConstantBuffer::WVPMatrix, wvp );

						// Draw the mesh.
						context->Draw( meshes[index] );
					}

					SCOPE_PROFILE_END();
				},
				context,
				viewProj,
				funcPreRender );

			threadPool->Queue( task );
		}


		// Join all rendering threads.
		SCOPE_PROFILE_BEGIN( "JoinRendering" );
		threadPool->WaitForAllTasks();
		SCOPE_PROFILE_END();

			
		//// Resolve the UAV to display using the main context.
		//// We assume that rendering order is independent.
		//SCOPE_PROFILE_BEGIN( "ResolveUnorderedAccessView " );
		//contexts[0]->ResolveUnorderedAccessViews( contexts );
		//SCOPE_PROFILE_END();
	}