diff --git a/doc/features.dox b/doc/features.dox index eb8eccef4..e9328c959 100644 --- a/doc/features.dox +++ b/doc/features.dox @@ -26,10 +26,146 @@ namespace Magnum { /** @page features Feature guide -@brief Fundamental principles and design goals. +@brief High-level introduction to design of the Magnum library and basic building blocks. -Overview and tutorials of high-level feature groups in Magnum. It's not -necessary to read through everything, pick only what you need. +@tableofcontents + +@todoc FUCK OFF doxygen, why are you not able to link to Corrade, Corrade::Utility and Magnum/Math/ you dumb shit?! + +Before you continue further, here are the essential bits of knowledge to help +you around. + +@section features-naming Library organization and naming scheme + +The @ref Magnum project consists of a library with core functionality and +optional sub-libraries. Each library is in its own namespace, which corresponds +to a sub-folder on the include path -- so e.g. things from @ref Magnum::Math +are included from @m_class{m-doc} [Magnum/Math/](dir_d816e7cf853e6723911731706bcab386.html). +@ref Magnum builds upon +@m_class{m-doc-external} [Corrade](https://doc.magnum.graphics/corrade/), which +provides platform abstraction, basic utilities and containers. + +To reduce redundant verbosity, references throughout the documentation and +code in example snippets have the the root @ref Magnum and +@m_class{m-doc-external} [Corrade](https://doc.magnum.graphics/corrade/namespaceCorrade.html) +namespaces omitted. In other words, as if the following was done: + +@snippet Magnum.cpp features-using-namespace + +If Magnum is the primary library you're building your project on, it's +recommended that you do the same --- we're careful to not pollute the root +namespace with overly generic names. However, except for `Literals` namespaces, +@cpp using @ce the subnamespaces is *not recommended*, as naming in those is +deliberately picked short and may introduce conflicts (such as +@relativeref{Corrade,Containers::String} vs +@relativeref{Corrade,Utility::String} or @ref GL::PixelFormat vs +@ref Vk::PixelFormat). + +If you frown upon the thought of @cpp using namespace Magnum @ce yet don't want +to wear your fingers off by repeatedly writing @cpp Magnum:: @ce everywhere, a +common shorthand that projects go with is the following --- similarly in spirit +to @cb{.py} import numpy as np @ce: + +@snippet Magnum.cpp features-using-namespace-alias + +@section features-includes Include files and forward declarations + +Depending on where you come from, the @cpp #include @ce policy used by Magnum +might either make you happy or freak you out. In short, there's no "include the +world" file, and instead you're supposed to include dedicated headers for APIs +you want to use. The main reason is compile times, and the speed gain from +doing it this way is too great to be ignored. + +The general rule is that each top-level class has a corresponding include, so +for example @ref Math::Matrix4 is included as @ref Magnum/Math/Matrix4.h. It's +not always like that though, and to help you out, documentation of each +namespace and class tells you what to include, and if particular namespace +members are defined in different headers, then detailed docs of each has a +corresponding @cpp #include @ce directive listed as well, ready to be copied. + +In order to have the includes actually independent of each other, most Magnum +types are forward-declared, and where possible, the header only relies on +forward declarations. Which means that often the type already exists as a +declaration, and in order to actually use it, you have to include the concrete +definition of it. If you don't, the compiler will complain about use of an +incomplete type. For example: + +@snippet Magnum.cpp features-forward-declaration-use + +Of course not all headers can be written with just forward declarations, so +there still are some transitive dependencies between headers (for example, the +@ref Magnum/Math/Matrix4.h header pulls in @ref Magnum/Math/Vector4.h as well). +But from most part this is an implementation detail and as such shouldn't be +relied on. + +For happy compile times you're encouraged to rely on forward declarations in +your code as well. See @ref compilation-forward-declarations for more +information. + +@section features-debug-output Debug output + +One of the essential debugging workflows is inspection of variable contents by +printing them out. Magnum defines a lot of new math types, enums and +containers and it would be very painful if you had to loop over their contents +or perform manual enum-to-string conversion every time you want to see what's +inside. + +Because writing to standard output and printing values for debugging purposes +are *distinct* use cases with potentially conflicting requirements (should an +enum value get written as a number? or as a name? a fully qualified name?), +Magnum *doesn't* provide @cpp operator<< @ce overloads for @ref std::ostream. + +Instead, there's @relativeref{Corrade,Utility::Debug}, for your typing +convenience also aliased to just @ref Debug directly in the @ref Magnum +namespace. On its own it's able to print builtin types, all usual C++ +containers as well as their Corrade equivalents. Magnum then implements debug +printers for its own math types, basic structures and most enums, which get +printed as fully-qualified names. For example: + +@m_class{m-code-figure} + +@parblock + +@snippet Magnum.cpp features-debug-output + + + +@m_class{m-nopad} + +@code{.shell-session} +Image format is PixelFormat::RGBA8Srgb and size Vector(256, 192) +Color of the bottom-left pixel is #33b27f +@endcode + +@endparblock + +The main goal of this utility is convenience and readability --- values are +implicitly delimited by spaces and ended with a newline, container contents +written with commas etc. Check out the class documentation for advanced +features like colors, output redirection or printing file/line info. + +@section features-examples Learn by example + +Before you do a deep dive into the documentation, and if you haven't done +already, it's recommended to go through the Getting Started Guide and check out +at least the first example: + +@m_class{m-row} + +@parblock + +@m_div{m-col-m-6} @m_div{m-button m-primary} @m_div{m-big}Getting Started@m_enddiv @m_div{m-small} bootstrap a basic project structure @m_enddiv @m_enddiv @m_enddiv + +@m_div{m-col-m-6} @m_div{m-button m-success} @m_div{m-big}Your First Triangle@m_enddiv @m_div{m-small} a step-by-step tutorial @m_enddiv @m_enddiv @m_enddiv + +@endparblock + +@section features-building-blocks Learn through documentation + +Each of the following pages provides a high-level description of a certain area +of the library. It's recommended to read through these first to understand the +overall principles and only then go to documentation of each concrete class and +function. - @subpage platform --- @copybrief platform - @subpage types --- @copybrief types diff --git a/doc/getting-started.dox b/doc/getting-started.dox index 544bc2eb5..6d4f10506 100644 --- a/doc/getting-started.dox +++ b/doc/getting-started.dox @@ -345,11 +345,19 @@ See @ref platform for more information. @section getting-started-tutorials Follow tutorials and learn the principles Now that you have your first application up and running, the best way to -continue is to render your first triangle. Then you can dig deeper and try -other examples, read about @ref features "fundamental principles" in the -documentation and start experimenting on your own! +continue is to get familiar with the basic workflows and render your first +triangle. Then you can dig deeper and try other examples, read about basic +building blocks in the documentation and start experimenting on your own! -@m_div{m-button m-success} @m_div{m-big}Your First Triangle@m_enddiv @m_div{m-small} a step-by-step tutorial @m_enddiv @m_enddiv +@m_class{m-row} + +@parblock + +@m_div{m-col-m-6} @m_div{m-button m-info} @m_div{m-big}The Fundamentals@m_enddiv @m_div{m-small} make yourself comfortable first @m_enddiv @m_enddiv @m_enddiv + +@m_div{m-col-m-6} @m_div{m-button m-success} @m_div{m-big}Your First Triangle@m_enddiv @m_div{m-small} a step-by-step tutorial @m_enddiv @m_enddiv @m_enddiv + +@endparblock @section getting-started-more Additional information diff --git a/doc/snippets/Magnum.cpp b/doc/snippets/Magnum.cpp index b76710945..67b66c8de 100644 --- a/doc/snippets/Magnum.cpp +++ b/doc/snippets/Magnum.cpp @@ -26,6 +26,7 @@ #include #include "Magnum/Math/Color.h" +#include "Magnum/Math/Matrix4.h" #include "Magnum/Image.h" #include "Magnum/ImageView.h" #include "Magnum/PixelFormat.h" @@ -37,6 +38,8 @@ #include "Magnum/GL/Texture.h" #endif +#define DOXYGEN_IGNORE(...) __VA_ARGS__ + using namespace Magnum; using namespace Magnum::Math::Literals; @@ -64,6 +67,42 @@ class MeshResourceLoader: public AbstractResourceLoader { int main() { +{ +/* [features-using-namespace] */ +using namespace Corrade; +using namespace Magnum; +/* [features-using-namespace] */ +} + +{ +/* [features-using-namespace-alias] */ +namespace Cr = Corrade; +namespace Mn = Magnum; +/* [features-using-namespace-alias] */ +} + +{ +/* The same #include is already above so this shouldn't hurt */ +/* [features-forward-declaration-use] */ +#include /* only a Matrix4 forward declaration */ +#include /* the actual definition */ + +DOXYGEN_IGNORE() + +Matrix4 a = Matrix4::translation({3.0f, 1.0f, 0.5f}); +/* [features-forward-declaration-use] */ +static_cast(a); +} + +{ +/* [features-debug-output] */ +Image2D image = DOXYGEN_IGNORE(Image2D{{}, {}, {}}); + +Debug{} << "Image format is" << image.format() << "and size" << image.size(); +Debug{} << "Color of the first pixel is" << image.pixels()[0][0]; +/* [features-debug-output] */ +} + { std::nullptr_t data{}; /* [Image-pixels] */ diff --git a/doc/types.dox b/doc/types.dox index 6831fec4b..6b055bb46 100644 --- a/doc/types.dox +++ b/doc/types.dox @@ -31,15 +31,19 @@ namespace Magnum { @m_footernavigation @m_keyword{Type system,,} -The root @ref Magnum namespace defines a few aliases for essential math types. -See its documentation for more information about usage. +Magnum defines a variety of scalar, vector and matrix types. Most of the +functionality is implemented using template classes in the @ref Math library, +with the most common variants brought as typedefs into the root @ref Magnum +namespace. @section types-builtin Builtin types -Magnum provides typedefs for builtin integral and floating-point arithmetic -types to ensure portability (e.g. @ref Int is *always* 32bit), maintain -consistency and reduce confusion (e.g. @ref std::int32_t, @cpp int @ce and -@cpp GLint @ce all refer to the same type). +Magnum provides its own typedefs for builtin integral and floating-point +arithmetic types to ensure portability, maintain consistency and reduce +confusion. E.g., the @ref Int typedef is guaranteed to *always* be 32-bit and +Magnum's own code and documentation prefers to use it over a wild mixture of +@ref std::int32_t, @cpp int @ce, @cpp GLint @ce and @cpp ALint @ce that all +refer to the same type. | Magnum type | Size | Equivalent GLSL type | | ------------------ | -------------- | ----------------------- | @@ -56,8 +60,8 @@ consistency and reduce confusion (e.g. @ref std::int32_t, @cpp int @ce and | @ref Double | 64bit | @glsl double @ce | Types not meant to be used in arithmetic (such as @cpp bool @ce or -@cpp std::size_t @ce) or types which cannot be directly passed to GLSL shaders -(such as @cpp long double @ce) have no typedefs. +@cpp std::size_t @ce) or types which have no use in GPU computations (such as +@cpp long double @ce) have no typedefs. Types from the above table are then used to define other types. All following types are aliases of corresponding types in @ref Math namespace. No suffix @@ -121,11 +125,11 @@ about the differences. @section types-binary Binary representation -Scalar types with GLSL equivalent are verified to be exactly the same as -corresponding `GL*` types. Matrix and vector classes have the same binary -representation as corresponding array of numeric values without any additional -data or padding (e.g. @cpp sizeof(Vector3i) == sizeof(Int[3]) @ce), all -matrices are stored in column-major order. +Scalar types with a GLSL equivalent are guaranteed to have exactly the same +binary representation. Consequently, matrix and vector classes also have the +same binary representation as corresponding array of numeric values without any +additional data or padding (e.g. @cpp sizeof(Vector3i) == sizeof(Int[3]) @ce), +all matrices are stored in column-major order. This means that all scalar, matrix and vector types can be used directly for filling GPU buffers and textures without any need for data extraction or