Render to Texture bug in linux in fullscreen

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
Post Reply
Noiecity
Posts: 317
Joined: Wed Aug 23, 2023 7:22 pm
Contact:

Render to Texture bug in linux in fullscreen

Post by Noiecity »

I was testing some calculations that estimated that in Irrlicht, a FOV equivalent to the calculations of some measurements I made by measuring the size of objects with a ruler from a distance (similar to measuring the size of the sun with a ruler, a few centimeters from your perspective), the FOV in Irrlicht would be 90.0f* core::DEGTORAD.

Well, the thing is, while I was testing that in a render to texture, I realized that I can't close or exit the application in fullscreen when I'm on Linux (I haven't tried it on Windows). I had to shutdown the PC the first time to exit, the second time I opened it again without realizing it, but I remembered that htop allows you to close processes... I closed it from the terminal that opens when you press ctrl + alt + f1, however I can't switch tabs where the Irrlicht application with the problem is displayed. In fact, after closing the process, I came here to write the post.


It may not be render to texture, I don't know, but here's the code with the problem:

Code: Select all

#include <irrlicht.h>

using namespace irr;

#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif

// Window configuration
const u32 WINDOW_WIDTH = 800;
const u32 WINDOW_HEIGHT = 600;

// Render texture configuration
const u32 RENDER_WIDTH = 512;   // Render texture width
const u32 RENDER_HEIGHT = 512;  // Render texture height

class RenderTextureManager {
private:
    IrrlichtDevice* device;
    video::IVideoDriver* driver;
    video::ITexture* renderTexture;
    u32 renderWidth;
    u32 renderHeight;
    f32 aspectRatio;

public:
    RenderTextureManager(IrrlichtDevice* dev, u32 width, u32 height)
        : device(dev), renderWidth(width), renderHeight(height) {
        driver = device->getVideoDriver();

        // Calculate aspect ratio
        aspectRatio = (f32)renderWidth / (f32)renderHeight;

        // Create render texture with specified size
        renderTexture = driver->addRenderTargetTexture(
            core::dimension2d<u32>(renderWidth, renderHeight), "RTT");
    }

    ~RenderTextureManager() {
        if (renderTexture) {
            driver->removeTexture(renderTexture);
        }
    }

    void beginRenderToTexture(const video::SColor& clearColor = video::SColor(255, 100, 101, 140)) {
        driver->setRenderTarget(renderTexture, true, true, clearColor);

        // IMPORTANT: Configure viewport to match render texture
        driver->setViewPort(core::rect<s32>(0, 0, renderWidth, renderHeight));
    }

    void endRenderToTexture() {
        driver->setRenderTarget(0); // Return to rendering to main screen

        // Restore full screen viewport
        core::dimension2d<u32> screenSize = driver->getScreenSize();
        driver->setViewPort(core::rect<s32>(0, 0, screenSize.Width, screenSize.Height));
    }

    void drawToScreen() {
        core::dimension2d<u32> screenSize = driver->getScreenSize();

        // Calculate destination size maintaining aspect ratio
        u32 destHeight = screenSize.Height;
        u32 destWidth = (u32)(destHeight * aspectRatio);

        // If calculated width is greater than screen width, adjust by width
        if (destWidth > screenSize.Width) {
            destWidth = screenSize.Width;
            destHeight = (u32)(destWidth / aspectRatio);
        }

        // Calculate position to center
        s32 destX = (screenSize.Width - destWidth) / 2;
        s32 destY = (screenSize.Height - destHeight) / 2;

        // Draw rendered texture to screen
        driver->draw2DImage(renderTexture,
                           core::rect<s32>(destX, destY, destX + destWidth, destY + destHeight),
                           core::rect<s32>(0, 0, renderWidth, renderHeight),
                           0, 0, true);

        // Draw drawing area borders
        driver->draw2DRectangleOutline(core::rect<s32>(destX, destY, destX + destWidth, destY + destHeight),
                                      video::SColor(255, 255, 0, 0));
    }

    u32 getRenderWidth() const { return renderWidth; }
    u32 getRenderHeight() const { return renderHeight; }
    f32 getAspectRatio() const { return aspectRatio; }
    video::ITexture* getRenderTexture() const { return renderTexture; }

    // Method to change render texture resolution at runtime
    void setRenderSize(u32 width, u32 height) {
        if (renderTexture) {
            driver->removeTexture(renderTexture);
        }

        renderWidth = width;
        renderHeight = height;
        aspectRatio = (f32)width / (f32)height;

        renderTexture = driver->addRenderTargetTexture(
            core::dimension2d<u32>(width, height), "RTT");
    }
};

int main() {
    // Create Irrlicht device
    IrrlichtDevice* device = createDevice(video::EDT_OPENGL,
                                        core::dimension2d<u32>(WINDOW_WIDTH, WINDOW_HEIGHT),
                                        16, true, false, false, 0);

    if (!device) return 1;

    video::IVideoDriver* driver = device->getVideoDriver();
    scene::ISceneManager* smgr = device->getSceneManager();
    gui::IGUIEnvironment* guienv = device->getGUIEnvironment();

    // Create render texture manager with configurable dimensions
    RenderTextureManager rtManager(device, RENDER_WIDTH, RENDER_HEIGHT);

    // Create camera with CORRECT aspect ratio of render texture
    scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS();
    camera->setPosition(core::vector3df(0, 0, -80));

    // CRITICAL CORRECTION: Use render texture aspect ratio
    camera->setAspectRatio(rtManager.getAspectRatio());

    // Also adjust field of view if necessary
    camera->setFOV(90.0f * core::DEGTORAD);

    // Create some test objects
    scene::IAnimatedMesh* mesh = smgr->getMesh("../../media/sydney.md2");
    if (mesh) {
        scene::IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode(mesh);
        if (node) {
            node->setMaterialFlag(video::EMF_LIGHTING, false);
            node->setMD2Animation(scene::EMAT_STAND);
            node->setMaterialTexture(0, driver->getTexture("../../media/sydney.bmp"));
            node->setPosition(core::vector3df(-20, 0, 0));
        }
    }

    // Add test cubes
    scene::ISceneNode* cube1 = smgr->addCubeSceneNode(15);
    if (cube1) {
        cube1->setPosition(core::vector3df(20, 0, 0));
        cube1->setMaterialFlag(video::EMF_LIGHTING, false);
        cube1->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));
    }

    scene::ISceneNode* cube2 = smgr->addCubeSceneNode(10);
    if (cube2) {
        cube2->setPosition(core::vector3df(0, 15, 0));
        cube2->setMaterialFlag(video::EMF_LIGHTING, false);
        cube2->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));
    }

    // Add informational text
    gui::IGUIFont* font = guienv->getBuiltInFont();
    core::stringw infoText;

    device->setWindowCaption(L"Render to Texture Configurable - Dynamic Aspect Ratio");

    // Main loop
    while (device->run()) {
        if (device->isWindowActive()) {
            // UPDATE CAMERA ASPECT RATIO EACH FRAME
            // (important if render texture size changes)
            camera->setAspectRatio(rtManager.getAspectRatio());

            // 1. Render scene to texture
            rtManager.beginRenderToTexture();
            smgr->drawAll();
            rtManager.endRenderToTexture();

            // 2. Clear main screen
            driver->beginScene(true, true, video::SColor(255, 0, 0, 0));

            // 3. Draw rendered texture to screen
            rtManager.drawToScreen();

            // Get screen size
            core::dimension2d<u32> screenSize = driver->getScreenSize();

            // Calculate destination dimensions to show in info
            u32 destHeight = screenSize.Height;
            u32 destWidth = (u32)(destHeight * rtManager.getAspectRatio());

            // Update informational text
            infoText = L"Render Texture: ";
            infoText += rtManager.getRenderWidth();
            infoText += L"x";
            infoText += rtManager.getRenderHeight();
            infoText += L"\nAspect Ratio: ";
            infoText += rtManager.getAspectRatio();
            infoText += L"\nScaled to: ";
            infoText += destWidth;
            infoText += L"x";
            infoText += destHeight;
            infoText += L"\nScreen: ";
            infoText += screenSize.Width;
            infoText += L" x ";
            infoText += screenSize.Height;

            // Draw information
            font->draw(infoText.c_str(),
                      core::rect<s32>(10, 10, 500, 130),
                      video::SColor(255, 255, 255, 255));

            driver->endScene();
        }
    }

    device->drop();
    return 0;
}
**
If you are looking for people with whom to develop your game, even to try functionalities, I can help you, for free. CC0 man.

