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;
}