Why does my off screen rendering Canvas3D not work? - java

I've been trying to make off screen rendering to work, using Java3D 1.5.2. In my source code I've been trying to attach an extended Canvas3D that will do off-screen rendering to SimpleUniverse, but doing so will break the render:
62. // FOR SOME REASON THIS BREAKS RENDERING
63. universe.getViewer().getView().addCanvas3D(canvas);
The full source code is a bit too large to paste on StackOverflow so I made it available via Pastie over here.
Line 63 has been commented out and has the ordinary Canvas3D do on-screen rendering. It will render a cube and display this in a JFrame. However if you remove the comment the off-screen render will cause the on-screen one from not rendering. Also the off-screen rendering will return a "big black nothing" BufferedImage.
I'd like to know how to make the off screen rendering work, i.e. render the scene of a rotated cube to a buffered image. I've been looking at the Java3D provided example code for off-screen rendering and they do it as this as well (with the exception that they use the Raster object to render the off screen buffer back to an on-screen window).

It might be the physical dimension of the Screen3D that is wrong. The value is supposed to be size of the physical screen in meters. You can test with:
screen3D.setPhysicalScreenWidth(0.0254/90.0 * destWidth);
screen3D.setPhysicalScreenHeight(0.0254/90.0 * destHeight);
The values are from the top of the Screen3D javadoc. The problematic line worked together with the above code, at least for me :)
Setting the wrong physical dimension may also change the aspect ratio of the rendered image.

Related

Change initial background color in libgdx without glClearColor?

is it possible to change the default background color in libgdx. i want to change the background color from black to whatever color i desire, and not clear the screen. i am using ShapeRenderer to create a rectangle that is filled. i then have that rectangle move around the screen and i want to keep the previously rendered rectangle.
using Gdx.gl.glClearColor() and Gdx.gl.glClear() obviously re-renders the background color over top the previous, clearing the previously rendered rectangle.
if i dont use the Gdx.gl.glClearColor() and Gdx.gl.glClear() the background is black and the rectangle rendering and movement is what i want, other then the fact that the default background color is black. witch is not the desired look i need.
The frame buffer has no concept of what is background and not. If you are working exclusively with the screen's frame buffer, the only way to change the color is to clear the screen and redraw everything. So in your case you would need to store the steps you used to render everything the first time and replay those steps after clearing the screen.
What might be easier would be to use a separate frame buffer for all the content of your scene, and draw that over the background. This would require a frame buffer with an alpha component, and you would need to use blendFuncSeparate when rendering so alpha is preserved in this frame buffer so it can be drawn over the background. You would use a transparent clear color within the frame buffer, and whatever color you want on the main frame buffer.
libGDX FrameBuffers are a big topic and too much to explain here. You should start with the documentation, and if you start implementing it and have issues you can create a new question.

How to draw with SpriteBatch NOT directly to the screen but a Pixmap?

I'm currently working on a game that is based on a window system (like the Windows (OS) Explorer).
For the sake of performance i only draw a window with all of it's components when it is dirty (with changes that has to be rendered). When drawing a "dirty" window the rendered image is stored in a Pixmap. So, next time the window is rendered, the Pixmap is drawn. Imagine it like rendering only a screenshot of the window. This actually causes a more stable framerate.
But here's my problem:
When the window background is transparent and something in the background changes, these changes are overlapped by the saved Pixmap (screenshot) of the transparent window.
My current solution to this is clearing the background before rendering into the Pixmap. But when I do so all of what's in the background get's flashed away for a frame. Then I tried to save a screenshot of everything drawn so far (background), then draw the transparent window, save it in the Pixmap, draw the background again and the clean Pixmap above it. As you can image this consumes too much rendering time and causes framedrops of over 50% on 1080p.
The optimal solution (imho) would be to always draw a dirty window directly to the Pixmap instead of the screen. Like this it could always be drawn to an empty canvas without interferring with the background. And afterwards the Pixmap would be drawn to the screen. Instead of a Pixmap a ByteArray or anything compareable would be fine too.
I couldn't come up with a way of doing this and didn't find anything useful on google.
~Thanks

OpenGL / GLSL viewport cut after resize