Image
**
n00bc0de
Posts: 118
Joined: Tue Oct 04, 2022 1:21 am

Re: Render to Texture bug in linux in fullscreen

Post by n00bc0de »

It could be that Irrlicht sets an actual fullscreen mode where it changes the display resolution and that could cause issues with the compositor. I haven't had any issues with fullscreen on linux but I use SDL2 to open the window and use the SDL_WINDOW_FULLSCREEN_DESKTOP flag to set a fake fullscreen mode. Maybe you could try that and see if you still get that bug.
CuteAlien
Admin
Posts: 9928
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Render to Texture bug in linux in fullscreen

Post by CuteAlien »

Will test later when I'm back on Linux. But you can usually leave with alt+f4 (knowledge which is admittably more and more lost these days)
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Noiecity
Posts: 317
Joined: Wed Aug 23, 2023 7:22 pm
Contact:

Re: Render to Texture bug in linux in fullscreen

Post by Noiecity »

CuteAlien wrote: Sun Nov 09, 2025 1:16 pm Will test later when I'm back on Linux. But you can usually leave with alt+f4 (knowledge which is admittably more and more lost these days)
I wrote the post precisely because Alt + F4 wasn't working, and I couldn't switch windows either(this only happens if I use render to texture; by default, there are no problems.)
Last edited by Noiecity on Sun Nov 09, 2025 2:22 pm, edited 1 time in total.
**
If you are looking for people with whom to develop your game, even to try functionalities, I can help you, for free. CC0 man.

