|
|
|
|
/*
|
|
|
|
|
This file is part of Magnum.
|
|
|
|
|
|
|
|
|
|
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
|
|
|
|
|
2020, 2021, 2022, 2023, 2024, 2025, 2026
|
|
|
|
|
Vladimír Vondruš <mosra@centrum.cz>
|
|
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
|
copy of this software and associated documentation files (the "Software"),
|
|
|
|
|
to deal in the Software without restriction, including without limitation
|
|
|
|
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
|
and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
|
Software is furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included
|
|
|
|
|
in all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
|
DEALINGS IN THE SOFTWARE.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
namespace Magnum {
|
|
|
|
|
/** @page troubleshooting Troubleshooting
|
|
|
|
|
@brief Various tricks and solutions to common pitfalls.
|
|
|
|
|
|
|
|
|
|
@tableofcontents
|
|
|
|
|
@m_footernavigation
|
|
|
|
|
|
|
|
|
|
@section troubleshooting-building Building issues
|
|
|
|
|
|
|
|
|
|
If your project suddenly stops building after a Magnum upgrade, check these
|
|
|
|
|
things:
|
|
|
|
|
|
|
|
|
|
- If building fails on the CMake step, be sure that you have up-to-date
|
|
|
|
|
`FindCorrade.cmake` and `FindMagnum.cmake` CMake modules in your project.
|
|
|
|
|
They are contained in the [modules/](https://github.com/mosra/magnum/tree/master/modules)
|
|
|
|
|
directory of Magnum repositories and also get installed into
|
|
|
|
|
`share/cmake/Corrade` and `share/cmake/Magnum`.
|
|
|
|
|
- In very rare cases the CMake build directory may not survive an upgrade. If
|
|
|
|
|
you get some particularly cursed errors, try recreating it from scratch.
|
|
|
|
|
- The library is constantly evolving, meaning that APIs may get deprecated
|
|
|
|
|
and removed over time. If you upgrade to a version that deprecated a
|
|
|
|
|
particular API you use, the code will emit a deprecation warning,
|
|
|
|
|
suggesting a migration path. Except for rare cases, the deprecated APIs are
|
|
|
|
|
guaranteed to stay in the codebase for a year at least (or two subsequent
|
|
|
|
|
version releases, whichever is longer) and only then they get removed. To
|
|
|
|
|
make sure you're no longer using any deprecated functionality, it's
|
|
|
|
|
possible to disable the `MAGNUM_BUILD_DEPRECATED`
|
|
|
|
|
@ref building-features "CMake option" when building Magnum, although for a
|
|
|
|
|
smoother experience it's recommended to flip this option back on when
|
|
|
|
|
upgrading. A list of deprecated APIs is maintained
|
|
|
|
|
@ref changelog-latest-deprecated "in the changelog".
|
|
|
|
|
- In some rare cases, it's impossible to provide a deprecated migration path
|
|
|
|
|
and an API gets changed in a backwards-incompatible manner, directly
|
|
|
|
|
leading to a compile error. Another possibility is that transitive header
|
|
|
|
|
dependencies got cleaned up for @ref compilation-forward-declarations "speeding up compilation" and you're now missing an @cpp #include @ce. The major
|
|
|
|
|
compatiblity breakages are always listed @ref changelog-latest-compatibility "in the changelog".
|
|
|
|
|
- If you upgrade from a really old release, it's recommended to gradually
|
|
|
|
|
upgrade over tagged versions of Magnum and not jumping directly to latest
|
|
|
|
|
version. That way you're more likely to follow the deprecation path,
|
|
|
|
|
instead of directly ending up with long-deprecated APIs being gone with no
|
|
|
|
|
direct way to know what should be used instead. If in doubt, browse the
|
|
|
|
|
@ref changelog "old changelogs".
|
|
|
|
|
|
|
|
|
|
@section troubleshooting-runtime Runtime issues
|
|
|
|
|
|
|
|
|
|
Magnum makes heavy use of assertions to catch programmer errors (as opposed to
|
|
|
|
|
runtime or data-dependent errors, which get handled in more graceful ways), and
|
|
|
|
|
because past experience showed their usefulness, majority of assertions is
|
|
|
|
|
@ref CORRADE_NO_ASSERT "by default kept even in release builds".
|
|
|
|
|
|
|
|
|
|
If your application abruptly exits, it's important to know whether it was a
|
|
|
|
|
regular *exit*, an *abort* or a *crash*, as each of these may point to a
|
|
|
|
|
different problem.
|
|
|
|
|
|
|
|
|
|
- Except for crashes, in which case the application usually won't even have a
|
|
|
|
|
chance to complain about anything, you should get a message on the standard
|
|
|
|
|
error output:
|
|
|
|
|
- On Unix systems the output can be seen when running from a console
|
|
|
|
|
- On Windows, if you don't see the console, switch the build back to a
|
|
|
|
|
console app @ref platform-windows-hiding-console "instead of a GUI app"
|
|
|
|
|
--- in case of CMake you can temporarily remove the `WIN32` part from
|
|
|
|
|
your @cmake add_executable() @ce call
|
|
|
|
|
- On Android @ref platforms-android-output-redirection "you can use logcat"
|
|
|
|
|
- On Emscripten the output is printed to the browser console
|
|
|
|
|
- A regular exit may happen during startup due to an error in arguments
|
|
|
|
|
passed on the command line, or when a window / context creation fails. The
|
|
|
|
|
error output should mention what happened.
|
|
|
|
|
- An abort is an assertion failure, with the error message telling you why.
|
|
|
|
|
It's an abort in order to trigger a debugger break (or the assertion dialog
|
|
|
|
|
on Windows) or create a core dump (on Unix systems) so you can see the
|
|
|
|
|
backtrace leading to the error.
|
|
|
|
|
- One of the more frequent assertion messages is
|
|
|
|
|
@cb{.shell-session} GL::Context::current(): no current context @ce.
|
|
|
|
|
This happens when you try to use OpenGL functionality when the OpenGL
|
|
|
|
|
context is not yet created (or no longer exists). See
|
|
|
|
|
@ref opengl-wrapping-instances-nocreate for more information.
|
|
|
|
|
- A crash is usually a memory issue. To find the root cause, by far the
|
|
|
|
|
easiest is to hook up AddressSanitizer (`-fsanitize=address` on GCC, Clang
|
|
|
|
|
and [recent MSVC](https://docs.microsoft.com/en-us/cpp/sanitizers/asan)).
|
|
|
|
|
It can detect out-of-bounds accesses, use-after-free, leaks and other
|
|
|
|
|
issues and upon discovering a problem it prints a lengthy diagnostic about
|
|
|
|
|
what happened, where does the memory come from and what code touched it and
|
|
|
|
|
how.
|
|
|
|
|
|
|
|
|
|
@section troubleshooting-opengl OpenGL issues
|
|
|
|
|
|
|
|
|
|
If you are experiencing the so-called "black screen of death", weird behavior
|
|
|
|
|
or crashes on GL calls, you might want to try these things:
|
|
|
|
|
|
|
|
|
|
- Enable @ref GL::DebugOutput "debug output" to see more detailed errors,
|
|
|
|
|
warnings and performance hints. You can do that easily through the
|
|
|
|
|
`--magnum-gpu-validation` @ref GL-Context-usage-command-line "command-line option"
|
|
|
|
|
or an environment variable.
|
|
|
|
|
- If you are on Mac, the native OpenGL implementation doesn't support
|
|
|
|
|
this. Instead you can manually verify that
|
|
|
|
|
@ref GL::Renderer::error() "no OpenGL error was emitted".
|
|
|
|
|
- Check that you use only extensions that are
|
|
|
|
|
@ref GL::Context::isExtensionSupported() "available on your system".
|
|
|
|
|
- Check that you didn't exceed any implementation-defined limit (see
|
|
|
|
|
@ref magnum-gl-info output for a list of all of them).
|
|
|
|
|
- If using framebuffer objects,
|
|
|
|
|
@ref GL::Framebuffer::checkStatus() "check that they are complete".
|
|
|
|
|
- Rendering to three-component @ref GL::TextureFormat works on some GPUs
|
|
|
|
|
but not others. TO avoid platform-dependent issues, always use one-,
|
|
|
|
|
two- or four-component formats.
|
|
|
|
|
- Change @ref GL::Renderer::setClearColor() "framebuffer clear color" to
|
|
|
|
|
something else than black to verify that at least something is drawn. The
|
|
|
|
|
engine sets it to @cpp 0x1f1f1f_rgbf @ce by default to help you a bit in
|
|
|
|
|
this regard.
|
|
|
|
|
- If nothing is drawn, use @ref GL::PrimitiveQuery to check that at least
|
|
|
|
|
some primitives were generated. Use @ref GL::SampleQuery to check whether
|
|
|
|
|
fragments were drawn.
|
|
|
|
|
- Verify that the mesh is properly set up --- nonzero vertex/index count,
|
|
|
|
|
matching type in buffer and @ref GL::Mesh::addVertexBuffer() "vertex specification",
|
|
|
|
|
properly set up @ref GL::Mesh::setIndexBuffer() "index buffer" and index
|
|
|
|
|
count for indexed mesh. If you specified index range, be sure that all
|
|
|
|
|
indices fall into it, otherwise you would get undefined behavior.
|
|
|
|
|
- Try disabling the @ref GL::Renderer::Feature::DepthTest "depth test",
|
|
|
|
|
@ref GL::Renderer::Feature::FaceCulling "face culling" and other renderer
|
|
|
|
|
features that might cause fragments to be discarded.
|
|
|
|
|
- Verify that your projection and transformation matrix is properly set up
|
|
|
|
|
--- try drawing points instead of triangles, to see if they are in proper
|
|
|
|
|
places at least.
|
|
|
|
|
- For custom shaders you can @ref GL::AbstractShaderProgram::validate() "Validate them".
|
|
|
|
|
Check that all used uniforms and attributes have proper locations. Try
|
|
|
|
|
reducing it until it is able to draw something, possibly also with some
|
|
|
|
|
simpler mesh.
|
|
|
|
|
- Magnum tracks the OpenGL state to improve performance, but the tracker can
|
|
|
|
|
get confused if you or any other library are doing OpenGL calls outside of
|
|
|
|
|
Magnum. For that to work, you need to
|
|
|
|
|
@ref opengl-state-tracking "reset the state tracker" on boundaries between
|
|
|
|
|
3rd party and Magnum calls into GL. The other library also needs to be
|
|
|
|
|
aware of this fact (either setting all state explicitly every time or
|
|
|
|
|
having similar ability to reset its state tracker), otherwise you may need
|
|
|
|
|
to save and restore GL state manually for that library to work.
|
|
|
|
|
|
|
|
|
|
@subsection troubleshooting-opengl-debugging Debugging rendering
|
|
|
|
|
|
|
|
|
|
- Use @ref GL::TimeQuery to find hot spots in the rendering code.
|
|
|
|
|
- @ref GL::DebugMessage::insert() "Mark relevant parts of code" to find them
|
|
|
|
|
easier in the debugger.
|
|
|
|
|
- Use ApiTrace or RenderDoc to trace the program call by call, verify buffer
|
|
|
|
|
and texture contents, vertex binding and count of generated primitives,
|
|
|
|
|
rendered fragments and time spent in various calls.
|
|
|
|
|
*/
|
|
|
|
|
}
|