kopia lustrzana https://github.com/jameshball/osci-render
Make GPU rendering toggleable to prevent crashes due to bad initialisation
rodzic
6271507113
commit
a7e8c2d9d5
|
@ -1,3 +1,7 @@
|
||||||
|
- 1.26.4
|
||||||
|
- Make GPU rendering toggleable to prevent crashes due to bad initialisation
|
||||||
|
|
||||||
|
|
||||||
- 1.26.3
|
- 1.26.3
|
||||||
- Fix potential bug with updating frequency spinner and slider from not-GUI thread
|
- Fix potential bug with updating frequency spinner and slider from not-GUI thread
|
||||||
|
|
||||||
|
|
2
pom.xml
2
pom.xml
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
<groupId>sh.ball</groupId>
|
<groupId>sh.ball</groupId>
|
||||||
<artifactId>osci-render</artifactId>
|
<artifactId>osci-render</artifactId>
|
||||||
<version>1.26.3</version>
|
<version>1.26.4</version>
|
||||||
|
|
||||||
<name>osci-render</name>
|
<name>osci-render</name>
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,8 @@ public class Camera {
|
||||||
|
|
||||||
private double focalLength;
|
private double focalLength;
|
||||||
private Vector3 pos;
|
private Vector3 pos;
|
||||||
|
private boolean hideEdges = false;
|
||||||
|
private boolean usingGpu = false;
|
||||||
|
|
||||||
public Camera(double focalLength, Vector3 pos) {
|
public Camera(double focalLength, Vector3 pos) {
|
||||||
this.focalLength = focalLength;
|
this.focalLength = focalLength;
|
||||||
|
@ -105,4 +107,20 @@ public class Camera {
|
||||||
public double getFocalLength() {
|
public double getFocalLength() {
|
||||||
return focalLength;
|
return focalLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void hideEdges(boolean hideEdges) {
|
||||||
|
this.hideEdges = hideEdges;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean edgesHidden() {
|
||||||
|
return hideEdges;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void usingGpu(boolean usingGpu) {
|
||||||
|
this.usingGpu = usingGpu;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isUsingGpu() {
|
||||||
|
return usingGpu;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,9 @@ public class CameraDrawKernel extends Kernel {
|
||||||
private float focalLength;
|
private float focalLength;
|
||||||
private int hideEdges = 0;
|
private int hideEdges = 0;
|
||||||
private int usingObjectSet = 0;
|
private int usingObjectSet = 0;
|
||||||
|
private boolean initialisedGpu = false;
|
||||||
private boolean failedGpu = false;
|
private boolean failedGpu = false;
|
||||||
|
private int maxGroupSize = 256;
|
||||||
|
|
||||||
public CameraDrawKernel() {}
|
public CameraDrawKernel() {}
|
||||||
|
|
||||||
|
@ -131,9 +133,13 @@ public class CameraDrawKernel extends Kernel {
|
||||||
this.cameraPosZ = (float) cameraPos.z;
|
this.cameraPosZ = (float) cameraPos.z;
|
||||||
this.focalLength = (float) camera.getFocalLength();
|
this.focalLength = (float) camera.getFocalLength();
|
||||||
|
|
||||||
this.hideEdges = object.edgesHidden() ? 1 : 0;
|
this.hideEdges = camera.edgesHidden() ? 1 : 0;
|
||||||
|
|
||||||
return executeGpu();
|
if (!camera.isUsingGpu() || failedGpu || vertices.length / 3 < MIN_GPU_VERTICES) {
|
||||||
|
return executeCpu();
|
||||||
|
} else {
|
||||||
|
return executeGpu();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Shape> postProcessVertices() {
|
private List<Shape> postProcessVertices() {
|
||||||
|
@ -164,16 +170,14 @@ public class CameraDrawKernel extends Kernel {
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Shape> executeGpu() {
|
private List<Shape> executeGpu() {
|
||||||
if (failedGpu || vertices.length / 3 < MIN_GPU_VERTICES) {
|
|
||||||
return executeCpu();
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
int maxGroupSize = 256;
|
if (!initialisedGpu) {
|
||||||
try {
|
try {
|
||||||
maxGroupSize = getKernelMaxWorkGroupSize(getTargetDevice());
|
maxGroupSize = getKernelMaxWorkGroupSize(getTargetDevice());
|
||||||
} catch (QueryFailedException e) {
|
initialisedGpu = true;
|
||||||
logger.log(Level.WARNING, e.getMessage(), e);
|
} catch (QueryFailedException e) {
|
||||||
|
logger.log(Level.WARNING, e.getMessage(), e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
execute(Range.create(roundUp(vertices.length / 3, maxGroupSize), maxGroupSize));
|
execute(Range.create(roundUp(vertices.length / 3, maxGroupSize), maxGroupSize));
|
||||||
|
|
|
@ -26,7 +26,6 @@ public class WorldObject {
|
||||||
private List<List<Vector3>> vertexPath;
|
private List<List<Vector3>> vertexPath;
|
||||||
private Vector3 position;
|
private Vector3 position;
|
||||||
private Vector3 rotation;
|
private Vector3 rotation;
|
||||||
private boolean hideEdges = false;
|
|
||||||
|
|
||||||
public WorldObject(Vector3[] vertices, int[] edgeIndices, int[][] faceIndices) {
|
public WorldObject(Vector3[] vertices, int[] edgeIndices, int[][] faceIndices) {
|
||||||
vertexPath = new ArrayList<>();
|
vertexPath = new ArrayList<>();
|
||||||
|
@ -319,12 +318,4 @@ public class WorldObject {
|
||||||
return new WorldObject(new ArrayList<>(objVertices), new ArrayList<>(vertexPath), position,
|
return new WorldObject(new ArrayList<>(objVertices), new ArrayList<>(vertexPath), position,
|
||||||
rotation);
|
rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hideEdges(boolean hideEdges) {
|
|
||||||
this.hideEdges = hideEdges;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean edgesHidden() {
|
|
||||||
return hideEdges;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,6 +148,8 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
||||||
@FXML
|
@FXML
|
||||||
private CheckMenuItem hideHiddenMeshesCheckMenuItem;
|
private CheckMenuItem hideHiddenMeshesCheckMenuItem;
|
||||||
@FXML
|
@FXML
|
||||||
|
private CheckMenuItem renderUsingGpuCheckMenuItem;
|
||||||
|
@FXML
|
||||||
private Spinner<Integer> midiChannelSpinner;
|
private Spinner<Integer> midiChannelSpinner;
|
||||||
@FXML
|
@FXML
|
||||||
private Spinner<Double> attackSpinner;
|
private Spinner<Double> attackSpinner;
|
||||||
|
@ -408,6 +410,8 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
||||||
|
|
||||||
hideHiddenMeshesCheckMenuItem.selectedProperty().addListener((e, old, hidden) -> objController.hideHiddenMeshes(hidden));
|
hideHiddenMeshesCheckMenuItem.selectedProperty().addListener((e, old, hidden) -> objController.hideHiddenMeshes(hidden));
|
||||||
|
|
||||||
|
renderUsingGpuCheckMenuItem.selectedProperty().addListener((e, old, usingGpu) -> objController.renderUsingGpu(usingGpu));
|
||||||
|
|
||||||
NumberFormat format = NumberFormat.getIntegerInstance();
|
NumberFormat format = NumberFormat.getIntegerInstance();
|
||||||
UnaryOperator<TextFormatter.Change> filter = c -> {
|
UnaryOperator<TextFormatter.Change> filter = c -> {
|
||||||
if (c.isContentChange()) {
|
if (c.isContentChange()) {
|
||||||
|
@ -691,6 +695,7 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
||||||
}
|
}
|
||||||
// FIXME: Is this safe since we are accessing GUI object in non-GUI thread?
|
// FIXME: Is this safe since we are accessing GUI object in non-GUI thread?
|
||||||
objController.hideHiddenMeshes(hideHiddenMeshesCheckMenuItem.isSelected());
|
objController.hideHiddenMeshes(hideHiddenMeshesCheckMenuItem.isSelected());
|
||||||
|
objController.renderUsingGpu(renderUsingGpuCheckMenuItem.isSelected());
|
||||||
executor.submit(producer);
|
executor.submit(producer);
|
||||||
} else if (samples != null) {
|
} else if (samples != null) {
|
||||||
samples.enable();
|
samples.enable();
|
||||||
|
@ -1141,6 +1146,10 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
||||||
hiddenEdges.appendChild(document.createTextNode(String.valueOf(hideHiddenMeshesCheckMenuItem.isSelected())));
|
hiddenEdges.appendChild(document.createTextNode(String.valueOf(hideHiddenMeshesCheckMenuItem.isSelected())));
|
||||||
root.appendChild(hiddenEdges);
|
root.appendChild(hiddenEdges);
|
||||||
|
|
||||||
|
Element usingGpu = document.createElement("usingGpu");
|
||||||
|
usingGpu.appendChild(document.createTextNode(String.valueOf(renderUsingGpuCheckMenuItem.isSelected())));
|
||||||
|
root.appendChild(usingGpu);
|
||||||
|
|
||||||
Element translationIncrement = document.createElement("translationIncrement");
|
Element translationIncrement = document.createElement("translationIncrement");
|
||||||
translationIncrement.appendChild(document.createTextNode(translationIncrementSpinner.getValue().toString()));
|
translationIncrement.appendChild(document.createTextNode(translationIncrementSpinner.getValue().toString()));
|
||||||
root.appendChild(translationIncrement);
|
root.appendChild(translationIncrement);
|
||||||
|
@ -1263,6 +1272,11 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
||||||
hideHiddenMeshesCheckMenuItem.setSelected(Boolean.parseBoolean(hiddenEdges.getTextContent()));
|
hideHiddenMeshesCheckMenuItem.setSelected(Boolean.parseBoolean(hiddenEdges.getTextContent()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Element usingGpu = (Element) root.getElementsByTagName("usingGpu").item(0);
|
||||||
|
if (usingGpu != null) {
|
||||||
|
renderUsingGpuCheckMenuItem.setSelected(Boolean.parseBoolean(usingGpu.getTextContent()));
|
||||||
|
}
|
||||||
|
|
||||||
Element translationIncrement = (Element) root.getElementsByTagName("translationIncrement").item(0);
|
Element translationIncrement = (Element) root.getElementsByTagName("translationIncrement").item(0);
|
||||||
if (translationIncrement != null) {
|
if (translationIncrement != null) {
|
||||||
translationIncrementSpinner.getValueFactory().setValue(Double.parseDouble(translationIncrement.getTextContent()));
|
translationIncrementSpinner.getValueFactory().setValue(Double.parseDouble(translationIncrement.getTextContent()));
|
||||||
|
|
|
@ -182,4 +182,8 @@ public class ObjController implements Initializable, SubController {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load(Element root) {}
|
public void load(Element root) {}
|
||||||
|
|
||||||
|
public void renderUsingGpu(boolean usingGpu) {
|
||||||
|
producer.setFrameSettings(ObjSettingsFactory.renderUsingGpu(usingGpu));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,9 @@ public class ObjFrameSettings {
|
||||||
public Double rotateSpeed;
|
public Double rotateSpeed;
|
||||||
public boolean resetRotation = false;
|
public boolean resetRotation = false;
|
||||||
public Boolean hideEdges = null;
|
public Boolean hideEdges = null;
|
||||||
|
public Boolean usingGpu = null;
|
||||||
|
|
||||||
protected ObjFrameSettings(Double focalLength, Vector3 cameraPos, Vector3 baseRotation, Vector3 currentRotation, Double rotateSpeed, boolean resetRotation, Boolean hideEdges) {
|
protected ObjFrameSettings(Double focalLength, Vector3 cameraPos, Vector3 baseRotation, Vector3 currentRotation, Double rotateSpeed, boolean resetRotation, Boolean hideEdges, Boolean usingGpu) {
|
||||||
this.focalLength = focalLength;
|
this.focalLength = focalLength;
|
||||||
this.cameraPos = cameraPos;
|
this.cameraPos = cameraPos;
|
||||||
this.baseRotation = baseRotation;
|
this.baseRotation = baseRotation;
|
||||||
|
@ -20,6 +21,7 @@ public class ObjFrameSettings {
|
||||||
this.rotateSpeed = rotateSpeed;
|
this.rotateSpeed = rotateSpeed;
|
||||||
this.resetRotation = resetRotation;
|
this.resetRotation = resetRotation;
|
||||||
this.hideEdges = hideEdges;
|
this.hideEdges = hideEdges;
|
||||||
|
this.usingGpu = usingGpu;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ObjFrameSettings(double focalLength) {
|
protected ObjFrameSettings(double focalLength) {
|
||||||
|
|
|
@ -68,7 +68,10 @@ public class ObjFrameSource implements FrameSource<List<Shape>> {
|
||||||
object.resetRotation();
|
object.resetRotation();
|
||||||
}
|
}
|
||||||
if (obj.hideEdges != null) {
|
if (obj.hideEdges != null) {
|
||||||
object.hideEdges(obj.hideEdges);
|
camera.hideEdges(obj.hideEdges);
|
||||||
|
}
|
||||||
|
if (obj.usingGpu != null) {
|
||||||
|
camera.usingGpu(obj.usingGpu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,6 +79,6 @@ public class ObjFrameSource implements FrameSource<List<Shape>> {
|
||||||
// TODO: Refactor!
|
// TODO: Refactor!
|
||||||
@Override
|
@Override
|
||||||
public Object getFrameSettings() {
|
public Object getFrameSettings() {
|
||||||
return new ObjFrameSettings(null, null, baseRotation, currentRotation, null, false, object.edgesHidden());
|
return new ObjFrameSettings(null, null, baseRotation, currentRotation, null, false, camera.edgesHidden(), camera.isUsingGpu());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ public class ObjSettingsFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ObjFrameSettings rotation(Vector3 baseRotation, Vector3 currentRotation) {
|
public static ObjFrameSettings rotation(Vector3 baseRotation, Vector3 currentRotation) {
|
||||||
return new ObjFrameSettings(null, null, baseRotation, currentRotation, null, false, null);
|
return new ObjFrameSettings(null, null, baseRotation, currentRotation, null, false, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ObjFrameSettings rotateSpeed(double rotateSpeed) {
|
public static ObjFrameSettings rotateSpeed(double rotateSpeed) {
|
||||||
|
@ -29,6 +29,10 @@ public class ObjSettingsFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ObjFrameSettings hideEdges(Boolean hideEdges) {
|
public static ObjFrameSettings hideEdges(Boolean hideEdges) {
|
||||||
return new ObjFrameSettings(null, null, null, null, null, false, hideEdges);
|
return new ObjFrameSettings(null, null, null, null, null, false, hideEdges, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ObjFrameSettings renderUsingGpu(Boolean usingGpu) {
|
||||||
|
return new ObjFrameSettings(null, null, null, null, null, false, null, usingGpu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
<menus>
|
<menus>
|
||||||
<Menu mnemonicParsing="false" text="File">
|
<Menu mnemonicParsing="false" text="File">
|
||||||
<items>
|
<items>
|
||||||
<MenuItem disable="true" mnemonicParsing="false" text="osci-render v1.26.3" />
|
<MenuItem disable="true" mnemonicParsing="false" text="osci-render v1.26.4" />
|
||||||
<MenuItem fx:id="openProjectMenuItem" mnemonicParsing="false" text="Open Project">
|
<MenuItem fx:id="openProjectMenuItem" mnemonicParsing="false" text="Open Project">
|
||||||
<accelerator>
|
<accelerator>
|
||||||
<KeyCodeCombination alt="UP" code="O" control="UP" meta="UP" shift="UP" shortcut="DOWN" />
|
<KeyCodeCombination alt="UP" code="O" control="UP" meta="UP" shift="UP" shortcut="DOWN" />
|
||||||
|
@ -152,6 +152,7 @@
|
||||||
<CheckMenuItem fx:id="flipXCheckMenuItem" mnemonicParsing="false" text="Flip X Direction" />
|
<CheckMenuItem fx:id="flipXCheckMenuItem" mnemonicParsing="false" text="Flip X Direction" />
|
||||||
<CheckMenuItem fx:id="flipYCheckMenuItem" mnemonicParsing="false" text="Flip Y Direction" />
|
<CheckMenuItem fx:id="flipYCheckMenuItem" mnemonicParsing="false" text="Flip Y Direction" />
|
||||||
<CheckMenuItem fx:id="hideHiddenMeshesCheckMenuItem" mnemonicParsing="false" text="Hide Hidden Meshes" />
|
<CheckMenuItem fx:id="hideHiddenMeshesCheckMenuItem" mnemonicParsing="false" text="Hide Hidden Meshes" />
|
||||||
|
<CheckMenuItem fx:id="renderUsingGpuCheckMenuItem" mnemonicParsing="false" text="Render Using GPU" />
|
||||||
</items>
|
</items>
|
||||||
</Menu>
|
</Menu>
|
||||||
<Menu mnemonicParsing="false" text="Controls">
|
<Menu mnemonicParsing="false" text="Controls">
|
||||||
|
|
Ładowanie…
Reference in New Issue