Image
**
Noiecity
Posts: 317
Joined: Wed Aug 23, 2023 7:22 pm
Contact:

Re: Render to Texture bug in linux in fullscreen

Post by Noiecity »

n00bc0de wrote: Sun Nov 09, 2025 6:54 am It could be that Irrlicht sets an actual fullscreen mode where it changes the display resolution and that could cause issues with the compositor. I haven't had any issues with fullscreen on linux but I use SDL2 to open the window and use the SDL_WINDOW_FULLSCREEN_DESKTOP flag to set a fake fullscreen mode. Maybe you could try that and see if you still get that bug.
It could be the resolution change. It had a resolution of 1024x768 and changed to 800x600... I play CS 1.6, where Valve did the port using SDL2 for linux. It supports software rendering and works well, but it's slow compared to Irrlicht... (It's very fast, but not as fast as Irrlicht by default. I could be wrong... since I know irrlicht supports sdl2, and I've seen some lines of code in the source where it appears, but I'm ignorant about it)
**
If you are looking for people with whom to develop your game, even to try functionalities, I can help you, for free. CC0 man.

Image
**
CuteAlien
Admin
Posts: 9928
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Render to Texture bug in linux in fullscreen

Post by CuteAlien »

Yeah, crashes the system and the desktop is still messed up after reboot *sigh*
Thanks for reporting. Thought I suppose the real solution is - do not change resolutions anymore to get games run fullscreen with another solution than what the desktop has.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
CuteAlien
Admin
Posts: 9928
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Render to Texture bug in linux in fullscreen

Post by CuteAlien »

So yeah - Alt+F4 not working in fullscreen either on my system. So needs a small event-receiver like this at minimum:

Code: Select all

class MyEventReceiver : public IEventReceiver
{
public:
	MyEventReceiver() : Quit(false) {}

	virtual bool OnEvent(const SEvent& event)
	{
		if (event.EventType == EET_KEY_INPUT_EVENT)
		{
			if ( event.KeyInput.Key == KEY_ESCAPE )
				Quit = true;
		}

		return false;
	}

	bool Quit;
};
And use that one in the main loop like:

Code: Select all

while (!events.Quit && device->run()) {
Turns out it didn't crash here at all - it just wasn't working and there was no key to leave.
It will work if the resolution of your window is the same as the current one of the desktop. There is some way to get that from Irrlicht by creating a nulldevice first and then using getVideoModeList()->getDesktopResolution (). You are already doing the correct thing by rendering to a texture and decide the resolution in the game that way.

I think just switching fullscreen resolutions is probably no longer supported by modern desktop managers. And if I had more energy left I'd rewrite Irrlicht to replace that, but as I don't I won't (for now - I still hope I'll get over my slump again some day).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Noiecity
Posts: 317
Joined: Wed Aug 23, 2023 7:22 pm
Contact:

Re: Render to Texture bug in linux in fullscreen

Post by Noiecity »

CuteAlien wrote: Sun Nov 09, 2025 8:39 pm So yeah - Alt+F4 not working in fullscreen either on my system. So needs a small event-receiver like this at minimum:

Code: Select all

class MyEventReceiver : public IEventReceiver
{
public:
	MyEventReceiver() : Quit(false) {}

	virtual bool OnEvent(const SEvent& event)
	{
		if (event.EventType == EET_KEY_INPUT_EVENT)
		{
			if ( event.KeyInput.Key == KEY_ESCAPE )
				Quit = true;
		}

		return false;
	}

	bool Quit;
};
And use that one in the main loop like:

Code: Select all

while (!events.Quit && device->run()) {
Turns out it didn't crash here at all - it just wasn't working and there was no key to leave.
It will work if the resolution of your window is the same as the current one of the desktop. There is some way to get that from Irrlicht by creating a nulldevice first and then using getVideoModeList()->getDesktopResolution (). You are already doing the correct thing by rendering to a texture and decide the resolution in the game that way.

I think just switching fullscreen resolutions is probably no longer supported by modern desktop managers. And if I had more energy left I'd rewrite Irrlicht to replace that, but as I don't I won't (for now - I still hope I'll get over my slump again some day).
Thank you, what you did is also a valid solution for me
**
If you are looking for people with whom to develop your game, even to try functionalities, I can help you, for free. CC0 man.

Image
**
Post Reply