| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
qmatrix4x4.h will lose its qquaternion.h include, so include
qquaternion.h explicitly in all files that mention 'QQuaternion',
unless, for a foo.cpp, the own foo.h has already included it.
Picking all the way back, even though the include removal won't be
picked as far back, because it's the correct thing to do and cannot
fail.
Also add forward declarations, where they suffice.
Pick-to: 6.10 6.9 6.8 6.5
Change-Id: Ibfc1e941978c750c05e57e3772f3a68bc921c81f
Reviewed-by: Volker Hilsheimer <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is a debugging tool for viewing Qt's baked lightmap files. While
users can use this tool, it is intended for development only.
The tool is both a GUI tool for viewing lightmaps and a command line
application that accepts flags for printing info and extracting the
content of the lightmap file.
Pick-to: 6.10
Change-Id: I95279e248ea82e0e1384bbf880dcecc7af778dfe
Reviewed-by: Laszlo Agocs <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Improves the collection of nodes and rendering data during the preparation
phase by:
- Only traversing and collecting nodes when the node tree changes.
- Assigning a unique ID to each node in the tree for fast access to its
associated rendering data.
- Having a single root node for the entire window. If there are multiple
views within a window, they all operate on their respective sections
of the tree.
- Storing rendering data separately which avoids collecting and copying
in addition to make it more feasibly to just uploading the data in bulk
when needed.
- Proper separation of data allows for the calculation of non-dependent
data in parallel, once the global state has been updated.
This is merely the initial step towards a more advanced storage solution.
However, some adjustments are still necessary to transition a significant
portion of the preparation phase to the GPU. Our somewhat contrived
benchmark demonstrates a 6x improvement, which is also applicable to the
worst case scenario when nodes are dynamically added.
Change-Id: I1dd12734f6a043ca8145cb1c667921bb664aa3db
Reviewed-by: Christian Strømme <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This amends 64821f3552aa7f3826de945141f1e3c16f175bc1 as the logic for
adjusting the view count in sub-views was done after the effects was
processed causing the queried view count to be out of sync.
This change also touches the general state tracking the layer node, to
make it more consistent and ensure the dependencies on the layer state
is processed in order.
Fixes: QTBUG-132811
Pick-to: 6.9 6.8
Change-Id: Idc4c78184f4af3834505c5d6c130e8212ee5837d
Reviewed-by: Andy Nichols <[email protected]>
|
|
|
|
|
|
|
|
|
| |
The code evidently relied on a transitive include of the QDebug header.
Include it explicitly to follow up on cleaning up changes elsewhere.
Pick-to: 6.9
Change-Id: Ifb30262309d599e08557aabd803b1ec378c82f36
Reviewed-by: Christian Strømme <[email protected]>
|
|
|
|
|
|
|
|
| |
Follow up on change in qtbase:577946c1f05aaaa2a3f9682001aeb4144386b26b.
Task-number: QTBUG-129575
Change-Id: Iaec6daeca8299c2f3a2048635112cbdf864b8d56
Reviewed-by: Allan Sandfeld Jensen <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When using instanced model's customData, it can be used
only with CustomMaterial.
It will not fully support instancing's all the feature
but customData and color of InstanceEntryList are
enough to check the shading effect for current material.
They will be mapped to INSTANCE_DATA and INSTANCE_COLOR
in vertex shader.
When using instacing, Preview will show 5 instances and
the center object in position (0, 0, 0) is affected by
modified properties.(color and customData)
This object's index(INSTANCE_INDEX) is 0 and it can
be used in vertex shader, too.
Change-Id: Ied2fbf456366d52a41cb6ef2d1dbab266d38112a
Reviewed-by: Andy Nichols <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
There is no feature datastream, so this disabled compilation of the tool
on all configurations.
Fixes a regression introduced in 4f042b2ebb0bc.
Pick-to: 6.8
Fixes: QTBUG-127326
Change-Id: Id330449def1c2f182cc1d357c3a1b507066bc22e
Reviewed-by: Jari Helaakoski <[email protected]>
Reviewed-by: Alexandru Croitor <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
| |
Currently spotlight shadows requires rendering six times. This changes
it to only require one depth map. Piggybacks the directional lights
texture array usage, so they both go through that path now.
Task-number: QTBUG-116885
Pick-to: 6.8
Change-Id: I4a23c8b22a1918d1e0ce2cfe5ac594bb527975c7
Reviewed-by: Jonas Karlsson <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
| |
According to QUIP-18 [1], all tools should be
LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
[1]: https://contribute.qt-project.org/quips/18
Pick-to: 6.7 6.8
Task-number: QTBUG-121787
Change-Id: I0883ded9f64fcf8107c397a837149133911f2951
Reviewed-by: Kai Köhne <[email protected]>
|
|
|
|
|
|
|
|
|
| |
Commit fixes mimetype, quick_shadereffect, cborstreamwriter, datastream and
localserver features.
Task-number: QTBUG-122999
Change-Id: If4850f37b2047edb59de198741111e731c0f0669
Reviewed-by: Alexandru Croitor <[email protected]>
|
|
|
|
|
|
|
|
|
| |
Won't work still, but for reasons different than before.
Plus some qmlxr test assets.
Change-Id: Ia7a81b0310d4006b14354e5d897493a73b142537
Reviewed-by: Andy Nichols <[email protected]>
|
|
|
|
|
|
|
|
| |
`m_ready` is apparently not used, causing a clang warning to be emitted
Pick-to: 6.7
Change-Id: Ibb56e91ebc7a99c951a12fe52c12b84d1c8f0c30
Reviewed-by: Laszlo Agocs <[email protected]>
|
|
|
|
|
|
|
| |
That's somewhat misleading and makes gcc 12 produce bogus warnings.
Change-Id: Ic563bba09a8baec34f07dacf774463399f902d15
Reviewed-by: Giuseppe D'Angelo <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Make the following functional in custom materials:
MODELVIEWPROJECTION_MATRIX
VIEWPROJECTION_MATRIX
VIEW_MATRIX
PROJECTION_MATRIX
INVERSE_PROJECTION_MATRIX
CAMERA_POSITION
CAMERA_DIRECTION
This is done by appending [gl_ViewIndex] after substitution.
For example, VIEWPROJECTION_MATRIX[1][2] becomes
qt_viewProjectionMatrix[gl_ViewIndex][1][2].
Change-Id: I546f465fb31aa497505f45d0197f564810593fb3
Reviewed-by: Qt CI Bot <[email protected]>
Reviewed-by: Andy Nichols <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
| |
...and for 2D content. Thus the xr_simple example is functional with
QT_QUICK3D_XR_MULTIVIEW=1 and a 3D API that has multiview support.
Apart from the modelview-projection matrix, any other camera-related
features are not yet multiview-aware.
Change-Id: Ic4f07d6da375ab3ebf57b2984a020d38790ae392
Reviewed-by: Christian Strømme <[email protected]>
Reviewed-by: Qt CI Bot <[email protected]>
|
|
|
|
|
| |
Change-Id: Ie69a05dde7643d05b5542e1419aa35e59b9bf4b0
Reviewed-by: Jonas Karlsson <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Extends the per extension storage with per camera storage as well,
allowing to properly store data specific to the camera being used.
Note that this still has some limitation, e.g., it's expected that the
camera instance is unchanged within a frame.
Since the frustum culling is now done when building the sorted node lists,
it's applied more widely (when enabled), which means, e.g., the shadow map
will also have its nodes culled. This is a problem due to how the
shadow map code is implemented, as it's already doing it wrong, it something
that needs to be fixed separately.
Taks-number: QTBUG-116570
Change-Id: I9c77648ed82635f14f26ab8260c8b3e7127dd0f1
Reviewed-by: Andy Nichols <[email protected]>
|
|
|
|
|
|
| |
Change-Id: I6016c54dde9564f85469b70034a215f66879fb23
Reviewed-by: Christian Strømme <[email protected]>
Reviewed-by: Qt CI Bot <[email protected]>
|
|
|
|
|
|
|
|
|
|
| |
The export functionality didn't work on windows as the path for
exporting the component was not resolved correctly.
Fixes: QTBUG-118806
Pick-to: 6.6 6.5
Change-Id: I050c6dad23e4bd64fdba03814d961f6e49a683a7
Reviewed-by: Tomi Korpipää <[email protected]>
|
|
|
|
|
|
| |
Task-number: QTBUG-116570
Change-Id: Id8fafb80dd19567bf3d1647d9385003ab0de32f0
Reviewed-by: Laszlo Agocs <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
| |
The QSSGRenderContextInterface is the main hub for all the internal
sub-components. Note that while the RCI is exposed, it doesn't mean all
the sub-components are exposed as well. Depending on the component some
might be exposes with a semi-public API while others still will require
the use of private headers.
Task-number: QTBUG-116570
Change-Id: Iad0d0069fbdfd8b66af6f3d020659395989b49dc
Reviewed-by: Laszlo Agocs <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
| |
Having this as a member of the renderer is kind of weird, and also leads to
interesting, and hard to read code for those not already initiated.
The class is due for some modernization, but for now just continue
keepng the cached version around.
Task-number: QTBUG-116570
Change-Id: If0cf8b7b75319d2f57199bce821e8d68461817ea
Reviewed-by: Laszlo Agocs <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
All these TUs relied on transitive includes of qpointer.h, maybe to a
large extent via qevent.h, though, given that qevent.h is more or less
the only public QtBase header that includes qpointer.h, something else
seems to be at play here.
Said qevent.h actually needs QPointer in-name-only, so a forward
declaration would suffice. Prepare for qevent.h dropping the include.
The algorithm I used was:
If the TU mentions 'passiveGrabbers', the name of the QEvent function
that returns QPointers, and the TU doesn't have qpointer.h included
explicitly, include it. That may produce False Positives, but better
safe than sorry. Otherwise, in src/, add an include to all source and
header files which mention QPointer. Exception: if foo.h of a foo.cpp
already includes it, don't include again.
Task-number: QTBUG-117670
Change-Id: I7840274c42334e6d2f7baf32a09dbd25bc462fc3
Reviewed-by: Fabian Kosmale <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
By adding it to the default build flags via .cmake.conf.
This disables the 3-arg QObject::connect() overload:
QObject::connect(sender, signal, functor)
For details see:
https://lists.qt-project.org/pipermail/development/2023-July/044141.html
Task-number: QTBUG-116296
Change-Id: I6ccca69c7cf214e826e35d8c221b067a2587c79a
Reviewed-by: Volker Hilsheimer <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We need to export the type as a value type, and also export its enums
in a namespace. This resulted in duplicated entries in the qmltypes
file, which confuses Qt Design Studio.
Fix it by introducing a derived class, and using it for exporting the
enums.
Fixes: QTBUG-115362
Pick-to: 6.6 6.5
Change-Id: I7a052592961fcbcecb8b48757a9babaa79d81f77
Reviewed-by: Fabian Kosmale <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
| |
Part of the effort to improve the API of some of our internal class'.
This means we don't need to expose the specific material types, this is
the callers responsibility to check. All our graph objects have type
info.
Pick-to: 6.6
Change-Id: I1fe13962920a827e4be7c6d4842d7d36b6bb6fcd
Reviewed-by: Andy Nichols <[email protected]>
|
|
|
|
|
|
| |
Pick-to: 6.6
Change-Id: I23c6fa951b566ddf87390ec6c14276cf5b63b0e8
Reviewed-by: Christian Strømme <[email protected]>
|
|
|
|
|
|
|
|
| |
A new mesh version has a separate morph target buffer and
this information should be printed by meshdebug.
Change-Id: I475e54f63e75ef73368012cfb505f981c093f0ca
Reviewed-by: Jonas Karlsson <[email protected]>
|
|
|
|
|
|
| |
Task-number: QTBUG-113331
Change-Id: I48aa18f2fb4a76d8eabe665d22e1bb3de5b3018c
Reviewed-by: Volker Hilsheimer <[email protected]>
|
|
|
|
|
|
| |
Pick-to: 6.5
Change-Id: I889c0c5f45f7b93b9512bd81fb39ae026df7056d
Reviewed-by: Andy Nichols <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
| |
The QSSGRef class is probably going away and as with our internal pass
API the RCI, as a central piece of our code, should also move away from
using the QSSGRef class. The ownership is also much stricter controlled
now.
Pick-to: 6.5
Change-Id: I123974a54287b93a7eb99557470501de7d4a2b66
Reviewed-by: Andy Nichols <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
| |
Move the RCI to the window attachment and get rid of the old global
storage. The RCI is per-window, same as the window attachment, so
it make sense to keep them together. The releaseCachedResources is
also tied to the window attachment, which means we can have a more
flexible callback system, for when cached resources should be cleared.
Pick-to: 6.5
Change-Id: If32318cdc492ed2303062523a969395706c84a4e
Reviewed-by: Christian Strømme <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
| |
There's no need to have multiple function that return the raw pointer
from QSSGRef. The data() function is also not compatible with e.g.,
smart pointers from the standard library, which we eventually will
replace some of the existing QSSGRef usages with.
Pick-to: 6.5
Change-Id: If9a3c3cac65123dca7a310501caa5ee942eda7a5
Reviewed-by: Andy Nichols <[email protected]>
|
|
|
|
|
|
|
|
|
| |
The qtquickcontrols2.conf file is not picked up when under the URI
resource path.
Pick-to: 6.5
Change-Id: I980fb01818711a256e01d462af4dba5bd05184d5
Reviewed-by: Kaj Grönholm <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Embedded textures are not always used by "*" + number format.
Since GetEmbeddedTextureAndIndex in assimp supports to get index
and name at the same time, it will be used instead of previous
logic.
If an embedded texture has a compressed format, the format hint
should be delivered to QImageReader.
TextureData has a member, 'fmt', related to the image format,
but it was not used. It will be used as the format hint, so
the type is changed to QByteArray.
Fixes: QTBUG-110918
Pick-to: 6.5
Change-Id: I33cc7871073bca383fc007dd8eaac38ebe7910ab
Reviewed-by: Christian Strømme <[email protected]>
|
|
|
|
|
|
|
|
|
| |
As suggested by the warning from code using the labs settings api, we
should from 6.5 use the one in core.
Pick-to: 6.5
Change-Id: I0b439dc15a932e0d99b3e5cd76d01f6ca8211b22
Reviewed-by: Andy Nichols <[email protected]>
|
|
|
|
|
|
|
|
|
|
| |
This fixes bug introduced in 44eb90389
Taks-number: QTBUG-111000
Pick-to: 6.5 6.4
Change-Id: I639f1ee2c0e882d898e339ab61d73c235ec5b87d
Reviewed-by: Kristoffer Skau <[email protected]>
Reviewed-by: Andy Nichols <[email protected]>
|
|
|
|
|
|
|
|
|
| |
Moved under the QSSGBaseTypeHelpers scope and moved out of the
header as there's no need to inline all these.
Pick-to: 6.5
Change-Id: Ibdf298d598d01c6e1ed9d81c0fc5120ccb910fb0
Reviewed-by: Andy Nichols <[email protected]>
|
|
|
|
|
|
|
|
|
|
| |
Add support for overriding materials and properties of
imported assets. The modifications are read from a JSON
file.
Task-number: QTBUG-106952
Change-Id: I905e1337bc4bcf9c371152f4f3e43472d2b6d2ef
Reviewed-by: Christian Strømme <[email protected]>
|
|
|
|
|
|
|
|
|
| |
See also
https://www.reddit.com/r/QtFramework/comments/yle4im/how_to_change_qt_global_parameters/
Change-Id: I269d12fc34d21322c8848784255ab03600576d18
Reviewed-by: Andy Nichols <[email protected]>
|
|
|
|
|
|
| |
Task-number: QTBUG-106952
Change-Id: I36a3fbb756dafe89ebc95ffd43c9e78fd06eaa02
Reviewed-by: Christian Strømme <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Introduces a new version of the mesh file format that stores
additional levels of detail that are generated by using using
meshoptimizer to simplify the original geometry of each subset.
The simplify process returns a list of new range of index values
that should be used when rendering a mesh at a particular level
of detail, as well as an ideal "distance" which manifests itself
as a ratio of how many pixels will be used to render the mesh.
The idea is that if a model will only be rendered as a small ratio
of screen space, then the full resolution geometry is not needed
to get the same result.
Part of the refinement of the simplification process is to add
additional vertices to lod levels where the attributes such as
vertex normals no longer make sense using the original index. In
this case the attributes are recalculated using the new indexes
of the simplified level of detail.
Currently generation of mesh levels of detail is off by default since
some tweaking may be necessary for the best results. This should instead
be an explicit choice by the user on import via the tooling.
Change-Id: I2a2bc0b75aa30284a40241bdf7b90ff072a0fcac
Reviewed-by: Laszlo Agocs <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
| |
Apple's clang says:
error: suggest braces around initialization of subobject
[-Werror,-Wmissing-braces]
and errors out with the -Werror default configuration.
Change-Id: I334a7a0b445d35e2a94cc66200691df840cb3e7e
Reviewed-by: Christian Strømme <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Implemented for default/principled materials and custom materials and
effects. For effects some changes are done to avoid the problem of
colliding hash keys in the first level effect cache. In a somewhat
similar manner, the QQsbCollection is updated to use different kind of
keys (like a string with a hex sha, not a uint64 from qHash).
Relies on a new shadertools API that allows shader baking to skip
target versions that fail in SPIRV-Cross. (because we try to bake
everything, but so have to deal gracefully with things like GLSL ES
100 not having textureSize() etc.)
The cache location is the QStandardPath::CacheLocation, so e.g.
Users\<user>\AppData\Local\<appname>\cache. The .qsbc file is under a
directory q3dshadercache-<buildabi>.
.qsbc files now store the Qt version they were built with. If there
is a mismatch, the file will be ignored, and upon saving it will be
replaced with new content. (this is identical to how the low-level
pipeline cache works when there is a mismatch)
This is an important change for pregenerated materials: previously any
.qsbc file was loaded, whereas now even a difference in the Qt patch
version will make the prebuilt data to get ignored. This is in theory
not great for apps that build against one version and then replace the
Qt libs with a newer version without rebuilding the app. Then again
there is no compatibility guarantee for the material shader generator,
so rejecting something from an older version is the right thing to do.
To facilitate this and the key change, the version of .qsbc files is
bumped. We do not support loading the old format.
Eventually an API on some level to control the file location may get
added (just like Qt Quick has QQuickGraphicsConfiguration APIs to
control the low-level pipeline cache). This may be interesting in
particular because the usual caveats apply with multiple windows: the
last window that closes wins, that's the one that gets to write out
its cache. (there is only a single file) The story here is identical
to Qt Quick: If one wants to have proper control over this, they need
to explicitly specify the file location on a per-window basis (not per
View3D, though, which may complicate things).
The persistent caching can be disabled using the existing mechanisms,
meaning disabling the Qt Quick pipeline cache (or the Qt 5 era
QOpenGLShaderProgram disk cache) will also disable this one. One can
set Qt::AA_DisableShaderDiskCache, or the env.var
QT_DISABLE_SHADER_DISK_CACHE or its QSG_RHI_... equivalent. This way
we do not need a Quick3D-specific setting at all.
For development purposes it can be handy to disable just the loading
of a possibly exising cache, while keeping the saving intact
(i.e. this allows overwriting any existing cache data when changing
the material shader generator, without running into problems due to
loading cached data from a Quick3D build without the latest
changes). To do this, set QT_QUICK3D_NO_SHADER_CACHE_LOAD to a
non-zero value.
To confirm what is happening under the hood, set the usual
QT_RHI_SHADER_DEBUG env.var. This will cause:
- upon QSSGShaderCache construction the printing of something like the
following, if there is an existing cache:
Attempting to seed material shader cache from <filename>
Loaded 15 shader pipelines into the material shader cache
- then on each default/custom material lookup it shows one of:
* nothing (if the highest level, runtime cache were hit, i.e. we
saw the material before during the run of the application),
* or it prints something along the lines of "Loading rhi shaders
from disk cache for <cache key> (<material key>)". That is when a
new QSSGRhiShaderPipeline was created on the cheap path,
i.e. when the QShaders are coming from the .qsbc file.
* Finally, if it prints the shader source code then it's on the
slow path with generating and processing the shaders.
A dedicated documentation page will likely need to be introduced
separately. That is however postponed until we get an idea if there
will be dedicated APIs to control the cache location or not.
Change-Id: I166f72c3f2f4ea0fbcf0b0af658117cdc537b241
Reviewed-by: Andy Nichols <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Store the global bounds in the renderable as we'll have use for that
later, e.g., culling. Also, the type was removed from
the renderable flags, as the type will never be reset or changed during
the lifetime of the object. We know the type at creation and is never
going to change. Having a fixed type means it's easier to make sensible
assumption about the object when it's e.g., created.
Task-number: QTBUG-106958
Change-Id: I459734725792b4a7d7fbe4fa88707277e3377b68
Reviewed-by: Christian Strømme <[email protected]>
|
|
|
|
|
|
|
| |
"Material Editor" is a bit to generic and conflicts with DS.
Change-Id: I716a15c609dd765c37769dba91b6e22ba4530b70
Reviewed-by: Laszlo Agocs <[email protected]>
|
|
|
|
|
|
|
|
| |
.. for some reason this is needed
Pick-to: 6.4
Change-Id: Ib25d9c0a350b5eb367efd491387be452d8e486b4
Reviewed-by: Andy Nichols <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
| |
Move some stuff into a base class (QQsbCollection) then have
two subclasses, the existing QIODevice-based one as
QQsbIoDeviceColletion and a new QQsbInMemoryCollection.
When using the latter's save and load functions, the file format is
exactly the same as with the former.
Change-Id: I1984f39b10c43d70b91ad341c12b0f8b6beb3b0c
Reviewed-by: Andy Nichols <[email protected]>
Reviewed-by: Qt CI Bot <[email protected]>
|
|
|
|
|
|
|
|
|
|
| |
After the previous change to a more dynamic data structure, create()
just forwarded to new. Using new directly instead makes the code more
readable and less error prone.
Task-number: QTBUG-106952
Change-Id: Ib9b6e80b8b5f55081b0d07e8e9517c103e917998
Reviewed-by: Christian Strømme <[email protected]>
|