diff --git a/Mods/TestMod/Content/RealTestSlider.uasset b/Mods/TestMod/Content/RealTestSlider.uasset new file mode 100644 index 0000000000..a3ac577fa4 Binary files /dev/null and b/Mods/TestMod/Content/RealTestSlider.uasset differ diff --git a/Mods/TestMod/Content/RootInstance_TestMod.uasset b/Mods/TestMod/Content/RootInstance_TestMod.uasset index 3442a304f2..340ad7f2ea 100644 Binary files a/Mods/TestMod/Content/RootInstance_TestMod.uasset and b/Mods/TestMod/Content/RootInstance_TestMod.uasset differ diff --git a/Mods/TestMod/Content/TestAddedWidget.uasset b/Mods/TestMod/Content/TestAddedWidget.uasset index 30d25927cd..e2fd5acc46 100644 Binary files a/Mods/TestMod/Content/TestAddedWidget.uasset and b/Mods/TestMod/Content/TestAddedWidget.uasset differ diff --git a/Mods/TestMod/Content/grid.uasset b/Mods/TestMod/Content/grid.uasset new file mode 100644 index 0000000000..1d52186bb0 Binary files /dev/null and b/Mods/TestMod/Content/grid.uasset differ diff --git a/Mods/TestMod/Content/out.uasset b/Mods/TestMod/Content/out.uasset deleted file mode 100644 index caf7210552..0000000000 Binary files a/Mods/TestMod/Content/out.uasset and /dev/null differ diff --git a/Mods/TestMod/Source/TestMod/Private/MyGameInstanceSubsystem.cpp b/Mods/TestMod/Source/TestMod/Private/MyGameInstanceSubsystem.cpp new file mode 100644 index 0000000000..11360ac15f --- /dev/null +++ b/Mods/TestMod/Source/TestMod/Private/MyGameInstanceSubsystem.cpp @@ -0,0 +1,118 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "MyGameInstanceSubsystem.h" + +#include "RHICommandList.h" +#include "Rendering/Texture2DResource.h" + + +void UMyGameInstanceSubsystem::Initialize(FSubsystemCollectionBase& Collection) +{ + Super::Initialize(Collection); + + TextureTotalPixels = TextureSideSize * TextureSideSize; + + // Get Total Bytes of Texture - Each pixel has 4 bytes for RGBA + TextureDataSize = TextureTotalPixels * 4; + TextureDataSqrtSize = TextureSideSize * 4; + + // Initialize Texture Data Array + TextureData = new uint8[TextureDataSize]; + + DynamicTexture = UTexture2D::CreateTransient(TextureSideSize, TextureSideSize, EPixelFormat::PF_R8G8B8A8, "DynamicTexture"); + DynamicTexture->CompressionSettings = TextureCompressionSettings::TC_EditorIcon; + DynamicTexture->Filter = TextureFilter::TF_Default; + DynamicTexture->SRGB = 0; + DynamicTexture->AddToRoot(); + DynamicTexture->UpdateResource(); + + TextureRegion = FUpdateTextureRegion2D{ 0, 0, 0, 0, TextureSideSize, TextureSideSize }; +} + + +void UMyGameInstanceSubsystem::Deinitialize() +{ + Super::Deinitialize(); + + DynamicTexture = nullptr; + delete[] TextureData; +} + + +void UMyGameInstanceSubsystem::UpdateTexture() +{ + struct FUpdateTextureRegionsData + { + FTexture2DResource* Texture2DResource; + FRHITexture2D* TextureRHI; + int32 MipIndex; + uint32 NumRegions; + FUpdateTextureRegion2D* Regions; + uint32 SrcPitch; + uint32 SrcBpp; + uint8* SrcData; + }; + + FTexture2DResource* Resource = static_cast(DynamicTexture->GetResource()); + + FUpdateTextureRegionsData RegionData{ + Resource, + Resource->GetTexture2DRHI(), + 0, + 1, + &TextureRegion, + TextureDataSqrtSize, + 4, + TextureData, + }; + + ENQUEUE_RENDER_COMMAND(UpdateTextureRegionsData)( + [RegionData, Texture = DynamicTexture](FRHICommandListImmediate& RHICmdList) + { + for (uint32 RegionIndex = 0; RegionIndex < RegionData.NumRegions; ++RegionIndex) + { + int32 CurrentFirstMip = Texture->FirstResourceMemMip; + if (RegionData.TextureRHI && RegionData.MipIndex >= CurrentFirstMip) + { + RHIUpdateTexture2D( + RegionData.TextureRHI, + RegionData.MipIndex - CurrentFirstMip, + RegionData.Regions[RegionIndex], + RegionData.SrcPitch, + RegionData.SrcData + + RegionData.Regions[RegionIndex].SrcY * RegionData.SrcPitch + + RegionData.Regions[RegionIndex].SrcX * RegionData.SrcBpp + ); + } + } + }); +} + + +void UMyGameInstanceSubsystem::CreateGrid(int count) +{ + FMemory::Memset(TextureData, 0, TextureDataSize); + + constexpr int dotInterval = 3; + constexpr uint32 color = 0xC87F7F7F; + const int interval = TextureSideSize / count; + + auto* pixelData = reinterpret_cast(TextureData); + + for (int i = 1; i < count; ++i) + { + uint32 linePos = i * interval; + + for (uint32 offset = 0; offset < TextureSideSize; offset += dotInterval) + { + // Draw the horizontal dot (y = linePos, x = offset) + pixelData[linePos * TextureSideSize + offset] = color; + + // Draw the vertical dot (y = offset, x = linePos) + pixelData[offset * TextureSideSize + linePos] = color; + } + } + + UpdateTexture(); +} diff --git a/Mods/TestMod/Source/TestMod/Public/MyGameInstanceSubsystem.h b/Mods/TestMod/Source/TestMod/Public/MyGameInstanceSubsystem.h new file mode 100644 index 0000000000..bf7022f038 --- /dev/null +++ b/Mods/TestMod/Source/TestMod/Public/MyGameInstanceSubsystem.h @@ -0,0 +1,44 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "Subsystems/GameInstanceSubsystem.h" +#include "MyGameInstanceSubsystem.generated.h" + +/** + * + */ +UCLASS() +class TESTMOD_API UMyGameInstanceSubsystem : public UGameInstanceSubsystem +{ + GENERATED_BODY() + +public: + virtual void Initialize(FSubsystemCollectionBase& Collection) override; + virtual void Deinitialize() override; + + UFUNCTION(BlueprintCallable) + void CreateGrid(int count); + +private: + void UpdateTexture(); + + +protected: + UPROPERTY(EditDefaultsOnly) + uint32 TextureSideSize = 2048; + + UPROPERTY(BlueprintReadWrite, EditAnywhere) + UTexture2D* DynamicTexture = nullptr; + +private: + uint8* TextureData; + + uint32 TextureDataSize; + uint32 TextureDataSqrtSize; + uint32 TextureTotalPixels; + + // Update Region Struct + FUpdateTextureRegion2D TextureRegion; +}; diff --git a/Mods/TestMod/Source/TestMod/TestMod.Build.cs b/Mods/TestMod/Source/TestMod/TestMod.Build.cs index aa2401f188..16f049f7d7 100644 --- a/Mods/TestMod/Source/TestMod/TestMod.Build.cs +++ b/Mods/TestMod/Source/TestMod/TestMod.Build.cs @@ -74,8 +74,8 @@ public TestMod(ReadOnlyTargetRules Target) : base(Target) }); PrivateDependencyModuleNames.AddRange(new string[] { - // ... add private dependencies that you statically link with here ... - }); + "RHI", "RenderCore" + }); DynamicallyLoadedModuleNames.AddRange(new string[] { // ... add any modules that your module loads dynamically here ...