Browse Source

doc: *finally* document the library organization and essential tools.

pull/529/head
Vladimír Vondruš 5 years ago
parent
commit
83f18b2313
  1. 142
      doc/features.dox
  2. 16
      doc/getting-started.dox
  3. 39
      doc/snippets/Magnum.cpp
  4. 30
      doc/types.dox

142
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
<b></b>
@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} <a href="getting-started.html">@m_div{m-big}Getting Started@m_enddiv @m_div{m-small} bootstrap a basic project structure @m_enddiv </a> @m_enddiv @m_enddiv
@m_div{m-col-m-6} @m_div{m-button m-success} <a href="examples-triangle.html">@m_div{m-big}Your First Triangle@m_enddiv @m_div{m-small} a step-by-step tutorial @m_enddiv </a> @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

16
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} <a href="examples-triangle.html">@m_div{m-big}Your First Triangle@m_enddiv @m_div{m-small} a step-by-step tutorial @m_enddiv </a> @m_enddiv
@m_class{m-row}
@parblock
@m_div{m-col-m-6} @m_div{m-button m-info} <a href="features.html">@m_div{m-big}The Fundamentals@m_enddiv @m_div{m-small} make yourself comfortable first @m_enddiv </a> @m_enddiv @m_enddiv
@m_div{m-col-m-6} @m_div{m-button m-success} <a href="examples-triangle.html">@m_div{m-big}Your First Triangle@m_enddiv @m_div{m-small} a step-by-step tutorial @m_enddiv </a> @m_enddiv @m_enddiv
@endparblock
@section getting-started-more Additional information

39
doc/snippets/Magnum.cpp

@ -26,6 +26,7 @@
#include <Corrade/Containers/StridedArrayView.h>
#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<GL::Mesh> {
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 <Magnum/Magnum.h> /* only a Matrix4 forward declaration */
#include <Magnum/Math/Matrix4.h> /* the actual definition */
DOXYGEN_IGNORE()
Matrix4 a = Matrix4::translation({3.0f, 1.0f, 0.5f});
/* [features-forward-declaration-use] */
static_cast<void>(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<Color4ub>()[0][0];
/* [features-debug-output] */
}
{
std::nullptr_t data{};
/* [Image-pixels] */

30
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 <b></b> |
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

Loading…
Cancel
Save