VoxelShop - voxel editor

Started by aZen, November 11, 2013, 06:01:18 PM

Previous topic - Next topic

aZen

This project relies on JPCT on a large scale and I'm very grateful for it!

>> VoxelShop - a voxel editor with animation support



This currently uses the software renderer and I'm still planning to change that.

Please consider using the Blackflux forum if you want to give feedback. I will probably not be able to check this thread regularly in the future.

Regards,
flux

EgonOlsen

#1
Looks cool. I think the software renderer is actually a good solution for this...less hassle, works everywhere, no hardware dependencies and no fighting between OpenGL and the GUI over world domination.

Edit: And if it's too slow, there always the option to enable multi-threading for it: http://www.jpct.net/wiki/index.php/Multithreading#The_software_renderer_on_multiple_cores

aZen

Thank you for the reply!

The software renderer is already multi-threaded. The problem is that the refresh rate goes down significantly when one expands the viewport (e.g. 2560x1440). I think the drawing onto the canvas is just taking too long.

Is there a way to improve that?

EgonOlsen

How are you doing that drawing into the canvas?

aZen

#4
In reality it's more complicated, but the basic idea is:


World world = ...;
FrameBuffer buffer = ...;

buffer.clear(BGCOLOR);
world.renderScene(buffer);
world.draw(buffer);
buffer.update();

Graphics2D igr = (Graphics2D) buffer.getGraphics();
[...] (draw on the igr)

Graphics2D gr = (Graphics2D) BufferedImage.getGraphics();
buffer.display(gr);


I already did some profiling and most time is spend on draw(...) and update(), but not sure what exactly happens when the canvas enlarges, so I'll need to test that again.

EgonOlsen

In case that you haven't done this already, you can try to set


http://www.jpct.net/doc/com/threed/jpct/Config.html#useMultiThreadedBlitting


to true. It might help, it might not. It highly depends on the system.

aZen

#6
Quote from: EgonOlsen on November 14, 2013, 02:58:46 PM
In case that you haven't done this already, you can try to set


http://www.jpct.net/doc/com/threed/jpct/Config.html#useMultiThreadedBlitting


to true. It might help, it might not. It highly depends on the system.

Ah, yeah I had experimented with that setting in the past, but didn't really see any benefit. Will try again and report back. It sounds like it's exactly what I need.

Edit: I think it might have caused some issues, but it's definitely smoother. I've enabled it for now and will see what people report.

EgonOlsen

Do you have an additional screen shot? I would like to add it to the projects page, but i need two screen shots for that.

aZen

Sure, will get back to you in a few days when I have access to my laptop again. Is there a limit to the amount of screenshots?

EgonOlsen

I'm using two for each project and they will be rather small. So if you care about these things, make sure that they will look good in 240*y.

aZen

Quote from: EgonOlsen on November 26, 2013, 11:22:45 PM
I'm using two for each project and they will be rather small. So if you care about these things, make sure that they will look good in 240*y.

Ok, great. I'll get back to you!

aZen

Made two new screenshots (click to enlarge):





And here the 240*y versions:




aZen

#12
Before I start implementing complicated optimization techniques (I have some cool stuff coming up!), I'd like to ask a few questions.

The following shows profiling done for the same scene rendered with a small frame buffer (200 x 200) and a large frame buffer (2000 x 1000). About the same amount of triangles are visible for both renders. The first number shows the absolute time spend, the second number indicates how often this code snipped was executed, etc.

buffer.clear([COLOR]); : 1425 / 564 = 2
buffer.display(gr); : 1283 / 564 = 2
drawLinkedOverlay((Graphics2D) buffer.getGraphics()); : 1281 / 564 = 2
buffer.update(); : 1300 / 564 = 2
world.draw(buffer); : 4396 / 564 = 7
world.renderScene(buffer); : 5895 / 564 = 10

buffer.display(gr); : 1928 / 565 = 3
drawLinkedOverlay((Graphics2D) buffer.getGraphics()); : 2830 / 565 = 5
buffer.update(); : 6940 / 565 = 12
buffer.clear([COLOR]); : 8080 / 565 = 14
world.draw(buffer); : 13954 / 565 = 24
world.renderScene(buffer); : 18313 / 565 = 32


Interestingly the Framebuffer.clear(Color) method "blows up". I was thinking that is must be possible to buffer the content and restore it much faster (e.g. with a low level memcpy). Is this something that you could help me with? Since this is independent of the amount of triangles in the scene (tested that), it's something I'd like to look at first.

Which times do you think will go down (and by how much) if I reduce the overall triangle count (while keeping the exact same rendering area), i.e. low poly model version?

EgonOlsen

I tried a lot of things to get these operations faster (including native operation via System.arraycopy) and the current solution is the best that i could come up with. The current implementation will use multiple threads if Config.useMultipleThreads is true. Are you using that? If no, it might be worth a try. If yes, it might be worth a try to disable it before clearing and enable it again afterwards.

If you reduce the polygon count, draw might improve as well as renderScene. But with the software renderer, you are usually fill rate bound in almost any case.

Edit: Thanks for the screen shots. I'll add the project, when i find the time.

aZen

Quote from: EgonOlsen on December 03, 2013, 11:41:36 PM
I tried a lot of things to get these operations faster (including native operation via System.arraycopy) and the current solution is the best that i could come up with. The current implementation will use multiple threads if Config.useMultipleThreads is true. Are you using that? If no, it might be worth a try. If yes, it might be worth a try to disable it before clearing and enable it again afterwards.
I was already using multiple threads. Disabling it for the clearing increases the time from 14 to 20 ms. So that's not helping. Guess I will have to accept it. Could you explain what is happening when clearing? As I understand it, it's "just" deleting all the old data and (re)initializing the data structure. Why is that taking such a long time (I'm just curious)?

Quote from: EgonOlsen on December 03, 2013, 11:41:36 PM
If you reduce the polygon count, draw might improve as well as renderScene. But with the software renderer, you are usually fill rate bound in almost any case.
Is there a way to determine what the bottle neck is? Considering that the optimization I have in mind is far from trivial I'd be nice to know if it's worth it. If you can think of an easy way to add profiling, that would be very much appreciated!

Quote from: EgonOlsen on December 03, 2013, 11:41:36 PM
Edit: Thanks for the screen shots. I'll add the project, when i find the time.
Np, take your time!