void FRuntimeMeshProxy::UpdateSectionProperties_GameThread(int32 SectionId, const FRuntimeMeshSectionPropertyUpdateParamsPtr& SectionData)
{
	// HORU: 4.22 rendering
	ENQUEUE_RENDER_COMMAND(FRuntimeMeshProxyUpdateSectionProperties)(
	        [this, SectionId, SectionData](FRHICommandListImmediate & RHICmdList)
		{
			UpdateSectionProperties_RenderThread(SectionId, SectionData);
		}
	);
}
void FRuntimeMeshProxy::DeleteSection_GameThread(int32 SectionId)
{
	// HORU: 4.22 rendering
	ENQUEUE_RENDER_COMMAND(FRuntimeMeshProxyDeleteSection)(
	        [this, SectionId](FRHICommandListImmediate & RHICmdList)
		{
			DeleteSection_RenderThread(SectionId);
		}
	);
}
void FRuntimeMeshProxy::CreateSection_GameThread(int32 SectionId, const FRuntimeMeshSectionCreationParamsPtr& SectionData)
{
	// HORU: 4.22 rendering
	ENQUEUE_RENDER_COMMAND(FRuntimeMeshProxyCreateSection)(
	       [this, SectionId, SectionData](FRHICommandListImmediate & RHICmdList)
		{
			CreateSection_RenderThread(SectionId, SectionData);
		}
	);
}
Beispiel #4
0
// Called when the game starts
void UOpenCVComponent::BeginPlay()
{
	Super::BeginPlay();

	// ...
	
	if (nullptr != Texture2D)
	{
		if (cv::ocl::haveOpenCL())
		{
			cv::ocl::Context Context;
			if (Context.create(cv::ocl::Device::TYPE_GPU))
			{
				cv::ocl::Device(Context.device(0));

				//!< Simple OpenCL Code
				const cv::String Code = "__kernel void main(__global uchar* dst, const int pitch, const int offset, const int rows, const int cols) {"
					"const int2 uv = { get_global_id(0), get_global_id(1) };"
					"const int2 dim = { rows, cols };"
					"const int2 grid = { 16, 16 };"
					"const int2 repeate = dim / grid;"
					"const int index = mad24(uv.y, pitch, uv.x + offset);"
					"dst[index] = ((uv.x % grid.x) * repeate.x >> 1) + ((uv.y % grid.y) * repeate.y >> 1);"
					"}";
				const cv::ocl::ProgramSource ProgramSource(Code);

				//!< Build OpenCL
				const cv::String Buildopt = "";
				cv::String Errmsg;
				const auto Program = Context.getProg(ProgramSource, Buildopt, Errmsg);

				const auto Width = Texture2D->GetSizeX();
				const auto Height = Texture2D->GetSizeY();
				//!< Result destination
				const auto Mat = cv::UMat(Height, Width, CV_8U, cv::ACCESS_WRITE, cv::USAGE_ALLOCATE_DEVICE_MEMORY);

				//!< OpenCL function name and arguments
				cv::ocl::Kernel Kernel("main", Program);
				Kernel.args(cv::ocl::KernelArg::ReadWrite(Mat));

				//!< Execute OpenCL
				size_t Threads[] = { Width, Height, 1 };
				if (!Kernel.run(ARRAY_COUNT(Threads), Threads, nullptr, true))
				{
					GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, TEXT("OpenCL run failed"));
				}

				const auto Result = Mat.getMat(cv::ACCESS_READ);

				//!< Add some OpenCV operations
				cv::putText(Mat, cv::String("Hello OpenCV"), cv::Point(0, 255), CV_FONT_HERSHEY_PLAIN, 2.0, cv::Scalar(0, 127, 127));
				cv::rectangle(Mat, cv::Point(64 + 5, 64 + 5), cv::Point(96 + 5, 96 + 5), cv::Scalar(0, 255, 0));
				cv::circle(Mat, cv::Point(128, 128), 32, cv::Scalar(0, 0, 255));

				//cv::imshow("Result", Result);

				//!< cv::Mat -> TArray<FColor>
				Colors.Empty();
				Colors.Reserve(Width * Height);
				for (auto i = 0; i < Height; ++i)
				{
					for (auto j = 0; j < Width; ++j)
					{
						const auto Value = Result.data[i * Width + j];
						Colors.Add(FColor(Value, Value, Value));
					}
				}

				//!< Update UTexture2D
				ENQUEUE_RENDER_COMMAND(UpdateTexture2D)(
					[Tex = Texture2D, this](FRHICommandListImmediate& RHICmdList)
					{
						const auto TexWidth = Tex->GetSizeX();
						const auto TexHeight = Tex->GetSizeY();
						const auto Pitch = GPixelFormats[Tex->GetPixelFormat()].BlockBytes * TexWidth;
						RHIUpdateTexture2D(Tex->Resource->TextureRHI->GetTexture2D(), 0, FUpdateTextureRegion2D(0, 0, 0, 0, TexWidth, TexHeight), Pitch, reinterpret_cast<const uint8*>(&Colors[0]));
					});
			}
		}
	}
}
	void InitResource() override
	{
		FLocalVertexFactory* VertexFactory = this;
		const FProceduralMeshVertexBuffer* PooledVertexBuffer = VertexBuffer;
		ENQUEUE_RENDER_COMMAND(InitProceduralMeshVertexFactory)(
			[VertexFactory, PooledVertexBuffer](FRHICommandListImmediate& RHICmdList)
		{
			FDataType Data;
			Data.PositionComponent = FVertexStreamComponent(
				&PooledVertexBuffer->PositionBuffer,
				0,
				sizeof(FVector),
				VET_Float3
			);

			Data.NumTexCoords = PooledVertexBuffer->GetNumTexCoords();

			{
				Data.LightMapCoordinateIndex = PooledVertexBuffer->GetLightmapCoordinateIndex();
				Data.TangentsSRV = PooledVertexBuffer->TangentBufferSRV;
				Data.TextureCoordinatesSRV = PooledVertexBuffer->TexCoordBufferSRV;
				Data.ColorComponentsSRV = PooledVertexBuffer->ColorBufferSRV;
				Data.PositionComponentSRV = PooledVertexBuffer->PositionBufferSRV;
			}

			{
				EVertexElementType UVDoubleWideVertexElementType = VET_None;
				EVertexElementType UVVertexElementType = VET_None;
				uint32 UVSizeInBytes = 0;
				if (PooledVertexBuffer->GetUse16bitTexCoords())
				{
					UVSizeInBytes = sizeof(FVector2DHalf);
					UVDoubleWideVertexElementType = VET_Half4;
					UVVertexElementType = VET_Half2;
				}
				else
				{
					UVSizeInBytes = sizeof(FVector2D);
					UVDoubleWideVertexElementType = VET_Float4;
					UVVertexElementType = VET_Float2;
				}

				int32 UVIndex;
				uint32 UvStride = UVSizeInBytes * PooledVertexBuffer->GetNumTexCoords();
				for (UVIndex = 0; UVIndex < (int32)PooledVertexBuffer->GetNumTexCoords() - 1; UVIndex += 2)
				{
					Data.TextureCoordinates.Add
					(
						FVertexStreamComponent(
							&PooledVertexBuffer->TexCoordBuffer,
							UVSizeInBytes * UVIndex,
							UvStride,
							UVDoubleWideVertexElementType,
							EVertexStreamUsage::ManualFetch
						)
					);
				}

				// possible last UV channel if we have an odd number
				if (UVIndex < (int32)PooledVertexBuffer->GetNumTexCoords())
				{
					Data.TextureCoordinates.Add(FVertexStreamComponent(
						&PooledVertexBuffer->TexCoordBuffer,
						UVSizeInBytes * UVIndex,
						UvStride,
						UVVertexElementType,
						EVertexStreamUsage::ManualFetch
					));
				}

				Data.TangentBasisComponents[0] = FVertexStreamComponent(&PooledVertexBuffer->TangentBuffer, 0, 2 * sizeof(FPackedNormal), VET_PackedNormal, EVertexStreamUsage::ManualFetch);
				Data.TangentBasisComponents[1] = FVertexStreamComponent(&PooledVertexBuffer->TangentBuffer, sizeof(FPackedNormal), 2 * sizeof(FPackedNormal), VET_PackedNormal, EVertexStreamUsage::ManualFetch);
				Data.ColorComponent = FVertexStreamComponent(&PooledVertexBuffer->ColorBuffer, 0, sizeof(FColor), VET_Color, EVertexStreamUsage::ManualFetch);
			}
			VertexFactory->SetData(Data);


		});

		if (IsInRenderingThread())
		{
			FLocalVertexFactory::InitResource();
		}
	}