I have written a display manager for LWJGL (OpenGL in Java). Everything works very well except of the 3D rendering part.
The 3D rendering part uses a FrameBuffer and a Shader. After every resize i generate a new FrameBuffer and Textures with the new size. The Shader isnt using any resolution uniforms.
The main problem part:
When I resize my window, there is only the box of the old display size visible. The 3D object is rendered normally over the whole screen except of the box.
Keep in mind, 2D rendering, after screen quad rendring, is working well.
Here are two screenshots:
Normal Window
Resized Window
Would be nice to get some hints.
Edit: RenderBuffer size hasn`t been updated... FIXED
You also need to set the viewport to the size of your window or framebuffer. (see glViewport). Initially, the viewport will be set to the size of the drawable when the context is fisrt bound to, but it will never be implicitely updated at all.
You need to resize the viewport by calling glViewport whenever the size of the window changes.
Finally found the issue: when I was resizing my FrameBuffer, I missed to update the renderbuffer size, so the renderbuffer still was 800x600 but the screen was 1300 x 900

(OpenGL) Clamping large content to smaller area

I'm using OpenGL wigh LWJGL in Java, but that's not important here. I'm not asking for code, but for a hint on how to do this. Language independent.
I have some region (a rectangle for simplicity), and, let's say, a big tiled map which I want to show in this area. The area is not the whole screen, I want to render something around it.
I know about a few approaches, but all are either huge pain or unsuitable.
Render the whole tiled map and everything else, including background and the frame,
on top - leaving the window. Yes, works, but it'd be pain.
Render only visible tiles and only the visible portions of the border tiles.
Again, doable but hard, and ie. when I use external font drawing library, I can't just tell it "Hey, stop at this line, there's my border." Not very good approach, I'd say.
Some OpenGL magic which I'm not aware of.
Guide me.
When your area is guaranteed to be an axis-aligned rectangle, you can just use glViewport and/or glScissor (the latter together with glEnable(GL_SCISSOR_TEST)) to prevent OpenGL from rendering outside that rectangle.
In case of modifying the viewport, the image resulting just is scaled to fit the viewport rectangle. Using the scissor test, the area is just "cut out", so not scaled with respect to the viewport setting. But the differences do not really even matter -you can get to the same result via both paths by just adjusting your transformations accordingly. Just note that, if you need to call glClear when you render your "tiled map", the clear operation will not be limited by the currently set viewport, but the scissor test will allow you to even limit the clearing.
If you're area can not be described as an axis-aligned rectangle, I'll recommend having a look at the stencil buffer. The algorithm is simple:
Clear stencil buffer to 0.
Just render the shape you want your tiled map to appear _only into the stencil buffer.
When rendering your tiled map, enable stencil test and set it up so that it will discard fragments for pixels the stencil buffer is 0.
Steps 1 and 2 do only have to be done once (as long as your area is not changing, or your windo size). Have a look at the glStencilFunc and glStencilOp functions for details of how to do that.

Printing in Java - Printable.print() resizes images

I have a custom report which draws via Graphics2D, and uses a lot of tiny BufferedImage sprites. PrinterJob.print() seems to be calling Printable.print() roughly once for each sprite (the actual count can vary both ways), so some pages are re-rendered 150 times... This causes printing to be unacceptably slow, about 10 seconds for two pages.
I found this: Why does the java Printable's print method get called multiple times with the same page number?
But it doesn't appear to explain my particular problem (or only partially explains it). I created a test report which has only a few sprites, and there was a small number of resizes that went up and down as I added and removed images on either the vertical or horizontal axes.
When printing to a PDF using Bullzip, I noticed that after zooming in on the images, they are being scaled up using a bilinear or bicubic algorithm. One of these images, which is unique in having an indexed color palette, does not appear to be scaled. I confirmed that the scaling is a Java behavior and not being performed by Bullzip by printing to a real printer and observing the same images being scaled versus not.
So it strikes me as the print API trying to rescale images to whatever DPI it has in mind, but for some reason it's calling Printable.print() each time it encounters an image that it deems as needing this treatment.
How do I fix this behavior? I tried setting rendering hints on the Graphics2D that I get when Printable.print() is called, to no avail. I don't know what else to do short of try to find and examine the print API's source code.
I think I just figured it out by accident. A report I just modified now draws an image over some geometry, and I noticed that the part of the geometry that's behind the box of the image is being rasterized and looks blurry compared to outside of the box. The image in question (and all other than the one indexed color image) has an 8 bit alpha channel.
I noticed before that Java's print rasterizer doesn't like things with translucency (one report which used it was being completely rasterized at I think 300dpi...), but I forgot that these images also had alpha channels.
When I get a chance, I'm probably going to fix this by further increasing the images' resolution and using 1 bit alpha. When scaled down for screen viewing, it will have a few bits of alpha again and look okay.

Categories

Resources