Last active
August 21, 2022 17:45
-
-
Save define-private-public/598cfe7ed59f2258a94f8d0c4e4d5bea to your computer and use it in GitHub Desktop.
PSRayTracing Qt GUI Blog Post
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Check if we're building for iOS (and put it into a more friendly variable) | |
set(IOS FALSE) | |
if (${CMAKE_SYSTEM_NAME} STREQUAL iOS) | |
set(IOS TRUE) | |
endif() | |
# If we're building for Android or iOS, turn on the UI | |
set(IS_MOBILE FALSE) | |
if (ANDROID OR IOS) | |
set(IS_MOBILE TRUE) | |
endif() | |
# Configurable options | |
option(BUILD_QT_UI "Build the Qt UI as well (requires Qt 6)" ${IS_MOBILE}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
readonly property real title_font_size_pt: 18 | |
readonly property real about_font_size_pt: 10 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
add_custom_target(fix_render_lib_static_linking | |
WORKING_DIRECTORY ${CMAKE_BINARY_DIR} | |
) | |
add_custom_command(TARGET fix_render_lib_static_linking | |
PRE_BUILD | |
COMMAND ln -sF ${CMAKE_BINARY_DIR}/render_library/Debug-${CMAKE_OSX_SYSROOT} ${CMAKE_BINARY_DIR}/render_library/Debug | |
) | |
add_dependencies(PSRayTracing_QtUI fix_render_lib_static_linking) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
readonly property real _scaling_factor: Screen.devicePixelRatio | |
readonly property real title_font_size_pt: _scaling_factor * 18 | |
readonly property real about_font_size_pt: _scaling_factor * 10 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
set_target_properties(PSRayTracing_QtUI PROPERTIES | |
XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2" | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
readonly property real _scaling_factor: Math.min(1.8, Screen.devicePixelRatio) | |
readonly property real title_font_size_pt: _scaling_factor * 18 | |
readonly property real about_font_size_pt: _scaling_factor * 10 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if (APPLE) | |
# Required (for on Apple devices) to get an app icon | |
set(APPLE_ASSETS ${CMAKE_CURRENT_SOURCE_DIR}/apple/Assets.xcassets) | |
target_sources(PSRayTracing_QtUI PRIVATE ${APPLE_ASSETS}) | |
set_source_files_properties(${APPLE_ASSETS} PROPERTIES MACOSX_PACKAGE_LOCATION Resources) | |
set(APPLE_BUNDLE_ID "net.16bpp.psraytracing") | |
set(APPLE_EXE_NAME "PSRayTracing") | |
set(APPLE_SHORT_VERSION_STRING "${PROJECT_VERSION}.0") # Apple requires a "major.minor.patch" string (e.g. "1.2.3"), but I'm only doing "major.minor" (e.g. "1.2") | |
set_target_properties(PSRayTracing_QtUI PROPERTIES | |
MACOSX_BUNDLE_GUI_IDENTIFIER ${APPLE_BUNDLE_ID} | |
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} | |
MACOSX_BUNDLE_EXECUTABLE_NAME ${APPLE_EXE_NAME} | |
MACOSX_BUNDLE_SHORT_VERSION_STRING ${APPLE_SHORT_VERSION_STRING} | |
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/apple/Info.plist.in | |
XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2" # Required os that we build for both iPhone & iOS. Without, it would only build for iPhone | |
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER ${APPLE_BUNDLE_ID} # Fixes an XCode warning | |
XCODE_ATTRIBUTE_EXECUTABLE_NAME ${APPLE_EXE_NAME} # Makes it so that our app name shows up as "PSRayTracing", without the `_QtUI` at the end | |
XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME "AppIcon" # Required to make sure our AppIcon works | |
) | |
# ... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Figure out the platform & architecture code we need | |
set(ANDROID_PLATFORM_ARCHITECTURE_CODE "xxx") | |
if (${ANDROID_ABI} STREQUAL "armeabi-v7a") | |
set(ANDROID_PLATFORM_ARCHITECTURE_CODE "032") | |
elseif (${ANDROID_ABI} STREQUAL "arm64-v8a") | |
set(ANDROID_PLATFORM_ARCHITECTURE_CODE "064") | |
elseif (${ANDROID_ABI} STREQUAL "x86") | |
set(ANDROID_PLATFORM_ARCHITECTURE_CODE "132") | |
elseif (${ANDROID_ABI} STREQUAL "x86_64") | |
set(ANDROID_PLATFORM_ARCHITECTURE_CODE "164") | |
endif() | |
# Slap the above together with a version code (major and minor only) | |
set(ANDROID_VERSION_CODE "${ANDROID_PLATFORM_ARCHITECTURE_CODE}${PROJECT_VERSION_MAJOR}${PROJECT_VERSION_MINOR}") | |
set_property(TARGET PSRayTracing_QtUI APPEND PROPERTY QT_ANDROID_VERSION_CODE ${ANDROID_VERSION_CODE}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
QSize android_get_device_resolution_in_pixels() | |
{ | |
// Call our Java/Android code | |
const QJniObject dim = QJniObject::callStaticObjectMethod( | |
"net/sixteenbpp/psraytracing/AndroidUtils", | |
"get_device_resolution_in_pixels", | |
"(Landroid/content/Context;)Landroid/graphics/Point;", | |
QNativeInterface::QAndroidApplication::context() | |
); | |
// Get the result | |
return QSize( | |
dim.getField<jint>("x"), | |
dim.getField<jint>("y") | |
); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class AndroidUtils | |
{ | |
/** | |
* This is an Android native method we need to call to get the physical screen size | |
* (in pixels) of our device. | |
* | |
* \a context must be the active application context. | |
*/ | |
public static Point get_device_resolution_in_pixels(Context context) | |
{ | |
// NOTE: This API is deprecated in android API 30 and above. | |
// But I don't see any other way of getting the "real size" (easily) in the | |
// new recommended API | |
Point dim = new Point(); | |
context.getDisplay().getRealSize(dim); | |
return dim; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ScrollView { | |
RenderSettingsForm { } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// State for controlling the widgets' layout | |
states: [ | |
// For normal screen widths | |
// Layout goes left to right: settings button, scene label, scene select, status message, render button | |
State { | |
name: 'normal_width' | |
when: !UITheme.is_width_small(root.width); | |
AnchorChanges { target: scene_label; anchors.left: settings_button.right; } | |
AnchorChanges { target: scene_select_dropdown; anchors.right: undefined; } | |
AnchorChanges { target: settings_button; anchors.top: parent.top; } | |
AnchorChanges { target: render_info_layout; anchors.left: scene_select_dropdown.right; } | |
AnchorChanges { target: render_button; anchors.top: parent.top; } | |
PropertyChanges { target: scene_label; anchors.leftMargin: __p.padding; } | |
PropertyChanges { target: scene_select_dropdown; width: 330; } | |
}, | |
// When the width is too tiny | |
// Scene select (and label) goes on top | |
// Render settings, status message, and render goes on bottom | |
State { | |
name: 'small_width' | |
when: UITheme.is_width_small(root.width); | |
AnchorChanges { target: scene_label; anchors.left: parent.left; } | |
AnchorChanges { target: scene_select_dropdown; anchors.right: parent.right; } | |
AnchorChanges { target: settings_button; anchors.top: scene_select_dropdown.bottom; } | |
AnchorChanges { target: render_info_layout; anchors.left: settings_button.right; } | |
AnchorChanges { target: render_button; anchors.top: scene_select_dropdown.bottom; } | |
PropertyChanges { target: scene_label; anchors.leftMargin: undefined; } | |
PropertyChanges { target: scene_select_dropdown; width: undefined; } | |
} | |
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ScrollView { | |
clip: true | |
ScrollBar.horizontal.interactive: true | |
ScrollBar.vertical.interactive: true | |
Flickable { | |
width: parent.width | |
height: parent.height | |
contentWidth: rsf.width | |
contentHeight: rsf.height | |
RenderSettingsForm { | |
id: rsf | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Item { | |
id: root | |
// The buttons that appear in the upper right | |
Rectangle { | |
ColumnLayout { | |
Button { } | |
Button { } | |
} | |
MouseArea { | |
// Normally MouseArea would "steal" the click events, so the buttons above wouldn't be clickable | |
// But if we do this below, we can have the mouse area only catch the hover events (which is what we want) | |
// and then the click events can be sent to the buttons | |
propagateComposedEvents: true | |
onClicked: function(mouse) { mouse.accepted = false; } | |
onPressed: function(mouse) { mouse.accepted = false; } | |
onReleased: function(mouse) { mouse.accepted = false; } | |
} | |
} | |
// Gives us the pan controls | |
Flickable { | |
// Give us those "pinch to zoom" controls | |
PinchArea { | |
// Mouse area (used for scroll wheel zoom, double click/tap) needs to live inside of the | |
// pinch area so things work nicely | |
MouseArea { } | |
} | |
// We want the target of the PanZoom to be centered, so we need to put it inside of a container Item. | |
Item { | |
// The actual image (itself) we pan/zoom upon | |
Image { } | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
QSize ios_utils::get_device_resolution_in_pixels() | |
{ | |
const CGRect dim = [UIScreen mainScreen].nativeBounds; | |
QSize native_size( | |
static_cast<int>(dim.size.width), | |
static_cast<int>(dim.size.height) | |
); | |
if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)) | |
native_size.transpose(); | |
return native_size; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** A descriptor of how a render should be performed */ | |
struct RenderJob | |
{ | |
uint16_t render_width = 960; | |
uint16_t render_height = 540; | |
std::string scene_id = "book2::final_scene"; | |
uint32_t samples_per_pixel = 10; | |
uint16_t max_depth = 50; | |
uint16_t num_threads = 1; | |
std::string seed_str = "ASDF"; | |
bool deep_copy_per_thread = true; | |
}; | |
/** The result of a render job. */ | |
struct Render | |
{ | |
std::vector<uint8_t> image_data; | |
uint16_t render_width = 0; | |
uint16_t render_height = 0; | |
uint8_t num_channels = 0; | |
float render_time_in_seconds = 0.0f; | |
std::chrono::nanoseconds render_time_in_nanoseconds; | |
bool was_succesful() const | |
{ return !image_data.empty(); } | |
}; | |
// The fuctions to perform a render | |
std::future<Render> do_render(const RenderJob &job); ///< Will start a render job (if one isn't in progress) | |
void stop_active_render(); ///< Will stop a render job (if one is in progress) | |
float render_progress(); ///< Returns the progress of a render [0.0, 1.0]. Returns less than 0 (e.g. -1) if no render is happening | |
bool render_in_progress(); ///< Checks to see if a render is already in progress (or not) | |
std::vector<std::string> all_scene_ids(); ///< Retrives all possible scenes that could be rendered | |
int num_concurrent_threads_supported(); ///< Retrives the maximum number of threads that can ru concurrently |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment