add wip articles

This commit is contained in:
Joshua Goins 2023-06-23 14:42:45 -04:00
parent 34281d91a9
commit 7f90b292bf
150 changed files with 728 additions and 61 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

BIN
assets/art/alear.avif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

BIN
assets/art/bard.avif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

BIN
assets/art/bathing.avif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

BIN
assets/art/goinghome.avif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
assets/art/marchsketch.avif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

BIN
assets/art/office-date.avif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
assets/art/short-hair.avif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

BIN
assets/art/warriors.avif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

BIN
assets/art/working-out.avif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
assets/art/workingout.avif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

BIN
assets/art/xbc3.avif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

View file

@ -45,14 +45,16 @@ permalinks:
art: 'art/:year/:month/:slugorfilename' art: 'art/:year/:month/:slugorfilename'
arttags: 'art/tags/:title' arttags: 'art/tags/:title'
characters: 'art/characters/:title' characters: 'art/characters/:title'
characters_listpath: "art/characters/"
tags: 'blog/tags/:title' tags: 'blog/tags/:title'
series: 'blog/series/:title'
projtags: 'software/tags/:title'
taxonomies: taxonomies:
series: 'series' series: 'series'
tag: 'tags' tag: 'tags'
arttag: 'arttags' arttag: 'arttags'
character: 'characters' character: 'characters'
projtag: 'projtags'
menu: menu:
main: main:

View file

