Unresolved external symbol UTextureRenderTarget2D::CalcTextureMemorySizeEnum

Hi guys,

I upgraded from UE5 to UE5.1 but now I have a single issue with the linker.

error LNK2001: unresolved external symbol "public: virtual unsigned int __cdecl UTextureRenderTarget2D::CalcTextureMemorySizeEnum(enum ETextureMipCount)const " (?CalcTextureMemorySizeEnum@UTextureRenderTarget2D@@UEBAIW4ETextureMipCount@@@Z)

I saw in the code that CalcTextureMemorySizeEnum is a new override in UTextureRenderTarget2D but that should be implemented in module “Engine” which I have added long time before. Where is my misconception?

Thanks.

It’s probably because I wrote a class that inherits from “UCanvasRenderTarget2D”. It still worked under UE5.

UCLASS(Blueprintable)
class XXX_API UMSCompositeTexture : public UCanvasRenderTarget2D
{
GENERATED_BODY()

It’s also unclear to me why there isn’t “UTextureRenderTarget2D::CalcTextureMemorySizeEnum” in the UE5.1 libraries. I checked there with “dumpbin”. But there is a new implementation (override) for “CalcTextureMemorySizeEnum” in the “UTextureRenderTarget2D” class.

The workaround to implement my own “CalcTextureMemorySizeEnum” works. But it’s just a workaround. I copied the implementation from “UTextureRenderTarget2D” to my “UMSCompositeTexture”.

2 Likes

Thank you, had the same issue in a custom plugin using ther RenderTarget2d, this helped me fix it quickly!

Just ran into this as well. We have a class that was inheriting from UCanvasRenderTarget2D. Worked in UE5.0, failed in UE5.1. Thanks for your updated answer!

I still have this problem, and now in Unreal 5.4 there are more methods with the same issue, (i.e. UTextureRenderTarget2D::GetTextureUClass(), UTextureRenderTarget2D::CanConvertToTexture, UTextureRenderTarget2D::GetFormat(), etc), I am needing to copy the implementation of them all to make it work.

Also the hotreload always crash with this error when inheriting UCanvasRenderTarget2D:

Tried to get the current ObjectInitializer, but none is set. Please use NewObject to construct new UObject-derived classes.

1 Like

I’m back here too, updating my code to 5.4 :joy:

Anyway, I could get my code to work again by copying large portions of engine code into my own class.

It’s actually just this:

UCLASS(Blueprintable)
class UCompositeTexture : public UCanvasRenderTarget2D

I think I’m doing something very wrong, but I couldn’t find any other solution to the linker errors.

My code is based on this old plugin: GitHub - Cyx69/TextureMergePlugin: This is a UE4 plugin for merging textures with UCanvasRenderTarget2D.

I’d be very happy to learn how to do this the right way.

We ran into the same on Unreal 5.4. Had to replicate these functions in our class that inherits from UCanvasRenderTarget2D

#if WITH_EDITOR
	virtual bool CanEditChange(const FProperty* InProperty) const override;
	virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
#endif
	virtual bool CanConvertToTexture(ETextureSourceFormat& OutTextureSourceFormat, EPixelFormat& OutPixelFormat, FText* OutErrorMessage) const override;
	virtual TSubclassOf<UTexture> GetTextureUClass() const override;
	virtual EPixelFormat GetFormat() const override;
	virtual bool IsSRGB() const override;
	virtual float GetDisplayGamma() const override;

Also running into this issue with two UCanvasRenderTarget2D subclasses while trying to migrate from UE 5.3.2 to UE 5.4.0. Are there any solutions to this and/or found the root cause of the issue that its happening in 5.4 and not 5.3 etc?

I tried copying the implementation of CanEditChange and PostEditChangeProperty just to test but am still seeing the unresolved symbol errors for those methods.
Thanks for any pointers in advance…

@RickGavin chec if these changes I had to make can help you:

build.cs:
added RenderCore to my PrivateDependenyModulesNames
added

         PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
         PrecompileForTargets = PrecompileTargetsType.Any;

Header missing includes added:

 #include "Engine/Texture.h"
 #include "Engine/Texture2D.h"
 #include "ImageUtils.h"

Header overrides added:


	// Workaround for UE5 5.1 START
	// https://forums.unrealengine.com/t/unresolved-external-symbol-utexturerendertarget2d-calctexturememorysizeenum/734482
	//copy implementation from UE_5.1\Engine\Source\Runtime\Engine\Classes\Engine\TextureRenderTarget2D.h
	virtual uint32 CalcTextureMemorySizeEnum(ETextureMipCount Enum) const override;
	// Workaround END

	// Workaround 5.4 START

	virtual bool CanConvertToTexture(ETextureSourceFormat& OutTextureSourceFormat, EPixelFormat& OutPixelFormat, FText* OutErrorMessage) const override;
	virtual TSubclassOf<UTexture> GetTextureUClass() const override;
	virtual EPixelFormat GetFormat() const override;
	virtual bool IsSRGB() const override;
	virtual float GetDisplayGamma() const override;


	static float GetDefaultDisplayGamma();

#if WITH_EDITOR
	virtual bool CanEditChange(const FProperty* InProperty) const override;
	virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
#endif // WITH_EDITOR

protected:
	ETextureSourceFormat ValidateTextureFormatForConversionToTextureInternal(EPixelFormat InFormat, const TArrayView<const EPixelFormat>& InCompatibleFormats, FText* OutErrorMessage) const;

	void OnSampleCountChanged();
	static ETextureSourceFormat ConvertToTextureSourceFormat(ERawImageFormat::Type Format);
	static ERawImageFormat::Type GetRawImageFormatForPixelFormat(EPixelFormat PF);
	// Workaround 5.4 END

Hope you can track down your missing parts.

Anyway, if someone with better C++ knowledge could chime in and tell me how to properly override this class, that’d be great.

thanks @Ben_Cykyria I tried the changes you mentioned but it did not fix the unresolved external symbol errors for me unfortunately. I do use a tweaked engine, so I did workaround the issue by adding the ENGINE_API prefix to those methods. However, I do not yet know why I need to do that if others do not.

So for example, the symbol error related to TextureRenderTarget2D::CanCovertToTexture(…), that method is an override from a base class. When you look at the same method declared in various classes up the chain, they all have the ENGINE_API prefix which exports the symbol. It is missing in TextureRenderTarget2D. Why the offending methods in TextureRenderTarget2D and CanvasRenderTarget2D do not have the ENGINE_API prefix like their parent classes do I do not know but seems like the general cause of the issue.

If others are not having the same problem, then I’ll have to assume that maybe my VisualStudio toolchain is out of date and a newer version can correctly traverse the symbol tree possibly? If anyone has any ideas on the matter.

I’m considering moving all my logic from C++ to the new (experimental) TextureGraph plugin. This might be an option for other people in this thread, too.

There doesn’t seem to be any official documentation yet. There are some tutorials on Youtube already, though.

edit: be aware that the TextureGraph plugin will not build for shipping in 5.4. You could work around it by modifying the plugin and remove editor dependencies, though. It’s still experimental after all.