MORPH INTO: Hyperboloid

This commit is contained in:
numzero 2026-07-20 02:01:29 +03:00
parent 05edd5db56
commit 25c1e7a909
20 changed files with 47 additions and 214 deletions

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.18)
project(PROJECT-NAME VERSION 1.0.0 LANGUAGES CXX)
project(hyperboloid VERSION 1.0.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

42
Cargo.lock generated
View File

@ -2,27 +2,6 @@
# It is not intended for manual editing.
version = 4
[[package]]
name = "PROJECT-NAME"
version = "0.1.0"
dependencies = [
"glam",
"pollster",
"wgpu",
"winit",
]
[[package]]
name = "PROJECT-NAME-impl"
version = "0.1.0"
dependencies = [
"PROJECT-NAME",
"glam",
"pollster",
"raw-window-handle",
"wgpu",
]
[[package]]
name = "ab_glyph"
version = "0.2.32"
@ -641,6 +620,27 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
[[package]]
name = "hyperboloid"
version = "0.1.0"
dependencies = [
"glam",
"pollster",
"wgpu",
"winit",
]
[[package]]
name = "hyperboloid-impl"
version = "0.1.0"
dependencies = [
"glam",
"hyperboloid",
"pollster",
"raw-window-handle",
"wgpu",
]
[[package]]
name = "indexmap"
version = "2.13.0"

View File

@ -2,7 +2,7 @@
members = ["ui"]
[package]
name = "PROJECT-NAME"
name = "hyperboloid"
version = "0.1.0"
edition = "2024"

View File

@ -1,22 +1 @@
# Qt6+WGPU skeleton program
This example combines Qt6 GUI (C++) with WGPU rendering (Rust). It doesnt do much of either but its the bridging whats relevant.
Currently only X11 (XCB) is supported but it should be easy to extend to other platforms.
## Usage
This program is intended as a starting point rather than a dependency, so just copy it.
1. Fetch this code:
* clone the repo: `git clone https://gitea.noteuclid.ru/noteuclid/qt-wgpu-skel.git`
* or, download and unpack the [tarball](https://gitea.noteuclid.ru/noteuclid/qt-wgpu-skel/archive/master.tar.gz).
2. Rename the directory to your liking
3. Run `init.sh` with the project name, like:
* `./init.sh 'My FANCY Project'`, or
* `./init.sh 'My FANCY Project' 'fancy-project'`.
Running `init.sh` without arguments prints the help.
If you want to use Qt5, change the version in both `CMakeLists.txt`, as well as the KF version.
If you dont want to depend on KDE, remove the ECM and KF5 dependencies, as well as `KColorCombo inBackground` from the UI. Youll need to replace `inBackground->color()` with something else though.
# Hyperboloid

79
init.sh
View File

@ -1,79 +0,0 @@
#!/bin/sh
# set -x # debug
set -e # abort on errors
cd "${0%/*}" # where this script is located
usage() {
{
echo "Usage:"
echo
echo " ./init.sh 'Project Name' [ internal-name ]"
echo
echo "Project name may be anything you like, in any language, with spaces (but not other control characters), etc."
echo
echo "Technical name must be ASCII alphanumeric (a-z, 0-9, also _ and - are allowed), preferably all-lowercase. If omitted, it will be generated from the project name (but that only works if the latter is ASCII too)."
echo
echo "Running this script with no arguments shows this message"
} | fold -s 2>&1
}
name="$1"
[ -n "$name" ] || { usage; exit 0; } 2>&1
echo -n "$name" | LC_ALL=C grep '[[:cntrl:]]' && { echo 'Project name must not contain any control characters'; exit 2; } 2>&1
name="$(echo -n $name)" # normalize whitespace
techname="$2"
if [ -z "$techname" ]; then
techname=$(
echo -n $name |
LC_ALL=C tr ' ' '-' |
LC_ALL=C tr -d -c '[:alnum:]-_' |
LC_ALL=C tr '[:upper:]' '[:lower:]' |
cat
)
echo "Technical name not specified; autogenerated: \"$techname\"" >&2
fi
echo -n $techname | LC_ALL=C grep '[^0-9A-Za-z_-]' && { echo 'Technical name must be ASCII alphanumeric'; exit 2; } 2>&1
echo -n $techname | LC_ALL=C grep -q '^[A-Za-z]' || { echo 'Technical name must start with an ASCII letter'; exit 2; } 2>&1
echo -n $techname | LC_ALL=C grep -q '[A-Za-z0-9]$' || { echo 'Technical name must end with an ASCII letter or digit'; exit 2; } 2>&1
echo "Project name: $name"
echo "Internal name: $techname"
if ! [ -e .git ]; then
alias git='echo skipping:'
fi
# detach from the skeleton repository
# oldurl="$(git remote -v get-url origin)"
git remote remove origin
# remove this script from the project (but keep on disk for now)
git rm --cached init.sh
git rm -r skel-test
# replace the README with a stub
echo "# $name" >| README.md
# escape HTML special characters (&, <, and >), but also sed special characters (& again, \, and /)
htmlname=$(echo -n "$name" | sed 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g; s:[\\/&]:\\&:g')
sed -i "s/PROJECT NAME/$htmlname/" ui/src/main_window.ui
# escape Rust special characters (" and \; don't worry of the others as they are unlikely enough and easy to fix manually), and also sed special characters (&, \, and /)
quotname=$(echo -n "$name" | sed 's/"/\\"/g; s:[\\/&]:\\&:g')
sed -i "s/PROJECT NAME/$quotname/" src/main.rs
# $techname is alphanumeric, nothing to escape
grep -l -r PROJECT-NAME | xargs sed -i "s/PROJECT-NAME/$techname/g"
# replace - with _ to form a valid snake_case identifier
ident=$(echo -n $techname | LC_ALL=C tr '-' '_')
grep -l -r PROJECT_NAME | xargs sed -i "s/PROJECT_NAME/$ident/g"
# black magic to convert snake_case to PascalCase
pascal=$(echo -n $ident | LC_ALL=C tr '_' '\n' | LC_ALL=C awk -v FIELDWIDTHS='1 1000' -v ORS='' '{print toupper($1) $2}')
grep -l -r PROJECTNAME | xargs sed -i "s/PROJECTNAME/$pascal/g"
git commit -a -m "MORPH INTO: $name"

View File

@ -1,3 +0,0 @@
# Self-tests
This directory contains self-tests for the skeleton itself. It should be removed when starting a new project.

View File

@ -1,5 +0,0 @@
#!/bin/sh
set -E
exec cargo check

View File

@ -1,8 +0,0 @@
#!/bin/sh
set -x
set -E
mkdir build
cmake -S . -B build -G Ninja -D CMAKE_BUILD_TYPE=Debug
ninja -C build

View File

@ -1,17 +0,0 @@
#!/bin/zsh
set -e
trap 'echo Test failed!' ERR
name='<Test/+> "Example"'
dir=${0%/*}
root=$dir/..
tmp=$(mktemp -d)
trap 'rm -rf $tmp' EXIT
rsync -a --exclude=/.git --exclude-from=$root/.gitignore $root/. $tmp/
cd $tmp
echo "Initializing in $tmp"
./init.sh $name
echo "Starting the shell in $tmp"
echo "Review the files, then exit the shell"
${SHELL:-/bin/sh} -i
echo "Review successful, cleaning up"

View File

@ -1,16 +0,0 @@
#!/bin/zsh
set -e
trap 'echo Test failed!' ERR
name='<Test/+> "Example"'
root=$(realpath ${0%/*}/..)
tmp=$(mktemp -d)
trap 'rm -rf $tmp' EXIT
cd $tmp
git -C $root archive HEAD | tar -x
echo "Initializing in $tmp"
./init.sh $name
echo "Starting the shell in $tmp"
echo "Review the files, then exit the shell"
${SHELL:-/bin/sh} -i
echo "Review successful, cleaning up"

View File

@ -1,18 +0,0 @@
#!/bin/zsh
set -e
trap 'echo Test failed!' ERR
name='<Test/+> "Example"'
dir=${0%/*}
root=$dir/..
tmp=$(mktemp -d)
trap 'rm -rf $tmp' EXIT
rsync -a --exclude-from=$root/.gitignore $root/. $tmp/
cd $tmp
git clean -fxdq
echo "Initializing in $tmp"
./init.sh $name
echo "Starting the shell in $tmp"
echo "Review the files, then exit the shell"
${SHELL:-/bin/sh} -i
echo "Review successful, cleaning up"

View File

@ -1,6 +1,6 @@
use std::sync::Arc;
use PROJECT_NAME::{Core, RedrawArgs, init_gpu_inner};
use hyperboloid::{Core, RedrawArgs, init_gpu_inner};
use glam::uvec2;
use winit::{
application::ApplicationHandler,
@ -9,7 +9,7 @@ use winit::{
window::Window,
};
const TITLE: &str = "PROJECT NAME";
const TITLE: &str = "Hyperboloid";
struct MainWindow {
window: Arc<Window>,

View File

@ -1,6 +1,6 @@
include(impl.cmake)
qt_add_executable(PROJECT-NAME
qt_add_executable(hyperboloid
src/api.cxx
src/main.cxx
src/main_window.cxx
@ -8,7 +8,7 @@ qt_add_executable(PROJECT-NAME
src/viewport.cxx
)
target_link_libraries(PROJECT-NAME PRIVATE Qt6::Gui Qt6::Widgets)
target_link_libraries(PROJECT-NAME PRIVATE KF6::WidgetsAddons)
target_link_libraries(PROJECT-NAME PRIVATE PROJECT_NAME_impl)
target_include_directories(PROJECT-NAME PRIVATE src)
target_link_libraries(hyperboloid PRIVATE Qt6::Gui Qt6::Widgets)
target_link_libraries(hyperboloid PRIVATE KF6::WidgetsAddons)
target_link_libraries(hyperboloid PRIVATE hyperboloid_impl)
target_include_directories(hyperboloid PRIVATE src)

View File

@ -1,5 +1,5 @@
[package]
name = "PROJECT-NAME-impl"
name = "hyperboloid-impl"
version = "0.1.0"
edition = "2024"
@ -7,7 +7,7 @@ edition = "2024"
crate-type = ["staticlib"]
[dependencies]
PROJECT-NAME = {path = "../"}
hyperboloid = {path = "../"}
glam = { version = "0.30" }
pollster = "0.4.0"

View File

@ -1,8 +1,8 @@
set(impl_basename "${CARGO_TARGET_DIR}/release/libPROJECT_NAME_impl")
set(impl_basename "${CARGO_TARGET_DIR}/release/libhyperboloid_impl")
add_custom_command(
OUTPUT ${impl_basename}.a
COMMAND env CARGO_TARGET_DIR=${CARGO_TARGET_DIR} ${CARGO} build --release --package PROJECT-NAME-impl
COMMAND env CARGO_TARGET_DIR=${CARGO_TARGET_DIR} ${CARGO} build --release --package hyperboloid-impl
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPFILE ${impl_basename}.d
USES_TERMINAL
@ -15,8 +15,8 @@ add_custom_target(build_impl
DEPENDS ${impl_basename}.a
)
add_library(PROJECT_NAME_impl STATIC IMPORTED)
add_library(hyperboloid_impl STATIC IMPORTED)
set_target_properties(PROJECT_NAME_impl PROPERTIES
set_target_properties(hyperboloid_impl PROPERTIES
IMPORTED_LOCATION ${impl_basename}.a
)

View File

@ -1,6 +1,6 @@
use std::{ffi::c_void, num::NonZero, ptr::NonNull};
use PROJECT_NAME::{Core, RedrawArgs, init_gpu_inner};
use hyperboloid::{Core, RedrawArgs, init_gpu_inner};
use glam::{UVec2, uvec2};
use raw_window_handle::{RawDisplayHandle, RawWindowHandle, XcbDisplayHandle, XcbWindowHandle};

View File

@ -8,7 +8,7 @@ int main(int argc, char* argv[]) {
QApplication app(argc, argv);
auto w = new PROJECTNAME;
auto w = new Hyperboloid;
w->show();
return app.exec();

View File

@ -2,16 +2,16 @@
#include "ui_main_window.h"
PROJECTNAME::PROJECTNAME(QWidget* parent)
Hyperboloid::Hyperboloid(QWidget* parent)
: QMainWindow(parent),
m_ui(new Ui::MainWindow) {
m_ui->setupUi(this);
updateView();
}
PROJECTNAME::~PROJECTNAME() = default;
Hyperboloid::~Hyperboloid() = default;
void PROJECTNAME::updateView() {
void Hyperboloid::updateView() {
const auto color = m_ui->inBackground->color();
RedrawArgs args{
.background = { color.redF(), color.greenF(), color.blueF(), 1.00 },
@ -19,7 +19,7 @@ void PROJECTNAME::updateView() {
m_ui->viewport->setView(args);
}
void PROJECTNAME::updateViewIf(bool update) {
void Hyperboloid::updateViewIf(bool update) {
if (update)
updateView();
}

View File

@ -7,12 +7,12 @@ namespace Ui {
class MainWindow;
}
class PROJECTNAME : public QMainWindow {
class Hyperboloid : public QMainWindow {
Q_OBJECT
public:
explicit PROJECTNAME(QWidget* parent = nullptr);
~PROJECTNAME() override;
explicit Hyperboloid(QWidget* parent = nullptr);
~Hyperboloid() override;
public slots:
void updateView();

View File

@ -11,7 +11,7 @@
</rect>
</property>
<property name="windowTitle">
<string>PROJECT NAME</string>
<string>Hyperboloid</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QHBoxLayout" name="horizontalLayout_2">