Dynamic texture in C++ for actor in editor

I have an actor placed in my level statically using the editor. The actor has a material, and the material uses a simple 2048x2048 texture (default DXT1). I want to edit the texture in C++ code at run-time. The editing is infrequent - eg when the player does an action once every 1-10 seconods, I want my C++ code to edit the texels in the texture. How do I reference this actor’s material’s texture from my C++ code such that I can edit texels at run-time?

I’ve read about dynamic textures but so far I’m very confused… If this was OpenGL (or DirectX) it would be so easy, but UE4 makes it complicated. Please help.

I’d prefer C++ but Blueprints is fine too because I already know how to interface Blueprints with C++ (and vice versa).

1 Like

I figured it out after reviewing appended links. Basically I just the following.

Material editor → right click texture → convert to parameter. In main level editor, add a blueprint to my actor, then in the blueprint I did - Create dynamic material instance, call my C++ function get texture, then set texture parameter value.

To interface with my C++ function, I use the standard blueprints/C++ interface trick… Make a C++ actor that extends AStaticMeshActor. Use Class Settings to set my blueprint parent to my C++ actor. In C++ code, use UFUNCTION(BlueprintCallable…) syntax eg:

UFUNCTION(BlueprintCallable, Category = "HQ Game Board") UTexture2D* GetMyTexture(UTexture2D* tex);

Then in my actor blueprint, I can call Get My Texture. Then back inside my C++ code, I do the following:

UTexture2D* ABoardActor::GetBoardTexture(UTexture2D* tex)
{
	FTexture2DMipMap& Mip = tex->PlatformData->Mips[0];
	FColor* FormatedImageData = static_cast(Mip.BulkData.Lock(LOCK_READ_ONLY));

	uint8 PixelX = 5, PixelY = 10;
	uint32 width = Mip.SizeX;
	uint32 height = Mip.SizeY;
	for (int y = 0; y < Mip.SizeY / 2; ++y)
	{
		for (int x = 0; x < Mip.SizeX / 2; ++x)
		{
			//TODO: if (InBoardFog)
			//FColor pixColor = *FormatedImageData[y * TextureWidth + x];
			//pixColor.R /= 4;
			//pixColor.G /= 4;
			//pixColor.B /= 4;
			//FormatedImageData[y * TextureWidth + x] = pixColor;
			FColor pixColor(0, 0, 0);
			pixColor.R = FormatedImageData[y * width + x].R / 4;
			pixColor.G = FormatedImageData[y * width + x].G / 4;
			pixColor.B = FormatedImageData[y * width + x].B / 4;
			FormatedImageData[y * width + x] = FColor(0, 0, 0); // crash
			//FormatedImageData[y * width + x].R = pixColor.R;
			//FormatedImageData[y * width + x].G = pixColor.G;
			//FormatedImageData[y * width + x].B = pixColor.B;
		}
	}

	Mip.BulkData.Unlock();
	tex->UpdateResource();
	return tex;
}

References:

Update: When I run this, is crashing without giving an error message and I don’t know why. It crashes in the above code snippet on the line labeled “// crash”. It doesn’t crash with some textures but it does with the one I want to use.

Update 2: After some experiments, I found the reason it crashes is because my texture has mip maps… Though I don’t know why this causes the crash. I of course want mip maps…

Update 3: It works on Windows and OS X, but not on Android. It doesn’t crash, but the texture fails to dynamically update on Android.