@ -12,3 +12,5 @@ Rambles and writings usually consisting of [Linux](/blog/tags/linux/), [KDE](/bl
If you're interested, you can follow this blog using [RSS](/blog/index.xml). If you're interested, you can follow this blog using [RSS](/blog/index.xml).
_Warning_: most of it is mindlessly technical. _Warning_: most of it is mindlessly technical.
{{< blog-featured >}}

View file

@ -4,6 +4,8 @@ date: 2022-05-04
draft: false draft: false
aliases: aliases:
- /notes/astra-0.4.0-release/ - /notes/astra-0.4.0-release/
tags:
- Astra
--- ---
I'm very sorry about the delay, but a new release of Astra is upon us! I'm very sorry about the delay, but a new release of Astra is upon us!

View file

@ -1,6 +1,8 @@
--- ---
title: "Breakdown of my static art gallery" title: "Breakdown of my static art gallery"
date: "2023-04-26" date: "2023-04-26"
tags:
- Website
--- ---
I realized today that I had inadvertently created a static art gallery. I think my system is interesting, so I wanted to write down how it works. I realized today that I had inadvertently created a static art gallery. I think my system is interesting, so I wanted to write down how it works.

View file

@ -1,17 +1,19 @@
--- ---
title: "Drawing simple cubes" title: "Graphics Dump: Drawing debug cubes"
date: 2023-06-10 date: 2023-06-27
draft: true draft: true
summary: "When working on my engine, I wanted to clean up my debug gizmos a bit. The first thing to tackle is drawing bounding boxes!" summary: "When working on my engine, I wanted to clean up my debug gizmos a bit. The first thing to tackle is drawing bounding boxes!"
tags: tags:
- C++ - C++
- Graphics Dump
- Math
series:
- Graphics Dump
--- ---
If you are writing graphical tools, one of the most common shapes you draw is boxes. They can represent areas (like the affected area of an environment capture) or a box collision. If you are writing graphical tools, one of the most common shapes you draw is boxes. They can represent areas (like the affected area of an environment capture) or a box collision.
One common problem that I run into, is dealing with these diagonals: One common problem that I run into, is dealing with these diagonals:
Of course this is natural due to the way that GPUs work, they work in triangles and when drawing the wireframe of a cube doesn't just draw the edges but everything in-between: I found a pretty neat trick for removing these diagonals without having to change the vertex data. This doesn't work for anything that isn't a cube (I think), but whatever.

View file

@ -1,6 +1,6 @@
--- ---
title: "Figure Review: Atelier Ryza 2" title: "Figure Review: Atelier Ryza 2"
date: 2022-10-05 date: 2023-06-23
draft: true draft: true
tags: tags:
- Figures - Figures

View file

@ -3,6 +3,9 @@ title: "Future of Silica Viewer"
date: 2023-03-27 date: 2023-03-27
draft: false draft: false
summary: "Silica Viewer is leaving the App Store." summary: "Silica Viewer is leaving the App Store."
tags:
- Procreate
- Apple
--- ---
I will not be renewing my Apple Developer License for various reasons [I've already discussed elsewhere]({{<ref "/blog/breaking-even" >}}). It is due to expire sometime in the summer, so there's still a couple of months before it disappears off the App Store. I'm actually _losing_ money by selling my software on the App Store, and I don't really work on a Mac anymore. Plus more fun problems related to Apple infrastructure: I will not be renewing my Apple Developer License for various reasons [I've already discussed elsewhere]({{<ref "/blog/breaking-even" >}}). It is due to expire sometime in the summer, so there's still a couple of months before it disappears off the App Store. I'm actually _losing_ money by selling my software on the App Store, and I don't really work on a Mac anymore. Plus more fun problems related to Apple infrastructure:
@ -11,6 +14,6 @@ I will not be renewing my Apple Developer License for various reasons [I've alre
If you already bought Silica Viewer, nothing will change - you can continue to re-download it into perpetuity. This just means you can't pay money for it now, although I wouldn't want you to because I don't keep up with active development. As always, Silica Viewer is open source and free to use still. If you already bought Silica Viewer, nothing will change - you can continue to re-download it into perpetuity. This just means you can't pay money for it now, although I wouldn't want you to because I don't keep up with active development. As always, Silica Viewer is open source and free to use still.
![Screenshot of Silicate](macos.png) ![Screenshot of Silicate](macos.webp)
For people looking for alternative software, check out [Silicate](https://github.com/Avarel/silicate) by [Avarel](http://antran.io/). It works on more platforms than Silica Viewer, and has a better rendering engine, along with other cool features! Thank you all who have supported by using my software, as always :) For people looking for alternative software, check out [Silicate](https://github.com/Avarel/silicate) by [Avarel](http://antran.io/). It works on more platforms than Silica Viewer, and has a better rendering engine, along with other cool features! Thank you all who have supported by using my software, as always :)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View file

@ -2,7 +2,7 @@
title: "Making fail2ban work on systemd Gentoo" title: "Making fail2ban work on systemd Gentoo"
date: 2022-11-03 date: 2022-11-03
draft: false draft: false
tags: blogtags:
- Linux - Linux
- Gentoo - Gentoo
--- ---

View file

@ -0,0 +1,17 @@
---
title: "Graphics Dump: Bokeh depth of field"
date: 2023-05-27
draft: true
series:
- Graphics Dump
---
Today I implemented Bart Wronski's fantastic Bokeh depth of field effect.
# Pitfalls
Here's some of the pitfalls I ran into while implementing this:
## Make sure the bokeh image doesn't repeat, or else it will start bleeding on the edge of triangles.
## Make sure your aperture texture has a black background.

View file

@ -3,6 +3,8 @@ title: "Retrospective on three years of self-hosting"
date: 2023-03-27 date: 2023-03-27
draft: false draft: false
summary: "I've been hosting my own infrastructure for almost three years now!" summary: "I've been hosting my own infrastructure for almost three years now!"
tags:
- Website
--- ---
This website has been running almost non-stop [since November 2020](https://web.archive.org/web/20201101074137/https://redstrate.com/), according to archive.org. Since then, I have been running this website and related services myself - not physically but still taking care of admin tasks.[^1] This website has been running almost non-stop [since November 2020](https://web.archive.org/web/20201101074137/https://redstrate.com/), according to archive.org. Since then, I have been running this website and related services myself - not physically but still taking care of admin tasks.[^1]

Binary file not shown.

After

Width:  |  Height:  |  Size: 542 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 896 KiB

View file

@ -0,0 +1,79 @@
---
title: "Game Review: INFRA"
date: 2023-06-28
draft: true
tags:
- Review
- Gaming
series:
- Game Reviews
---
A little while ago, people suggested that I play INFRA. The premise is simple, you are
a man walking around and taking pictures. I won't spoil plot details of the
game, but I will show screenshots from several places in the game. So if you wish
to go in blind, I _highly_ suggest playing the game first.
---
The thing I absolutely love about this game is the environments, like the office
in the beginning of the game. INFRA is made in [Source](https://developer.valvesoftware.com/wiki/Source) (although I'm not sure
what branch it is) and the fantastic art direction combined with the outdated
Source lighting gives the game a unique vibe.
![Your office.](office.webp)
You are "Markku Siltanen", but called "Mark" by your coworkers. As part of a
consulting group, you are equipped with the gripping task of _"structural survey"_.
What this really means is taking an obscene amount of pictures on your camera
with a battery that only lasts five seconds if you leave it on. While there
is dialogue in typical Source game fashion there is not a wealth of cutscenes
and you'll have control of your character for a large part of the game. In
some sections, there are visible NPCs but you'll be lonely for most of the
game except for the occasional phone or radio call.
![Some office workers.](npcs.webp)
As you progress through the game you'll enter farther and farther into the
depths of the city. The gradual exploration aspect is really fascinating, and
there is a wealth of nature but also grimy underground facilities.
![A forest.](pretty2.webp)
![Abandoned facility.](pretty1.webp)
The game is not always a "walking simulator", but that's what you do for most
of the game. There is small puzzles here and there, and some segments
that are timed. At least for me, some of the obstacles were not straightforward
and I needed a walkthrough for later parts of the game. I never felt frustrated
though, but the game definitely does not hold your hand.
![Another overgrown facility.](sky.webp)
I'm not sure if the environments are supposed to be liminal, but it gives
off that feeling through most of the game. The sound design is also fantastic,
and I felt really immersed while playing. A lot of the game is not "signposted"
(as in, it warns you what's about to happen) so there is some intentional and
unintentional jumpscares. That's on top of the general creepiness. One of my
favorite locations is the metro, which is empty once you get there of course.
![One of the metro lines.](metro.webp)
The later half of the game puts you (mostly) above ground, with a lot of city
and urban environments in a stark contrast to the first half of the game. I also
loved the gradual transistion into night time as well, which just added to the
creepiness and unease.
![Getting closer to the city.](environment.webp)
Despite being a Source game, the environment art is so good it really carries
the graphics - although it looks dated in some spots. For example, reflections
are really simple and some environments almost look like they have no lighting.
It's just a minor gripe though, this game released a while ago and probably
started development even farther back.
![One of the less pretty environments.](reflections.webp)
If you're a fan of Source games, and urban exploration (like I am) then this
game is definitely up your alley. You can buy it [on Steam](https://store.steampowered.com/app/251110/INFRA/). Enjoy!
![Bye!](bear.webp)

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 281 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 974 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

BIN
content/blog/infra-review/sky.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -8,6 +8,8 @@ tags:
- KDE - KDE
- Qt - Qt
toc: true toc: true
series:
- My Work in KDE
--- ---
Here's my KDE contributions for this month! It's a little bit shorter than I'd like, but I'm still trying to find a nice balance between **$work** and KDE. Here's my KDE contributions for this month! It's a little bit shorter than I'd like, but I'm still trying to find a nice balance between **$work** and KDE.
@ -37,21 +39,21 @@ I finally [merged the improved dark mode I started a while ago](https://invent.k
I added [support for the new Maximize component](https://invent.kde.org/network/tokodon/-/merge_requests/200), which doesn't change anything functionality-wise but makes our code leaner: I added [support for the new Maximize component](https://invent.kde.org/network/tokodon/-/merge_requests/200), which doesn't change anything functionality-wise but makes our code leaner:
![Screenshot of the Maximize component in action!](maximize.png) ![Screenshot of the Maximize component in action!](maximize.webp)
I also [pushed along the MR to use the SearchPopupField component](https://invent.kde.org/network/tokodon/-/merge_requests/144) from Kirigami Add-ons too, which is another change that doesn't change anything functionally but will make the code much leaner. I also [pushed along the MR to use the SearchPopupField component](https://invent.kde.org/network/tokodon/-/merge_requests/144) from Kirigami Add-ons too, which is another change that doesn't change anything functionally but will make the code much leaner.
[Interaction icons were overhauled, not just visually but also their layout has improved](https://invent.kde.org/network/tokodon/-/merge_requests/211). Below is a screenshot of a mobile sized window, where the icons now spread out which will make them easier to tap (I plan on increasing the size on mobile too!) [Interaction icons were overhauled, not just visually but also their layout has improved](https://invent.kde.org/network/tokodon/-/merge_requests/211). Below is a screenshot of a mobile sized window, where the icons now spread out which will make them easier to tap (I plan on increasing the size on mobile too!)
![Screenshot of the new icons in mobile layout](new-icons.png) ![Screenshot of the new icons in mobile layout](new-icons.webp)
The [amount of characters you have left is now shown in the composer](https://invent.kde.org/network/tokodon/-/merge_requests/212), which should load from your server (I don't have anything but a 500-char limit to test with though): The [amount of characters you have left is now shown in the composer](https://invent.kde.org/network/tokodon/-/merge_requests/212), which should load from your server (I don't have anything but a 500-char limit to test with though):
![The character count shows up in the bottom-left](character-count.png) ![The character count shows up in the bottom-left](character-count.webp)
It's not merged yet, but I'm adding [overhauling how you view posts on profile pages](https://invent.kde.org/network/tokodon/-/merge_requests/214)! It has the usual separation of _"Posts"_, _"Replies"_ and _"Media"_ tabs but you can hide boosts too: It's not merged yet, but I'm adding [overhauling how you view posts on profile pages](https://invent.kde.org/network/tokodon/-/merge_requests/214)! It has the usual separation of _"Posts"_, _"Replies"_ and _"Media"_ tabs but you can hide boosts too:
![The new profile tabs and post options](profile-posts.png) ![The new profile tabs and post options](profile-posts.webp)
As a cherry on top, [I added icons to some of the menus](https://invent.kde.org/network/tokodon/-/merge_requests/217) which makes them easier to quickly navigate: As a cherry on top, [I added icons to some of the menus](https://invent.kde.org/network/tokodon/-/merge_requests/217) which makes them easier to quickly navigate:
@ -66,7 +68,7 @@ Some more minor changes:
I did some touching up work for Keysmith late this month: I fixed [a bunch of binding loops](https://invent.kde.org/utilities/keysmith/-/merge_requests/112), and added better keyboard navigation. I also [added a passive notification when you copy the code to your clipboard](https://invent.kde.org/utilities/keysmith/-/merge_requests/113) too: I did some touching up work for Keysmith late this month: I fixed [a bunch of binding loops](https://invent.kde.org/utilities/keysmith/-/merge_requests/112), and added better keyboard navigation. I also [added a passive notification when you copy the code to your clipboard](https://invent.kde.org/utilities/keysmith/-/merge_requests/113) too:
![Example of the notification](passive.png) ![Example of the notification](passive.webp)
There doesn't appear to be an active maintainer, so I'll get another reviewer and merge them next month. I also cleaned up some duplicate bugs, and moved some spam off of the tracker. There doesn't appear to be an active maintainer, so I'll get another reviewer and merge them next month. I also cleaned up some duplicate bugs, and moved some spam off of the tracker.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -8,6 +8,8 @@ tags:
- KDE - KDE
- Qt - Qt
toc: true toc: true
series:
- My Work in KDE
--- ---
# New Gamepad KCM # New Gamepad KCM
@ -53,7 +55,7 @@ See the [merge request](https://invent.kde.org/network/tokodon/-/merge_requests/
You can now select the language you're posting in! You can't view a post's language or filter them from within Tokodon yet, but it's a start[^1]. Your preferred languages (chosen through the Languages & Formats KCM if you're using KDE) is shown at the top of the list. You can now select the language you're posting in! You can't view a post's language or filter them from within Tokodon yet, but it's a start[^1]. Your preferred languages (chosen through the Languages & Formats KCM if you're using KDE) is shown at the top of the list.
![Screenshot of the language combo box](post-lang.png) ![Screenshot of the language combo box](post-lang.webp)
See the [merge request](https://invent.kde.org/network/tokodon/-/merge_requests/156). See the [merge request](https://invent.kde.org/network/tokodon/-/merge_requests/156).
@ -61,7 +63,7 @@ See the [merge request](https://invent.kde.org/network/tokodon/-/merge_requests/
Tokodon has supported viewing polls already, but not posting them. Now you can create polls! All of your usual options are exposed, including some not even shown on Mastodon Web. This is not merged yet, but will be soon. Tokodon has supported viewing polls already, but not posting them. Now you can create polls! All of your usual options are exposed, including some not even shown on Mastodon Web. This is not merged yet, but will be soon.
![Screenshot of creating a poll](adding-polls.png) ![Screenshot of creating a poll](adding-polls.webp)
See the [merge request]https://invent.kde.org/network/tokodon/-/merge_requests/152). See the [merge request]https://invent.kde.org/network/tokodon/-/merge_requests/152).
@ -84,7 +86,7 @@ Now the badge will actually update based on your current notification count, hur
Last month I redid the Window Decoration KCM, and this month I did the same for the PulseAudio KCM, although the changes needed where much smaller. Last month I redid the Window Decoration KCM, and this month I did the same for the PulseAudio KCM, although the changes needed where much smaller.
![The "new" PulseAudio KCM](pulse-pa.png) ![The "new" PulseAudio KCM](pulse-pa.webp)
See the [merge request](https://invent.kde.org/plasma/plasma-pa/-/merge_requests/157). See the [merge request](https://invent.kde.org/plasma/plasma-pa/-/merge_requests/157).
@ -100,11 +102,11 @@ For qqc2-desktop-style, I [fixed an odd case where you could select text in Text
Oliver landed the Plasma Welcome redesign for 6.0, which looks _wonderful_. As with all great features, this has had it's fair share of technical issues which I had the pleasure of helping with, including fixing this bug: Oliver landed the Plasma Welcome redesign for 6.0, which looks _wonderful_. As with all great features, this has had it's fair share of technical issues which I had the pleasure of helping with, including fixing this bug:
![Broken Plasma Welcome Toolbar](broken-toolbar.png) ![Broken Plasma Welcome Toolbar](broken-toolbar.webp)
Embedded KCMs create and manage their own QML engine. Objects like `Kirigami.ApplicationWindow` are separated though, because that exists in Plasma Welcome's engine and not the KCMs, which breaks a lot of things including the global toolbar. I figured out that you can inject your own QML engine to KDeclarative, which will fix most of the issues. While doing this, I also simplified embedded KCMs in Plasma Welcome which will help developers creating their custom pages. Embedded KCMs create and manage their own QML engine. Objects like `Kirigami.ApplicationWindow` are separated though, because that exists in Plasma Welcome's engine and not the KCMs, which breaks a lot of things including the global toolbar. I figured out that you can inject your own QML engine to KDeclarative, which will fix most of the issues. While doing this, I also simplified embedded KCMs in Plasma Welcome which will help developers creating their custom pages.
![Fixed Plasma Welcome Toolbar](fixed-toolbar.png) ![Fixed Plasma Welcome Toolbar](fixed-toolbar.webp)
There's one lingering issue -- KDeclarative get's a little bit too greedy with the engine we give it and will try to destroy it to due to `std::shared_ptr` shenanigans, but fixing it will require changes to the framework. Right now we work around the issue by not assigning a parent, but I want to look into changing that soon. There's one lingering issue -- KDeclarative get's a little bit too greedy with the engine we give it and will try to destroy it to due to `std::shared_ptr` shenanigans, but fixing it will require changes to the framework. Right now we work around the issue by not assigning a parent, but I want to look into changing that soon.
@ -138,13 +140,13 @@ See the [new repository](https://invent.kde.org/websites/kdevelop-org).
I opened an MR to update the matrix.to redirector hosted at [go.kde.org](go.kde.org/matrix) which should include a link to open in NeoChat! Once it's merged, I plan on replacing the links on the KDE Community Wiki with these instead of the WebChat links we have now. I opened an MR to update the matrix.to redirector hosted at [go.kde.org](go.kde.org/matrix) which should include a link to open in NeoChat! Once it's merged, I plan on replacing the links on the KDE Community Wiki with these instead of the WebChat links we have now.
See the [merge request](https://invent.kde.org/websites/go-kde-org/-/merge_requests/1). <!-- See the [merge request](https://invent.kde.org/websites/go-kde-org/-/merge_requests/1). -->
# Changing Notification History Order # Changing Notification History Order
This is something that's been sitting on my backlog, but I'm super annoyed about the ordering of notification history. Whenever I miss a notification[^4] I scroll through my notification history. However, it's ordered seemingly randomly, because it's sorted by "type and urgency". That's not too helpful because neither criteria is really exposed in the UI. I propose changing it to "Date" which makes way more sense for a history view of notifications. This is something that's been sitting on my backlog, but I'm super annoyed about the ordering of notification history. Whenever I miss a notification[^4] I scroll through my notification history. However, it's ordered seemingly randomly, because it's sorted by "type and urgency". That's not too helpful because neither criteria is really exposed in the UI. I propose changing it to "Date" which makes way more sense for a history view of notifications.
![The new, much more improved notification order](notifications.png) ![The new, much more improved notification order](notifications.webp)
See the [merge request](https://invent.kde.org/plasma/plasma-workspace/-/merge_requests/2659). See the [merge request](https://invent.kde.org/plasma/plasma-workspace/-/merge_requests/2659).

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

View file

@ -8,6 +8,8 @@ tags:
- KDE - KDE
- Qt - Qt
toc: true toc: true
series:
- My Work in KDE
--- ---
This is a non-comprehensive list of all of the major work I've done for KDE this month of January. I think I got a lot done this month! I also was accepted as a KDE Developer near the start of the month, so I'm pretty happy about that. This is a non-comprehensive list of all of the major work I've done for KDE this month of January. I think I got a lot done this month! I also was accepted as a KDE Developer near the start of the month, so I'm pretty happy about that.

View file

@ -0,0 +1,62 @@
---
title: "My work in KDE for June 2023"
date: 2023-06-30
draft: false
tags:
- Linux
- Open Source
- KDE
- Qt
toc: true
series:
- My Work in KDE
---
We're over halfway through year! This update is a bit smaller than usual, and more focused on applications than Plasma. This isn't for lack of time or trying, but I made a conceited effort to clear out my MR backlog - fixing more issues than piling on features. This uh... didn't really work out and I'll be trying the same goal next month. I'm also going to explain a little bit of the reasoning behind this month's changes, so maybe it could inspire or help someone.
# Tokodon
The Android build (and CI) for Tokodon was broken ever since I replaced the video player with libmpv, so I spent a good chunk of this month making sure it's working again. This was quite a doozy, but I feel much more confident about improving Craft blueprints in the future.
To anyone who is not familiar with Craft, it's a meta build system created by KDE which is also used for the GitLab CI. Craft and it's blueprints are written in Python. Blueprints describe how to build the application or library, and has easy utilities for working with existing build systems (AutoTools, CMake, Meson, etc). It may be a little daunting, but these blueprints are extremely easy to write and maintain. More importantly, Craft enables easy cross-compilation since it contains blueprints for the underlying libraries for KDE applications: OpenSSL, zlib, and so on.
The problem is that Tokodon is - to my knowledge - the first KDE application to use libmpv on Android so I needed to break a lot of new ground to make this happen.
## zlib
zlib is already included in the Android NDK, but for some reason they don't ship pkgconfig files for it (for anything, really). This is troublesome, not for libraries or applications that link to zlib directly but as it turns out, other pkgconfig files. Libraries like freetype declare dependencies for zlib, and in turn pkgconfig will complain that it can't "find zlib" although the library itself exists, but not the pkgconfig file for it. Very annoying, I have some ideas on how we could solve this but for now, we now build it again on Android.
## kirigami-addons
This is a really simple fix, QtMultimedia was missing as a dependency for this library. The new FullscreenMaximizeDelegate component uses QtMultimedia under the hood to display video, but it wasn't declared in the blueprint.
## libarchive
When using libarchive for Android, you might encounter this error when including any of it's header:
```
<put error here>
```
But a quick search revels that this bug has been known and fixed, but there wasn't a new enough version in it's blueprint. Now it's bumped to 3.6.2, which includes the fix.
## ffmpeg
Tokodon uses libmpv to display videos from Mastodon and other services, which are served over HTTPS. libmpv uses ffmpeg to fetch video data along with playback, but the blueprint for ffmpeg did not enable any TLS backend yet. Now it enables the OpenSSL backend, since we already build it.
## fribidi and mpv
Here's probably the weirdest and honestly harder-than-it-should-be error I had to fix.
Here's a rundown of the necessary changes:
* Enable zlib on Android. This is necessary because Android NDK doesn't ship a pkgconfig for their built-in zlib.
* Kirigami-addons needed the QtMultimedia dependency (because of the new FullscreenImageDelegate component).
* libarchive needs to be bumped to 3.6.2, because of an Android build bug fixed in more recent versions.
* Enable OpenSSL support in ffmpeg, so there is HTTPs playback support.
* Build fribidi and mpv statically.
# Gamepad KCM
# Misc
* Two sticker fixes stickers in NeoChat

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View file

@ -8,6 +8,8 @@ tags:
- KDE - KDE
- Qt - Qt
toc: true toc: true
series:
- My Work in KDE
--- ---
Another month in the year, another collection of bugfixes and features I contributed to KDE! Another month in the year, another collection of bugfixes and features I contributed to KDE!
@ -25,7 +27,7 @@ too, although I haven't gotten around to opening up a merge request for that.
I opened a doxyqml[^1] [merge request to make it's output more useful](https://invent.kde.org/sdk/doxyqml/-/merge_requests/16), by automatically I opened a doxyqml[^1] [merge request to make it's output more useful](https://invent.kde.org/sdk/doxyqml/-/merge_requests/16), by automatically
adding import statement hints to the page: adding import statement hints to the page:
![Example of the new doxyqml output](image.png) ![Example of the new doxyqml output](image.webp)
# Plasma 6 Porting # Plasma 6 Porting

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 413 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 212 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 441 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -8,6 +8,8 @@ tags:
- KDE - KDE
- Qt - Qt
toc: true toc: true
series:
- My Work in KDE
--- ---
I can't believe it's already the end of May! This month turned out a little meatier than last month I think, but I still have a large backlog of merge requests and TODOs to go through. I can't believe it's already the end of May! This month turned out a little meatier than last month I think, but I still have a large backlog of merge requests and TODOs to go through.
@ -16,19 +18,19 @@ I can't believe it's already the end of May! This month turned out a little meat
Now when there isn't enough space to display the QR code in the clipboard applet, there [is a clearer message of what to do next](https://invent.kde.org/plasma/plasma-workspace/-/merge_requests/2952). Now when there isn't enough space to display the QR code in the clipboard applet, there [is a clearer message of what to do next](https://invent.kde.org/plasma/plasma-workspace/-/merge_requests/2952).
![Screenshot of the new message in action.](better-qr-text.png) ![Screenshot of the new message in action.](better-qr-text.webp)
On the topic of QR codes, the menu [is now a menu of radio buttons and not checkboxes](https://invent.kde.org/plasma/plasma-workspace/-/merge_requests/2953) which didn't make sense because it's an exclusive option. On the topic of QR codes, the menu [is now a menu of radio buttons and not checkboxes](https://invent.kde.org/plasma/plasma-workspace/-/merge_requests/2953) which didn't make sense because it's an exclusive option.
![You can't have two different codes being displayed after all.](qr-radio.png) ![You can't have two different codes being displayed after all.](qr-radio.webp)
There [is now a separator above the "Close" action](https://invent.kde.org/plasma/kwin/-/merge_requests/4132) in the window menu! There [is now a separator above the "Close" action](https://invent.kde.org/plasma/kwin/-/merge_requests/4132) in the window menu!
![It now matches other context menus with this action, e.g. the Task Manager](close-action.png) ![It now matches other context menus with this action, e.g. the Task Manager](close-action.webp)
I added [a metadata extractor for Krita files](https://invent.kde.org/frameworks/kfilemetadata/-/merge_requests/97), which means certain information about your Krita artwork can show up in Dolphin, Baloo and other programs that can take advantage of it! This includes helpful information such as canvas width, height and creation date. I added [a metadata extractor for Krita files](https://invent.kde.org/frameworks/kfilemetadata/-/merge_requests/97), which means certain information about your Krita artwork can show up in Dolphin, Baloo and other programs that can take advantage of it! This includes helpful information such as canvas width, height and creation date.
![A slightly outdated screenshot, but showing off some of the metadata it can extract](krita-extract.png) ![A slightly outdated screenshot, but showing off some of the metadata it can extract](krita-extract.webp)
Soon, the Language and Region settings [will support the `$LANGUAGE` environment variable](https://invent.kde.org/plasma/plasma-workspace/-/merge_requests/2946). This only affects users who did not configure the language explicitly from KDE, like those coming from another computing environment. We already supported loading your pre-existing language from `$LANG`. Included in that merge request is a fix that stops an erroneous warning message telling you that your language isn't supported, even though it clearly is. Soon, the Language and Region settings [will support the `$LANGUAGE` environment variable](https://invent.kde.org/plasma/plasma-workspace/-/merge_requests/2946). This only affects users who did not configure the language explicitly from KDE, like those coming from another computing environment. We already supported loading your pre-existing language from `$LANG`. Included in that merge request is a fix that stops an erroneous warning message telling you that your language isn't supported, even though it clearly is.
@ -43,7 +45,7 @@ An applet name or path must be specified, e.g. --applet org.kde.plasma.analogclo
I proposed [making the icon name selectable](https://invent.kde.org/plasma/plasma-sdk/-/merge_requests/76), because I can't stop myself from clicking on it! I proposed [making the icon name selectable](https://invent.kde.org/plasma/plasma-sdk/-/merge_requests/76), because I can't stop myself from clicking on it!
![Screenshot of selecting the icon name in Cuttlefish.](cuttlefish-select.png) ![Screenshot of selecting the icon name in Cuttlefish.](cuttlefish-select.webp)
## Gamepad KCM ## Gamepad KCM
@ -63,7 +65,7 @@ Playing videos and GIFs should be less crashy, but with worse scrolling performa
You can now [change certain account preferences](https://invent.kde.org/network/tokodon/-/merge_requests/238), but the selection is limited due to lack of a proper API. These are preferences that were supported before, but now you can change them from within Tokodon. You can now [change certain account preferences](https://invent.kde.org/network/tokodon/-/merge_requests/238), but the selection is limited due to lack of a proper API. These are preferences that were supported before, but now you can change them from within Tokodon.
![The preferences you can tweak in Tokodon](tokodon-prefs.png) ![The preferences you can tweak in Tokodon](tokodon-prefs.webp)
And a whole slew of smaller stuff, some which are appearing in the next bugfix release: And a whole slew of smaller stuff, some which are appearing in the next bugfix release:
@ -72,7 +74,7 @@ And a whole slew of smaller stuff, some which are appearing in the next bugfix r
* The duplicate account [bug should _finally_ be fixed](https://invent.kde.org/network/tokodon/-/merge_requests/229)! * The duplicate account [bug should _finally_ be fixed](https://invent.kde.org/network/tokodon/-/merge_requests/229)!
* [Fix icons on non-KDE environments, such as GNOME](https://invent.kde.org/network/tokodon/-/merge_requests/228). * [Fix icons on non-KDE environments, such as GNOME](https://invent.kde.org/network/tokodon/-/merge_requests/228).
![Tokodon on GNOME!](gnome-tokodon.png) ![Tokodon on GNOME!](gnome-tokodon.webp)
For the current and future contributors, I started working on better and more detailed documentation. The first two areas I covered was [timeline models](https://invent.kde.org/network/tokodon/-/merge_requests/237) and the [account classes](https://invent.kde.org/network/tokodon/-/merge_requests/236)! For the current and future contributors, I started working on better and more detailed documentation. The first two areas I covered was [timeline models](https://invent.kde.org/network/tokodon/-/merge_requests/237) and the [account classes](https://invent.kde.org/network/tokodon/-/merge_requests/236)!
@ -101,17 +103,17 @@ I started [replacing the old foreach macro](https://invent.kde.org/education/kit
The [go.kde.org Matrix redirector update](https://invent.kde.org/websites/go-kde-org/-/merge_requests/1) is now merged, which I started in February. This means NeoChat is now preferred right below Element Web (which is still pointed towards https://webchat.kde.org/). Thanks to Thiago Sueto, [the Community Wiki has been updated already](https://invent.kde.org/teams/web/wiki-sites/-/issues/2#note_652483) and I sent two merge requests to update [kde.org](https://invent.kde.org/websites/kde-org/-/merge_requests/200) and the [footer](https://invent.kde.org/websites/hugo-kde/-/merge_requests/4). The [go.kde.org Matrix redirector update](https://invent.kde.org/websites/go-kde-org/-/merge_requests/1) is now merged, which I started in February. This means NeoChat is now preferred right below Element Web (which is still pointed towards https://webchat.kde.org/). Thanks to Thiago Sueto, [the Community Wiki has been updated already](https://invent.kde.org/teams/web/wiki-sites/-/issues/2#note_652483) and I sent two merge requests to update [kde.org](https://invent.kde.org/websites/kde-org/-/merge_requests/200) and the [footer](https://invent.kde.org/websites/hugo-kde/-/merge_requests/4).
![The updated matrix.to redirector!](webchat-matrix.png) ![The updated matrix.to redirector!](webchat-matrix.webp)
To finish off more February work, I got around to working on the two big pieces of API documentation improvements for KDE Frameworks 6. If you don't remember, I wanted to add import statements for components meant to be used in Qt Quick. Doxygen already gives us hints for C++ headers, so QML users shouldn't be left in the dust. For example, how are you even supposed to use this component? To finish off more February work, I got around to working on the two big pieces of API documentation improvements for KDE Frameworks 6. If you don't remember, I wanted to add import statements for components meant to be used in Qt Quick. Doxygen already gives us hints for C++ headers, so QML users shouldn't be left in the dust. For example, how are you even supposed to use this component?
![This is a real example. Not all components are like this, fortunately.](bad-docs.png) ![This is a real example. Not all components are like this, fortunately.](bad-docs.webp)
In order to accomplish this, subclasses of `QQuickItem` need to have their doc comments modified. The first library to get this treatment is plasma-framework, see the merge requests for [PlasmaCore](https://invent.kde.org/frameworks/plasma-framework/-/merge_requests/783), [PlasmaQuick](https://invent.kde.org/frameworks/plasma-framework/-/merge_requests/785) and [hiding ToolTipDialog](https://invent.kde.org/frameworks/plasma-framework/-/merge_requests/786). In order to accomplish this, subclasses of `QQuickItem` need to have their doc comments modified. The first library to get this treatment is plasma-framework, see the merge requests for [PlasmaCore](https://invent.kde.org/frameworks/plasma-framework/-/merge_requests/783), [PlasmaQuick](https://invent.kde.org/frameworks/plasma-framework/-/merge_requests/785) and [hiding ToolTipDialog](https://invent.kde.org/frameworks/plasma-framework/-/merge_requests/786).
For regular QML-based components, doxyqml (the tool to auto-generate QML documentation, because Doxygen lacks support for the language) needed to spit these out too. The [merge request to add import statements](https://invent.kde.org/sdk/doxyqml/-/merge_requests/16) is cleaned up, the tests fixed and ready for final review! For regular QML-based components, doxyqml (the tool to auto-generate QML documentation, because Doxygen lacks support for the language) needed to spit these out too. The [merge request to add import statements](https://invent.kde.org/sdk/doxyqml/-/merge_requests/16) is cleaned up, the tests fixed and ready for final review!
![Ah! I had to import that module!](good-docs.png) ![Ah! I had to import that module!](good-docs.webp)
I also spent some time cleaning up [the Community wiki](https://community.kde.org/), which just means I roam around and make sure links aren't dead and the formatting looks nice. If you're interested in some wiki improvement, join us in [#kde-www](https://go.kde.org/matrix/#/#kde-www:kde.org) and the [Issue board](https://invent.kde.org/teams/web/wiki-sites/-/issues)! I also spent some time cleaning up [the Community wiki](https://community.kde.org/), which just means I roam around and make sure links aren't dead and the formatting looks nice. If you're interested in some wiki improvement, join us in [#kde-www](https://go.kde.org/matrix/#/#kde-www:kde.org) and the [Issue board](https://invent.kde.org/teams/web/wiki-sites/-/issues)!

Binary file not shown.

Before

Width:  |  Height:  |  Size: 366 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

View file

@ -0,0 +1,340 @@
---
title: "Graphics Dump: Easy level building with tiny_csg"
date: 2023-06-25
draft: true
summary: "Have you ever played Half-Life 2 and infatuated with it's odd, cubic level design like I am? Well, you can use it at home!"
tags:
- C++- Math
toc: true
series:
- Graphics Dump
---
I've always been fascinated with CSG, as someone who has spent some time messing around in Valve's Hammer and Unreal Editor. However, when trying to implement CSG level geometry in my engine there's surprisingly little information! Here's a CSG tutorial I wish existed, so maybe it can help you too.
![My CSG example level.](banner.webp)
Much of the example code is ripped out of my engine, but this should give you a good enough walk-through to replicate it on your own.
# Constructive Solid Geometry
CSG stands for [Constructive Solid Geometry](https://en.wikipedia.org/wiki/Constructive_solid_geometry), a helpful technique to create complex geometry using simple primitives and boolean operators. Using CSG, it's possible to create a model in a procedural, non-destructive fashion and has been a popular tool in game engines (and CAD applications).
![A cube being cut by a boolean operation in Blender.](cube-viewport.webp)
![Finished result.](cube-render.webp)
I like video games, so naturally my first-hand experience with CSG is Source games. This is how much of the level geometry was built in those games:
![Hammer level editor, from the ["Valve Hammer Editor - Change level tutorial"](https://www.youtube.com/watch?v=VcEnQYJjeSU).](hammer.webp)
# Integration
I wanted to use CSG in my game engine, but searching online you'll get very few tutorials or even discussion about integrating it. If you have the enough prerequisite math knowledge, you might be able to get something going but I was hoping for a ready-made solution I could integrate.
Fortunately, there is one fantastic and almost-all-batteries-included library created by [Luka Aleksić](https://github.com/laleksic) called [tiny_csg](https://github.com/laleksic/tiny_csg). It's written in C++, and is perfect for the brush building tooling I wanted. Since the library uses CMake, it was easy enough to vendor into my source tree as well.
## Defining brushes
Before we can start using tiny_csg, we need some way to define the brushes in our map first. Brushes are defined by a list of planes that enclose a primitive. I'm focusing on cube primitives in this article, so we only need to worry about six planes: _front, back, left, right, bottom and top_.
Let's define an array of eight points, which correspond to each corner of the cube. Here is the points visualized:
![Points of the cube, visualized.](positions.webp)
And it can be defined like this in C++:
```cpp
std::array<float3, 8> points = {
float3{1, 1, -1}, // A
float3{1, 1, 1}, // B
float3{-1, 1, 1}, // C
float3{-1, 1, -1}, // D
float3{1, -1, -1}, // E
float3{1, -1, 1}, // F
float3{-1, -1, 1}, // G
float3{-1, -1, -1}, // H
};
```
Now that we have the points of our cube well-defined, let's move onto defining each plane that we need. Here is a list of the planes, and the points they contain:
* **Front:** B, A, E, F
* **Back:** D, C, G, H
* **Top:** A, B, C, D
* **Bottom:** H, G, F, E
* **Right:**: C, B, F, G
* **Left:** A, D, H, E
(Note that the ordering is important, and should be _counter-clockwise_.)
Using a group of these four points, you can calculate the center of a plane:
```cpp
center = (a + b + c + d) / 4.0f;
```
However a plane isn't defined by only a center, you also need to calculate a normal which is used to find the face direction. This is easy to do however, first you need a function that gives you the normal of a triangle:
```cpp
float3 triangle_normal(float3 p1, float3 p2, float3 p3) {
return normalize(cross(p1 - p2, p1 - p3));
}
```
Given a plane (a, b, c, d), you can calculate two triangles: (c, b, a) and (a, d, c). Finally, average the normals of those two triangles and you completed the plane!
## Using tiny_csg
Now that we have our list of planes defined, we can start building the level geometry using tiny_csg. This library will do the heavy lifting for us, and give us a list of triangles to render with.
First, create the world and set the void volume:
```cpp
csg::world_t world{};
world.set_void_volume(AIR);
```
There is no predefined volume types, so you need to define your own:
```cpp
constexpr csg::volume_t AIR = 0;
constexpr csg::volume_t SOLID = 1;
constexpr csg::volume_t WATER = 2;
...
```
Create a brush_t with `csg::world_t::add()` and set the planes and the kind of volume it is:
```cpp
auto brush = world.add();
brush->set_planes(get_planes()); // a list of the planes we created earlier.
brush->set_volume_operation(csg::make_fill_operation(SOLID));
```
Next, call `world_t::rebuild()` to begin the level building process. The result is faces and fragments we can then use to rasterize the brushes! It's a linked list, so to iterate it start with `world_t::first()` and get the next brush in the list using `world_t::next()`:
```cpp
csg::brush_t* brush = world.first();
if (brush) {
while (brush) {
...
brush = world.next(brush);
}
}
```
To start looping through the triangles, use `brush_t::get_faces()` and loop through the faces, and then the fragments of said faces:
```cpp
auto faces = brush->get_faces();
for (csg::face_t& face : faces) {
for (csg::fragment_t& fragment : face.fragments) {
const auto triangles = csg::triangulate(fragment);
// process the triangles...
}
}
```
You'll want to discard any fragments that are touching two of the same volume type. For example, air touching air would contribute a lot of unnecessary geometry:
```cpp
const csg::volume_t front = fragment.front_volume;
const csg::volume_t back = fragment.back_volume;
// Discard air/air and solid/solid polygons
if (front == back)
continue;
```
Now let's deep dive into how to process these triangles, and some pitfalls you might run into.
## Triangulation
tiny_csg will triangulate the brush fragments for you, but it's up to you to calculate things like texture coordinates, normal, tangents/bitangents and more. Those are all pretty easy though, so let's start with normals.
### Normals
To calculate normals, you can just take the normal of the plane the face is part of:
```cpp
for (auto triangle : triangles) {
float3 normal = face.plane->normal;
...
}
```
However, make sure that when the back is a void volume (like `AIR`), that you _flip_ the normal:
```cpp
for (auto triangle : triangles) {
float3 normal = face.plane->normal;
if (back == AIR) {
normal = -normal;
}
...
}
```
When you intersect a solid with a void brush, the new geometry created to fill the hole is calculated _from_ the void brush - meaning that the normals are facing the wrong direction. It's technically correct for the void brush, but not the hole.
If you are building an index list, I think you also want to flip it as well but it might not be needed.
### Texture coordinates
Texture coordinates are relatively easy to calculate as well, first set up a loop iterating through all the triangles.
```cpp
for (std::size_t i = 0; i < indices.size(); i += 3) {
const float3 v1 = vertices[indices[i]].position;
const float3 v2 = ...;
const float3 v3 = ...;
}
```
Calculate a face normal, and also check if all of the components do not equal zero:
```cpp
float3 normal = cross(v3 - v1, v2 - v1);
if (normal.x == 0.0f && normal.y == 0.0f && normal.z == 0.0f) {
continue;
}
```
Next we want to create a rotation that looks "towards" this normal:
```
Quaternion rotation = look_rotation(float3{0, 0, 1}, normal);
```
Then for each vertex in this triangle, we can multiply it component-wise to create a pretty nice distribution. I included an extra `scale` variable that I can adjust on the whole brush.
```cpp
vertices[indices[i]].uv = float2{(rotation * v1).x, (rotation * v1).y} * scale;
vertices[indices[i + 1]].uv = float2{(rotation * v2).x, (rotation * v2).y} * scale;
vertices[indices[i + 2]].uv = float2{(rotation * v3).x, (rotation * v3).y} * scale;
```
## Tangents and bitangents
This one is a little bit more difficult, and I ended up going with a widely used library called Mikktspace to calculate these. It's interface is a little obtuse at first too. You need to create a `SMikkTSpaceInterface` and assign a bunch of functions it will use to grab and store triangle data. I used lambdas for these, and assigning userdata:
```cpp
SMikkTSpaceInterface iface = {};
iface.m_getNumFaces = [](const SMikkTSpaceContext *ctx) -> int {
const CSGMesh *m = static_cast<const CSGMesh *>(ctx->m_pUserData);
return m->indices.size() / 3;
};
iface.m_getNumVerticesOfFace = [](const SMikkTSpaceContext *, const int) -> int {
return 3;
};
iface.m_getNormal = [](const SMikkTSpaceContext *ctx, float normals[],
const int iface, const int ivert) {
const CSGMesh *m = static_cast<const CSGMesh *>(ctx->m_pUserData);
int i = iface * 3 + ivert;
memcpy(normals, m->vertices[i].normal.ptr(), sizeof(float3));
};
iface.m_getTexCoord = [](const SMikkTSpaceContext *ctx, float texcoords[],
const int iface, const int ivert) {
const CSGMesh *m = static_cast<const CSGMesh *>(ctx->m_pUserData);
int i = iface * 3 + ivert;
memcpy(texcoords, m->vertices[i].uv.ptr(), sizeof(float2));
};
iface.m_getPosition = [](const SMikkTSpaceContext *ctx, float position[],
const int iface, const int ivert) {
const CSGMesh *m = static_cast<const CSGMesh *>(ctx->m_pUserData);
int i = iface * 3 + ivert;
memcpy(position, m->vertices[i].position.ptr(), sizeof(float3));
};
iface.m_setTSpaceBasic = [](const SMikkTSpaceContext *ctx, const float tangent[], const float sign,
const int iface, const int ivert) {
const CSGMesh *m = static_cast<const CSGMesh *>(ctx->m_pUserData);
int i = iface * 3 + ivert;
float4 t{tangent[0], tangent[1], tangent[2], sign};
memcpy(m->vertices[i].tangent.ptr(), t.ptr(), sizeof(float4));
};
```
(This code could absolutely be improved!)
After you created your interface, you can then create a context and assign your userdata and then start the tangent process.
```cpp
SMikkTSpaceContext ctx;
ctx.m_pUserData = &cgMesh;
ctx.m_pInterface = &iface;
genTangSpaceDefault(&ctx);
```
## Bullet
It's also really easy to plug the triangle data straight into Bullet too, if that's the physics engine you're using. Here's the snippet if you also want Bullet integration:
```cpp
csg::brush_t* brush = scene.world->first();
if (brush != nullptr) {
while (brush) {
auto faces = brush->get_faces();
for (csg::face_t& face : faces) {
for (csg::fragment_t& fragment : face.fragments) {
const csg::volume_t front = fragment.front_volume;
const csg::volume_t back = fragment.back_volume;
if (front == back) // discard air/air and solid/solid polygons.
continue;
const auto triangles = csg::triangulate(fragment);
for (auto triangle : triangles) {
brushes_positions.push_back(fragment.vertices[triangle.i].position.x);
brushes_positions.push_back(fragment.vertices[triangle.i].position.y);
brushes_positions.push_back(fragment.vertices[triangle.i].position.z);
brushes_indices.push_back(brushes_indices.size());
brushes_positions.push_back(fragment.vertices[triangle.j].position.x);
brushes_positions.push_back(fragment.vertices[triangle.j].position.y);
brushes_positions.push_back(fragment.vertices[triangle.j].position.z);
brushes_indices.push_back(brushes_indices.size());
brushes_positions.push_back(fragment.vertices[triangle.k].position.x);
brushes_positions.push_back(fragment.vertices[triangle.k].position.y);
brushes_positions.push_back(fragment.vertices[triangle.k].position.z);
brushes_indices.push_back(brushes_indices.size());
}
}
}
brush = scene.world->next(brush);
}
}
auto *index_vertex_array = new btTriangleIndexVertexArray(brushes_indices.size() / 3,
const_cast<int *>(reinterpret_cast<const int *>(brushes_indices.data())),
sizeof(int) * 3,
brushes_positions.size(),
const_cast<btScalar *>(brushes_positions.data()),
sizeof(btScalar) * 3);
const bool quantized_aabb_compression = false;
auto *shape = new btBvhTriangleMeshShape(index_vertex_array, quantized_aabb_compression);
```
# Results
The result is pretty amazing, here is a quick walk-through of a level I made using CSG:
{{< tube "https://tube.ryne.moe/videos/embed/b11d3bb5-cec9-4109-8a01-bc9b0e60d92c" >}}
# Credits
* Luka Aleksić for the amazing tiny_csg library!
* This [StackExchange answer](https://gamedev.stackexchange.com/a/147030) by "DMGregory" which suggested using Mikktspace for creating tangent and bitangent vectors.
* This [StackExchange answer](https://gamedev.stackexchange.com/a/139955) by "DMGregory" again which suggested how to calculate texture coordinates for arbitrary triangles.

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View file

@ -2,10 +2,9 @@
title: "Graphics Dump: Mesa, Vulkan and DRM" title: "Graphics Dump: Mesa, Vulkan and DRM"
date: 2022-11-15 date: 2022-11-15
draft: false draft: false
tags: blogtags:
- Vulkan - Vulkan
- Linux - Linux
- Graphics Dump
- KDE - KDE
comments: comments:
host: mastodon.art host: mastodon.art

Some files were not shown because too many files have changed in this diff Show more