How to Render a canvas to a high-resolution texture?
Hi!
One of our GUI draws vector graphics on a canvas. We want to provde an "export to file" functionality to the user, is there an easy way to do it? Note that the exported texture usually have much higher resolution for printing, so I can't just dump the content of the current render window.
In WPF we can create a RenderTargetBitmap rtb and use rtb.Render(canvas) to render the canvas into the bitmap and save it to file, but in Noesis GUI I can't find a similar way to do it. Do I need to implement it on my own? If so, can anyone show me (roughly) how to do it?
BTW: I'm using Noesis GUI 2.0 and the functionality only needs to support D3D11.
Thanks!
One of our GUI draws vector graphics on a canvas. We want to provde an "export to file" functionality to the user, is there an easy way to do it? Note that the exported texture usually have much higher resolution for printing, so I can't just dump the content of the current render window.
In WPF we can create a RenderTargetBitmap rtb and use rtb.Render(canvas) to render the canvas into the bitmap and save it to file, but in Noesis GUI I can't find a similar way to do it. Do I need to implement it on my own? If so, can anyone show me (roughly) how to do it?
BTW: I'm using Noesis GUI 2.0 and the functionality only needs to support D3D11.
Thanks!
Re: How to Render a canvas to a high-resolution texture?
I've managed to get high-res (8K, iPhone/iPad retina) screenshots from Unity Editor, see here: viewtopic.php?f=3&t=1048
Had to do a couple workarounds. In the code in the above post, I have some commented out code that renders to texture.
Unfortunately the render-to-texture commented out code crashes. I'm going to play with it and report a bug if I can't get it to work.
If you manage to get it to work please let us know!
Had to do a couple workarounds. In the code in the above post, I have some commented out code that renders to texture.
Unfortunately the render-to-texture commented out code crashes. I'm going to play with it and report a bug if I can't get it to work.
If you manage to get it to work please let us know!
Re: How to Render a canvas to a high-resolution texture?
You could also have a look at NoesisXamlEditor.cs where we have all the code to generate previews and thumbnail. That code is rendering UI into textures.
Re: How to Render a canvas to a high-resolution texture?
Thanks for the info!
Re: How to Render a canvas to a high-resolution texture?
Thanks, but I don't use Unity. I use Ogre with C++, so it should be quite different (and sorry, I didn't even find NoesisXamlEditor.cs in the SDK)You could also have a look at NoesisXamlEditor.cs where we have all the code to generate previews and thumbnail. That code is rendering UI into textures.
I managed to make screen capture working as follows:
Code: Select all
void renderToTargetDX11(FrameworkElement* element, ID3D11RenderTargetView* rt) {
if(rt) g_pImmediateContext->OMSetRenderTargets(1, &rt, g_pDepthStencilView);
if (element != NULL){
IView* view = element->GetView();
view->GetRenderer()->Render();
}
}
void captureScreen(Noesis::Gui::FrameworkElement* element) {
...
ID3D11Texture2D* rtt_d3d;
ID3D11RenderTargetView* renderTargetView;
// get rtt_d3d/renderTargetView with Ogre, code omitted
renderToTargetDX11(element, renderTargetView);
// write rtt_d3d to a file, code omitted
}
Code: Select all
int paperWidth = 3507; // 300 dpi A4 paper
int paperHeight = 2480;
Noesis::Gui::FrameworkElement* element = static_cast<Noesis::Gui::FrameworkElement*>(canvas);
if (element != NULL){
canvas->setWidth(paperWidth);
canvas->setHeight(paperHeight);
// and clear canvas's children and recreate new ones, code ommited
Noesis::IView* view = element->GetView();
view->Update(0);
view->GetRenderer()->UpdateRenderTree();
if (view->GetRenderer()->NeedsOffscreen()) {
view->GetRenderer()->RenderOffscreen(); // didn't arrive here, though
}
}
ID3D11Texture2D* rtt_d3d;
ID3D11RenderTargetView* renderTargetView;
// get rtt_d3d/renderTargetView with Ogre, code omitted
renderToTargetDX11(element, renderTargetView);
// write rtt_d3d to a file, code omitted
// restore canvas
canvas->setWidth(backupWidth);
canvas->setHeight(backupHeight);
I also tried some other things:
Code: Select all
view->SetSize(paperWidth, paperHeight); // doesn't work, have STRANGE effect
element->UpdateLayout(); // nothing's different
view->GetRenderer()->SetRenderRegion(0, 0, paperWidth, paperHeight);// doesn'twork for large area, but works if paperWidth/paperHeight are smaller than the main window
Re: How to Render a canvas to a high-resolution texture?
Does it work when you resize to a lower resolution?
Peter Verswyvelen,
Strongly Typed Solutions
Strongly Typed Solutions
Re: How to Render a canvas to a high-resolution texture?
Good question! Unfortunately, no (I didn't try until you asked this). Now I feels that I'm misunderstanding something (I'm a novice). Now I'm doing this:Does it work when you resize to a lower resolution?
Code: Select all
// first, create a BRAND NEW canvas, set the widht/height to paperWidth and paperHeight, draw everything in (0-paperWidth-1) x (0-paperHeight-)
Noesis::Ptr<Noesis::IView> view = Noesis::GUI::CreateView(canvas);
view->GetRenderer()->Init(g_context.GetPtr());
view->SetSize(paperWidth, paperHeight);
view->Update(0);
view->GetRenderer()->UpdateRenderTree();
if (view->GetRenderer()->NeedsOffscreen()) {
view->GetRenderer()->RenderOffscreen();
}
// create Texture/RenderTargetView with Ogre, as before
renderToTargetDX11(canvas, renderTargetView);
// dump the content of the texture to file, with Ogre
I'm quite confused. Any suggestion would be welcome. Thanks!
-
sfernandez
Site Admin
- Posts: 3005
- Joined:
Re: How to Render a canvas to a high-resolution texture?
In C++ you should be able to render to a high-res texture by doing the following:
It shouldn't be necessary to create a new Noesis::IView to do the screenshot.
Code: Select all
noesisView->SetSize(bigWidth, bigHeight);
noesisView->Update(currentTimeInSecs);
Noesis::IRenderer* noesisRenderer = view->GetRenderer();
noesisRenderer->UpdateRenderTree();
if (noesisRenderer->NeedsOffscreen())
noesisRenderer->RenderOffscreen();
// Set texture render target
// Set render target viewport
// Clear render target
// Render other parts of the scene
noesisRenderer->Render();
// Copy texture content to a file
// Restore noesisView size
Re: How to Render a canvas to a high-resolution texture?
We've finally fixed the problem. All the methods posted here (including my own) are conceptually correct, but when it comes to implementation details, the real problem is that we forgot to call RSSetViewports() after changing render target, so D3D11 is still using the old viewport, thus restricted to the current window size. I'm posting the complete working snippet in case anyone needs it:
Thank you all!
Code: Select all
void setRenderTargetDX11(ID3D11RenderTargetView* rt) {
if (rt)
g_pImmediateContext->OMSetRenderTargets(1, &rt, g_pDepthStencilView);
}
void renderToTargetDX11(FrameworkElement* element, ID3D11RenderTargetView* rt) {
setRenderTargetDX11((ID3D11RenderTargetView*)rt);
if (element != NULL){
D3D11_VIEWPORT vp = { 0.0f, 0.0f, (FLOAT)element->GetWidth(), (FLOAT)element->GetHeight(), 0.0f, 1.0f };
g_pImmediateContext->RSSetViewports(1, &vp); // don't forget this!
IView* view = element->GetView();
view->GetRenderer()->Render();
}
}
-
sfernandez
Site Admin
- Posts: 3005
- Joined:
Re: How to Render a canvas to a high-resolution texture?
Thanks for sharing
Who is online
Users browsing this forum: Semrush [Bot] and 4 guests