mosra / magnum Goto Github PK
View Code? Open in Web Editor NEWLightweight and modular C++11 graphics middleware for games and data visualization
Home Page: https://magnum.graphics/
License: Other
Lightweight and modular C++11 graphics middleware for games and data visualization
Home Page: https://magnum.graphics/
License: Other
The reason why I would like to build using xcode is so I can hack the source from within the editor. I can get it to build via the instructions just fine but I would like have nicer debug tools available.
Using an out of source build
cmake version 2.8.12
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.0.0
Thread model: posix
The build.sh
sudo rm -rf build
mkdir build
cd build
cmake .. -G Xcode
-DTARGET_DESKTOP_GLES=ON
-DCMAKE_INSTALL_PREFIX=/usr
-DWITH_SDL2APPLICATION=ON
-DWITH_MESHTOOLS=ON
-DWITH_PRIMITIVES=ON
-DWITH_SCENEGRAPH=ON
-DWITH_SHADERS=ON
-DWITH_SHAPES=ON
-DWITH_TEXT=ON \
-- The C compiler identification is Clang 5.0.0
-- The CXX compiler identification is Clang 5.0.0
-- Check for working C compiler using: Xcode
-- Check for working C compiler using: Xcode -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler using: Xcode
-- Check for working CXX compiler using: Xcode -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Found Corrade: /usr/lib/libCorradeUtility.dylib
-- Found OpenGL: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/OpenGL.framework
-- LIB_SUFFIX variable is not defined. It will be autodetected now.
-- You can set it manually with -DLIB_SUFFIX= (64 for example)
-- LIB_SUFFIX autodetected as '', libraries will be installed into /usr/lib
-- Found SDL2: /Library/Frameworks/SDL2.framework
-- Configuring done
-- Generating done
cd build
xcodebuild -version
Xcode 5.0.2
Build version 5A3005
sudo xcodebuild -target install build
The lengthy log here.
http://pastebin.com/W3F8TWnX
/// ends here
The following build commands failed:
Ld build/src/MeshTools/Debug/libMagnumMeshTools.dylib normal x86_64
The I am not sure why this is an issue anyone have a clue?
The example on this page of the documentation is incorrect.
http://mosra.cz/blog/magnum-doc/classMagnum_1_1Texture.html#details
The incorrect line is:
Image2D image({4096, 4096}, ColorFormat::RGBA, ColorType::UnsignedByte, data);
It should be:
Image2D image(ColorFormat::RGBA, ColorType::UnsignedByte, {4096, 4096}, data);
Along with the other examples on the page.
There are 820 warnings for Mac builds due to the AppleGLGetProcAddress's signature. Here is a sample of the warnings:
/Users/miguel/Documents/Programming/Projects/Repos/magnum/external/OpenGL/GL/gl_magnum.c:2711:86: warning:
passing 'char [12]' to parameter of type 'const GLubyte *' (aka
'const unsigned char *') converts between pointers to integer types with
different sign [-Wpointer-sign]
...GLubyte * (CODEGEN_FUNCPTR *)(GLenum))IntGetProcAddress("glGetString");
^~~~~~~~~~~~~
/Users/miguel/Documents/Programming/Projects/Repos/magnum/external/OpenGL/GL/gl_magnum.c:86:57: note:
expanded from macro 'IntGetProcAddress'
#define IntGetProcAddress(name) AppleGLGetProcAddress(name)
^
/Users/miguel/Documents/Programming/Projects/Repos/magnum/external/OpenGL/GL/gl_magnum.c:9:52: note:
passing argument to parameter 'name' here
static void* AppleGLGetProcAddress (const GLubyte *name)
ShapeGroup
stores the shapes in flat array, making it easy for user to query the contents and possibly save a reference to particular shape. It also saves some allocations compared to previous solution, but the internals more complicated. Nothing for user to worry about, the API is the the same as before:auto group = Physics::Point2D(1.0f, -0.5f) || Physics::Sphere2D({}, 1.5f);
bool collides = group % Physics::Point2D(0.5f, 0.5f);
Adding shapes as references to original objects is not possible though, they need to be extracted back after creating the group:
Physics::Sphere2D& sphere = group.get<Physics::Sphere2D>(1);
ObjectShape
is now templated on shape, stores two instances of it (original and transformed one) and common functionality is in abstract base AbstractObjectShape
. It is now actually usable, compare previous, where ObjectShape
wasn't useful for anything:ObjectShapeGroup2D* group;
Object2D* o;
Physics::Point2D point({1.0f, -0.5f});
(new Physics::ObjectShape2D(o, shapes))->setShape(&point);
Vector2 transformedPosition = point.transformedPosition();
With current:
auto shape = new Physics::ObjectShape<Physics::Point2D>(o, {{1.0f, -0.5f}}, shapes);
Vector2 transformedPosition = shape->transformedShape().position();
ShapeGroup
and ObjectShape
. It is good because it doesn't add confusing wrappers to the user (except one additional "internal" header file with no public documentation and no need for user to include it). Has it any downsides? Will the user need the polymorphism anywhere?Physics::Point2D a;
Physics::Sphere2D b;
auto shape = new Physics::ObjectShape<Physics::ShapeGroup2D>(o, a || b, shapes);
The above code is not intuitive, becasuse the user might not immediately know that result of a || b
is ShapeGroup
. Even if he would, this is a lot of unnecessary typing, because the shape type is known from the arguments (unlike in above examples). Two considered (but unsufficient) solutions:
ShapeGroup
into specialized ObjectShape
, e.g. ObjectShapeHierarchy
? Will result in having the internal polymorphic wrappers in only one place (hopefully), which is good, but removes the possibility to operate on ShapeGroup
alone without scene graph. Has ShapeGroup
any use without scene graph?std::make_tuple
which removes the need for explicit type specification, e.g.:auto shape = Physics::makeObjectShape(o, a || b, shapes);
It would save typing also in some other cases, but what should this function return? Pointer to object created on heap? Object by value? Both have valid use cases and having both makeObjectShape()
and makeObjectShapePtr()
is ugly.
The user can't intuitively tell what's the difference between ObjectShapeGroup
and ShapeGroup
, thus they should be renamed to something more meaningful. Also why not to move everything to different namespace so Physics
can be saved for other things like rigid bodies and particle systems? Linking Physics
library just because one needs to click menus seems like overkill. But on the other hand, will collision detection be large enough to be in separate library?
Physics
namespace to Shapes
(CollisionDetection
is too long?)ShapeGroup
to Hierarchy
. Because it will always be written as Shapes::Hierarchy
it will be obvious what is going on. Better name?ObjectShape
to Shape
and ObjectShapeGroup
to ShapeGroup
(Object
was redundant). Is it descriptive enough for scene graph feature (Collidable
sounds to Java-ish)? Physics itself will contain RigidBody
.Hi, when i use the newest version mangnum and corrade, I got a link error, the error message is below:
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../../lib/libMagnum.so: undefined reference to
Corrade::Utility::Implementation::BasicConfigurationValue::toString(int const&, Corrade::Containers::EnumSet<Corrade::Utility::ConfigurationValueFlag, unsigned char, (unsigned char)255>)'`.
can you help me to handle with it? Thank u!
Is the Flat2D shader supposed to have transparency support? It seems that it doesn't on my machine, and I'm not sure if it's supposed to or not. Either way it would be lovely to have alpha support without having to create another shader.
Evidence of no alpha support:
Running Mac OS X 10.9.
Compiler:
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.0.0
Thread model: posix
OpenGL context information:
Vender: Intel Inc.
Renderer: Intel HD Graphics 3000 OpenGL Engine
Version: 3.3 INTEL-8.18.27
Hallo,
I tried to find answer to this in the documantation, with no immediate success:
Im trying to build magnum library for use with VS2013 in release as well as in debug modes. It seems however that output files have same names, and overwrite each other on install. Additionaly, cmake modules don't care to differentiate between release/debug versions of binaries either.
This is however important, as release/debug modules are not compatible, for example, you can't link magnum's release binaries with corrade's debug ones(error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL', error LNK2038: mismatch detected for 'RuntimeLibrary' is a direct result of such an attempt).
Exactly the same issue happens in custom programs that link to magnum: one can only build either debug or release, depending on what corrade/magnum configuration was recently built
I'd love to see support for this standard (OpenDDL/OpenGEX) made as a first class citizen within the library. I have an implementation (https://github.com/dysfictional/openddl) in progress that I'd be happy to have included at which time we're both happy with it.
Currently Magnum (and also Corrade) headers are included with no explicit path or prefix. They also have very generic names:
#include <Color.h>
Generic, short and unprefixed names are good for usability, but only until some issue appears. Notably on Windows (both with MinGW and MSVC) there are name collision problems, e.g. Types.h
from motionblur
example conflicts with Types.h
from Magnum, causing horrific error messages. One other example was String.h
from Corrade Utility, which was conflicting with system string.h
, but that issue disappeared somehow. There are also other problems, which may or may not be bugs in how the compiler handles paths and filenames. It's not limited to files though -- the Magnum::Rectangle
class conflicted with Rectangle()
from WINAPI, but that's not an issue anymore, as Rectangle
is now replaced with more generic Range
. In this case the <windows.h>
/<Xlib.h>
headers with unprefixed functions and macros are the main offenders, but I can't do anything else than accomodate to them.
One simple solution to include collision might be to not add (e.g.) /usr/include/Magnum
to include path and use absolute includes instead, i.e.:
#include <Magnum/Color.h>
This would require fairly big repository reorganization -- moving everything from src/
to src/Magnum
and then changing all headers to have absolute includes too. The includes from external
directory would need to be adjusted too. Then the src/
directory would contain only one Magnum
subdirectory, resembling the very verbose and inconvenient way Java projects are organized in the filesystem.
This change has also its downsides, mainly:
The includes are way more verbose. Not so much for root includes, but for subnamespaces:
#include <Magnum/Math/Algorithms/GaussJordan.h>
Unwanted separation of Corrade (sub)library. Currently Corrade library is a first-class citizen in Magnum, i.e. the user doesn't have to think whether some class is part of Magnum or Corrade, it's enough just include it and use as if it was part of Magnum:
#include <Magnum.h>
#include <Utility/Directory.h>
using namespace Magnum;
Directory::write(...);
With this change the user would need to explicitly specify the actual project given header comes from, which is not so convenient:
#include <Magnum/Magnum.h>
#include <Corrade/Utility/Directory.h> // huh?
To allow multiple versions of the library be installed alongside each other, the includes would need to be installed into (e.g.) include/Magnum1/Magnum
and include/Magnum2/Magnum
, which is even more horrifying.
I hope for a less drastic solution than this.
Another solution might be to have the headers and classes with some unique prefix. If I take inspiration from Qt, they are having everything in Qt*/
subdirectories, each class is prefixed with Q*
and each function is prefixed with q*
. But (as far as I know) this was from the times where support for C++ namespaces was rather poor (Qt classes are not wrapped in any namespace) and with current C++ state the final decision might be totally different.
I thought about adding similar prefix to the root classes and subnamespaces (Mn*
, Cr*
), but I don't like having Magnum::MnSceneGraph
, Magnum::MnVector2
etc., it seems overly verbose and redundant for me. It might be possible to have the prefix only for header files, but having to include <MnRenderer.h>
to use Magnum::Renderer
is not intuitive at all.
Read, learn, undestand, design and implement support for
and equivalent subset found in ES 3.0 / 3.1.
Currently the main use case is GPU-powered particle systems and physics on hardware that doesn't support generic compute shaders.
As reported in mosra/kotel#1, the ANGLE GLSL-to-HLSL converter fails to compile the shader because of non-constant vector component indexing in src/Magnum/Shaders/MeshVisualizer.vert:
AbstractShaderProgram::link(): linking failed with the following message:
(26,2-71): error X3500: array reference cannot be used as an l-value; not natively addressable
Warning: D3D shader compilation failed with default flags.
Failed to create D3D shaders.
Assertion link() failed in ../src/Magnum/Shaders/MeshVisualizer.cpp on line 107
The offending line is:
barycentric[int(mod(vertexIndex, 3.0))] = 1.0;
GLSL ES 1.0 specification allows this (section 5.5), so it should be supported in ANGLE too:
Array subscripting syntax can also be applied to vectors to provide numeric indexing. So in
vec4 pos;
pos[2]
refers to the third element ofpos
and is equivalent topos.z
. This allows variable indexing into a vector, as well as a generic way of accessing components. Any integer expression can be used as the subscript. The first component is at index zero. Reading from or writing to a vector using a constant integral expression with a value that is negative or greater than or equal to the size of the vector is illegal. When indexing with non-constant expressions, behavior is undefined if the index is negative or greater than or equal to the size of the vector.
Proposed solution is to work around this using ugly branch, but that might harm performance elsewhere.
int i = int(mod(vertexIndex, 3.0));
if(i == 0) barycentric.x = 1.0;
else if(i == 1) barycentric.y = 1.0;
else barycentric.z = 1.0;
Better (and future proof) solution would be to implement some ANGLE autodetection and enable this only if we might be running on ANGLE. Sadly there doesn't seem to be any easy way to do it.
Hi:
I try magnum on osx, but more matter.
example: text
/* Load FreeTypeFont plugin */
//if(!(manager.load("FreeTypeFont") & PluginManager::LoadState::Loaded))
//std::exit(1);
//font = manager.instance("FreeTypeFont");
I think It's error, so I change to:
if(!(manager.load("MagnumFont") & PluginManager::LoadState::Loaded))
std::exit(1);
font = manager.instance("MagnumFont");
if I build magnum to share lib, echo:
Using optional features:
GL_APPLE_vertex_array_object
GL_ARB_ES2_compatibility
GL_ARB_separate_shader_objects
GL_ARB_texture_storage
GL_EXT_debug_label
GL_EXT_debug_marker
GL_EXT_texture_filter_anisotropic
PluginManager::Manager::load(): unresolved dependency TgaImporter of plugin MagnumFont
if I build magnum to static lib, failed to build
[ 92%] Building CXX object src/text/CMakeFiles/text.dir/resource_TextExample_RESOURCES.cpp.o
Linking CXX executable text
Undefined symbols for architecture x86_64:
"Magnum::TextureTools::distanceField(Magnum::Texture<2u>&, Magnum::Texture<2u>&, Magnum::Math::Range2D const&, int, Magnum::Math::Vector2 const&)", referenced from:
Magnum::Text::DistanceFieldGlyphCache::setImage(Magnum::Math::Vector2 const&, Magnum::ImageReference<2u> const&) in libMagnumText.a(DistanceFieldGlyphCache.cpp.o)
"Magnum::TextureTools::atlas(Magnum::Math::Vector2 const&, std::__1::vectorMagnum::Math::Vector2<int, std::__1::allocatorMagnum::Math::Vector2 > const&, Magnum::Math::Vector2 const&)", referenced from:
Magnum::Text::GlyphCache::reserve(std::__1::vectorMagnum::Math::Vector2<int, std::__1::allocatorMagnum::Math::Vector2 > const&) in libMagnumText.a(GlyphCache.cpp.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [src/text/text] Error 1
make[1]: *** [src/text/CMakeFiles/text.dir/all] Error 2
make: *** [all] Error 2
When trying to build the library with GCC 4.6+ on MinGW get the error that OpenGL.h cannot find GL/glew.h
Quick fix is to replace the following segment in Magnum/src/CMakeLists.txt;
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${CORRADE_INCLUDE_DIR}We can use both implicit include path (GLES2/gl2.h) where our headers can
be overriden with system ones or explicit (OpenGL/GLES2/gl2ext.h) where
only our headers will be used
${CMAKE_SOURCE_DIR}/external
${CMAKE_SOURCE_DIR}/external/OpenGL${GLEW_INCLUDE_DIR})
Right now I see a big problem for any new comer which is interested in trying Magnum. They are going only to clone mangnum git repository and as soon as they try to compile the project they will realize that it needs other 3 repositories just to get an example working in Linux.
I have to say that I totally agree in having different repositories for each thing but I also think that magnum should be complete just by cloning it's repository. My experience with Git is not as extensive as with SVN but by using SVN you can have external repositories locked into a specific revisition as directories so that when you check out the repository for the first time its also going to check out the external repositories to a specific revisiton.
I investigated a bit about this and in git you can have submodules (external repositories) locked to a specific commit.
http://git-scm.com/book/en/Git-Tools-Submodules
So we would have a directory structure like
magnum/libs/corrade
magnum/plugins
magnum/examples
A neat thing would be that CMake would also build corrade by default and at least the triangle example.
When trying to create a flat shader, the following warning is outputted:
AbstractShaderProgram: linking succeeded with the following message:
WARNING: Could not find vertex shader attribute 'textureCoordinates' to match BindAttributeLocation request.
Here is what this warning looks like (visually within an actual program):
As you can see, no texture(s) is rendered properly. Note, the screen is cleared white to see the black rendered 'textures' easier. The code for the above is located here (header/source), and the same result occurs for your textured triangle example (a black triangle is rendered).
Running Mac OS X 10.9.
Compiler:
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.0.0
Thread model: posix
OpenGL context information:
Vender: Intel Inc.
Renderer: Intel HD Graphics 3000 OpenGL Engine
Version: 3.3 INTEL-8.18.27
The setImage function seems a bit ambiguous. Why do I need to provide the TextureFormat if the image (that I pass to the function) already has the format of the texture?
There are some warnings occurring for OS X builds, due to the use of depreciated function calls:
/Users/miguel/Documents/Programming/Projects/Repos/magnum/external/OpenGL/GL/gl_magnum.c:16:13: warning:
'NSAddImage' is deprecated [-Wdeprecated-declarations]
image = N...
^
/usr/include/mach-o/dyld.h:229:34: note: 'NSAddImage' declared here
extern const struct mach_header* NSAddImage(const char* image_name,...
^
/Users/miguel/Documents/Programming/Projects/Repos/magnum/external/OpenGL/GL/gl_magnum.c:25:20: warning:
'NSLookupSymbolInImage' is deprecated [-Wdeprecated-declarations]
symbol = image ? NSLookupSymbolInImage(image, symbolName,...
^
/usr/include/mach-o/dyld.h:181:17: note: 'NSLookupSymbolInImage' declared here
extern NSSymbol NSLookupSymbolInImage(const struct mach_header* image,...
^
/Users/miguel/Documents/Programming/Projects/Repos/magnum/external/OpenGL/GL/gl_magnum.c:27:19: warning:
'NSAddressOfSymbol' is deprecated [-Wdeprecated-declarations]
return symbol ? NSAddressOfSymbol(symbol) : NULL;
^
/usr/include/mach-o/dyld.h:187:21: note: 'NSAddressOfSymbol' declared here
extern void * NSAddressOfSymbol(NSSymbol symbol)...
^
Loosely based on the proposal on https://gist.github.com/3966677
Missing especially:
Magnum appears to be missing 2 Resource Files when building the Shader and TextureTools target; namely;
resource_MagnumTextureTools_RCS.cpp
resource_MagnumShaders_RCS.cpp
I think every decent graphics engine should have a flexible particle system. I request one of those in magnum. :)
GlutApplication is unable to locate freeglut headers when glut headers are not in system or mingw include directory
Some parameters (like "${CMAKE_INSTALL_PREFIX}/bin" and "${CMAKE_CURRENT_SOURCE_DIR}") are passed to CMake commands in your build scripts without enclosing them by quotation marks. I see that these places will result in build difficulties if the contents of the used variables will contain special characters like spaces.
I would recommend to apply advices from a Wiki article.
By default, I was unable to get Magnum to build on the most recent version of OS X (10.9, with fully updated Xcode). I suspect that the issues I experienced would be the same on other OS X versions.
Ultimately, I got it to compile, but there were two issues that should probably be fixed with the CMake files (I've never used CMake for anything other than building other peoples libraries myself, so forgive any inaccurate terminology).
cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local -DWITH_SDL2APPLICATION=ON
) it fails with the error Could NOT find OpenAL (missing: OPENAL_INCLUDE_DIR)
.-DOPENAL_INCLUDE_DIR=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/OpenAL.framework/Headers
. Presumably, MacOSX10.8.sdk
would be needed on 10.8, and etc. I'm not sure how you can fix this, as it seems the code for finding OpenAL is built-in to CMake (or it's hidden somewhere deep within your project), but it already does the right thing for OpenGL, so... maybe that helps.make
ing everything after generating the makefiles above, compilation fails due to being unable to find SDL_scancode.h
in Sdl2Application.h
, included from Sdl2Application.cpp
. It might be worth noting that it had already succeeded in including SDL.h
at this point.-DSDL2_INCLUDE_DIR=/Library/Frameworks/SDL2.framework/Headers/
when using CMake to generate the makefiles. Prior to this, it did find SDL2 at /Library/Frameworks/SDL2.framework
, so I'm not sure what the difference was. This issue could come from the fact that I originally installed SDL2 by using the installer from their website, and not by building from source, or via my package manager, but since that's the recommended method of installing SDL2, it should probably be supported.Anyway, as I mentioned, after fixing these problems I was successfully able to compile and install Magnum, but these seemed to be issues with your build process, so I figured that reporting an issue about it might streamline the process for other users.
This used to be a list of exciting new features present in newer C++ standards to look forward to. Now it's rather a list of non-insance C++14+ features that could be worth backporting to C++11.
CORRADE_CXX_STANDARD
CMake property and preprocessor macroCORRADE_CONSTEXPR14
-- mosra/corrade@9cf91f0std::integer_sequence
optimizations -- mosra/corrade@0b82814
For all compilers we need to wait until their usage is similar to GCC 4.7 and Clang 3.2 just now (May 2014). We'll see after dropping GCC 4.7 support (#274).
Good resources about compiler support are at http://www.g-truc.net/project-0036.html for major vendors and also at http://en.cppreference.com/w/cpp/compiler_support for the other.
constexpr
-- it would be finally possible to implement compile-time MurmurHash without the code being write-only, also many math functions will benefit from that (so the user doesn't need to precompute math operations in tight loops by hand, but can just slap constexpr
specifier on the result and be done with it). Experimental stuff already available in cpp14
branch.Pi<float>
) -- not sure about the usage, the current way with enums and functions ensures that the value is not exposed as any linkable symbol (you can't take address of enum or function result), which in my opinion is exactly what we want for constants -- to be always on stack and not referenced through some slow indirection. Also this (from API perspective) is easily doable using template aliases, am I missing something?1 << n
is much more readable[[deprecated]]
attribute might help with getting rid of the ugly CORRADE_DEPRECATED()
macro and its compiler-specific quirksThe issue is that these won't be advertised in compiler release changelogs and thus we might have some very nasty surprises (e.g. std::map::emplace()
didn't exist until GCC 4.8).
std::float32_t
and std::float64_t
instead of float
and double
, just to be consistent with strict type definitions we already have for integersstd::enable_if_t<...>
instead of typename std::enable_if<...>::type
(and similar) -- 13 characters shorter, will help a lot in implementation details of generic classesstd::make_unique()
for much less verbose std::unique_ptr
constructionstd::exchange()
utility function instead of the following fugly piece of codestd::string
literals, I hope they help with avoiding the copy and allocation on construction, otherwise I can't think of any other use case (apart from proper '\0'
handling)CORRADE_CXX_STANDARD
CMake property and preprocessor macroposix_memalign()
on pre-C++17 -- mosra/corrade@c095551
Array
/ ArrayTuple
if dealing with over-aligned types[[deprecated]]
!) for namespaces, enums and enum values (for enums this somehow already works in Clang C++11) -- currently used in CORRADE_DEPRECATED_ENUM()
macroContainers::Optional
with std::optional
Containers::StringView
with std::string_view
-- mosra/corrade@cf0bd1fmake*()
helperspointer()
vs Pointer
), so this is a non-issuestatic_assert()
without messagestd::observer_ptr
instead of raw pointersstd::is_integral_v<...>
instead of std::is_integral<...>::value
(and similar) - 5 characters shorter (slower compile times?)std::void_t
(N3911) has an interesting example to simplify CORRADE_HAS_TYPE()
macrostd::tuple
with just {}
std::tuple
from the codebase sinceuninitialized_value_construct()
etc. as more optimal alternatives to placement-new-in-a-loop in Containers::Array
NoInit
and other versions (but one needs <memory>
for that, ugh)Corrade::Utility::Directory
isSandboxed()
) vs what it provides (operator/
for concatenating directories, wtf)CORRADE_CXX_STANDARD
CMake property and preprocessor macroContainers::ArrayView
with std::span
__VA_OPT__
, like __VA_ARGS__
, but allowed to be emptynew
to avoid unnecessary reallocations#include
system -- though probably DOA, not speeding up anythingGL::defaultFramebuffer
to be initialized using a constant expression, but then used as a mutable instance?constexpr
, but enforcing that the function call is actually done at compile time (instead of just making it possible)
Utility::format()
is already much faster than fmtlib at compile time and could be also faster at runtime, once I get my hands on it.#elifdef
/ #elifndef
; I wonder when it will make sense to upgrade to C++23 just to get these (or maybe they'll be usable even wiithout picking the full standard?)operator[]
where I can use ,
, finally
StridedArrayView
, and an operator()
fallback until thenMatrix
, and an operator()
fallback until then<stacktrace>
StridedArrayView
with std::mdspan
std::initializer_list<T>
parameters to GLuint[]
when passing them to glBindTextures()
, glShaderSource()
and other "multi" functions. Not part of C++14, but available in GCC since forever as GNU extension and it is made "official" in 4.9. Clang originally chose to not implement this at all, so it's not available in it yet. On the other hand, if I'm lucky I might be able to work around the allocation with some implicit conversions and then pass the std::initializer_list
data directly.Currently all examples and bootstrap repository are using Platform::GlutApplication
. Originally it was because GLUT was available on most platforms and SDL2 was still in development, but as SDL 2 is released for some time it would be good to use Platform::Sdl2Application
everywhere instead, as it offers better features.
The (free)GLUT toolkit is already showing its limits -- poor configuration options, missing keyboard/mouse event handlers and the installation and usage is not ideal (the official FindGLUT.cmake
routine sometimes complains about missing Xmu
library or something, linking issues with MinGW etc.). Apart from the fact that the library is not evolving any further I also don't know about any support of EGL, OpenGL ES or e.g. Wayland.
The Emscripten toolchain supports (subset of) SDL2 out of the box and support for it could probably be done also for NaCl, so this would greatly simplify cross-platform development. I think Emscripten also supports GLUT, but implementing it in Magnum isn't worth it in my opinion.
SDL 2.0.0 was released back in August 2013 and thus it should be already available for majority of Linux distributions (official packages for Windows and OS X are available since the release, so it's not an issue either). My only concern is Ubuntu 12.04 LTS, which is still widely used and currently is pretty much outdated. To use Magnum on it the user needs at least newer CMake (we need 2.8.8 and 12.04 has only 2.8.7) and for convenient usage upgrade also the compiler. As mentioned in #18, it would be probably wise to wait until the next LTS (14.04) is released and then do the switch.
I don't know, but if there is any trusted PPA containing SDL2 packages also for 12.04, then the switch could be done now without needing to wait for adoption of the next LTS.
MinGW32 has several issues and it seems that the developers don't care about the users anymore, for example:
std::to_string()
functions, which I need to work around using slow std::stringstream
. The related bug was closed as "out of date" and no fix is in sight.std::u32string
on GCC 4.7 (memory corruption on destruction), so I had to workaround it everywhere by using std::vector<char32_t>
instead. Again, not sure whether this works now.As ArchLinux maintainers removed all MinGW32 packages and replaced them with MinGW-w64 equivalents, I think it would be good to do the same, clean up all these ugly MinGW32-specific workarounds and support just MinGW-w64.
Is there anyone using MinGW32 who can't switch to MinGW-w64? These cases come to my mind:
compatibility
)Currently all Platform::*Application
classes create the context with no explicit flags, which is (as far as I know) understood as OpenGL <=2.1 + everything possible on top of it without losing backwards compatibility. While this works on most systems with vendor-provided graphics drivers (Linux, Windows), it apparently fails on (some?) OSX systems.
According to OSX OpenGL capabilities tables there are two kinds of OpenGL support:
On some systems it was reported that the context in Platform::Sdl2Application
can't be created unless explicitly requesting Core profile, e.g. via the following SDL2 calls:
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE)
Sadly this cuts off all Legacy hardware, so we basically don't have any context creation method which would cover all systems.
When I get to it, I will add some context creation options to Platform::*Application::Configuration
(i.e., at least version and core/non-core profile specification). But it would be good to have something that just works without explicit configuration (i.e. trying core profile first and if that fails, fall back to legacy).
Anyone with OSX system willing to help with this?
Currently the internal GL state tracker expects that only Magnum and nothing else makes GL calls. This will break when:
Also the engine won't be ever completely bug-free and sometimes the state tracker might be wrong (last time in f0df35a). This function might then help when trying to debug rendering issues. Hopefully it won't evolve into some fixAllStuff()
function which would be preventively called each 5 lines :-)
There are two options, either reset the tracker to real GL state (i.e. a lot of glGet(*_BINDING)
calls) or reset the tracker to "disengaged" state. The latter would be better, but we need to ensure that all disengaged states are not valid and will be later replaced with proper values. The engine tracks the following:
0
. Also this state is immutable, so there is no need to reset it.~0u
as disengaged state and assert that no object with such ID will be ever bound? Or be really paranoid and use std::optional
instead?Renderer
and more) -- std::optional
is the only option, as in many cases (e.g. colors) all possible values are valid.Also now all binding points are initialized to 0
because that's the initial state after context creation. Probably will be wise to initialize them to disengaged value instead to avoid random bugs. This might however cause issues on drivers not supporting ARB_framebuffer_object
, as the engine would call glBindFramebuffer(0)
when the default framebuffer is accessed for the first time.
I first wrote this text as a reply to #8, but after realizing how lengthy it is I've decided it's worth a new issue. If you think it's OT, go and close it, I won't mind :)
I think it's good approach to force user to learn a little bit about conventions (e.g. monoid as in #8) before using Magnum, even if they might sound weird and are not used in other engines. Why should they choose Magnum over other engines? Magnum needs to be different.
I'd love to see a new user's learning process like this:
main.cpp
+ some directories.object->setShape(new Box({}))
to object->setSchape(new Box || new Sphere({1, 0, 0}))
. And if I wanted shape intersection instead of union I'd simply use &&
.main()
and add collision shape to object.This tutorial should serve as simple evaluation to users, whether they want to use Magnum or not. I think the key is to be user's guide and solve trivial choices instead of him - e.g. which physics framework to use (prefer one), help him with project structure (directory tree, classes etc.).
Developing convention of project structure might be valuable for user. In current state I don't know where should I put class representing a car and that's worrying, because I might put it directly into /src
, but what if /src
becomes one big mess. Maybe into /src/car
, but what if I want to add class representing a bike?
Think about it in context of new user, but keep in mind, that it should be suitable for a small project as good as for a larger one.
A community can help you a lot and I think it might be the right time to start building one. Chose one killer feature, polish its interface, craft a simple tutorial and publish it (phoronix?).
Maybe read about Ruby on Rails framework approach. I know it's different field, but I think it's worth knowing their principles.
Also keep asking yourself questions, it helps :)
All I've said is a brain dump, not a solid guide how to write and sell an engine. It's only based on my experience with building application on top of a framework. And please before taking any of previous ideas into account, try asking potential users if it's what they want.
When creating a OpenGL 3.2 context, on OS X 10.7.5 with SDL 2.0 (the framework binary, which is downloadable from the website), with the following code (ignore the logs, they are just used for debugging purposes):
LOG(INFO) << "Setting OpenGL context settings";
/* Require an OpenGL 3.2 context */
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
/* Enable double buffering and 24bt depth buffer */
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
/* Multisampling */
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, _config.sampleCount > 1 ? 1 : 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, _config.sampleCount);
// Create the Window
LOG(INFO) << "Creating Window...";
_window = SDL_CreateWindow(_windowSettings.title.c_str(),
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
(_config.windowWidth == Config::DEFAULT_WIDTH ? _windowSettings.defaultWidth : _config.windowWidth),
(_config.windowHeight == Config::DEFAULT_HEIGHT ? _windowSettings.defaultHeight : _config.windowHeight),
_windowSettings.flags | SDL_WINDOW_OPENGL);
if(!_window)
{
LOG(FATAL) << "Failed to create Window!";
LOG(FATAL) << "Reason:" << SDL_GetError();
getGame().quit(FAILED_TO_CREATE_WINDOW);
return;
}
LOG(INFO) << "Successfully created Window";
// Create our context
LOG(INFO) << "Creating OpenGL Context";
_context = SDL_GL_CreateContext(_window);
if(!_context)
{
LOG(FATAL) << "Failed to create OpenGL context";
LOG(FATAL) << "Reason: " << SDL_GetError();
getGame().quit(FAILED_TO_CREATE_OPENGL_CONTEXT);
return;
}
LOG(INFO) << "Successfully created OpenGL Context";
LOG(INFO) << "Creating Magnum Context!\n";
_magnumContext.reset(new Magnum::Context); // make a magnum context
LOG(INFO) << "Successfully created Magnum Context!\n";
// log graphics information
logGraphicsInformation();
It fails due to creating a Magnum context, as ogl_LoadFunctions is called in the constructor of Context. The error is during run-time and only occurs when I have SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
in the code. Without SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
, SDL2 does not create a 3.2 context (it will default to 2.1, in which case I can't use the in-built shaders). The runtime error received is: EXC_BAD_ACCESS in ogl_LoadFunctions() on line 2702 of gl_magnum.c.
At the current moment, the only way to upload texture information is via the Image
class. The Image
class also manages the memory for you. Thus, if you load an image from a file and store the data in a std::vector
, you must copy this data into a pointer in order for there to be no runtime errors (as your Image class will delete the memory and my std::vector
object will also attempt to delete the same memory.
e.g.
util::ImageData data = util::loadImage(source.CString());
if(data.pixels.empty())
{
return false;
}
std::uint8_t* rawData = new std::uint8_t[data.pixels.size()];
std::copy(data.pixels.begin(), data.pixels.end(), rawData);
Image2D image{Magnum::ColorFormat::RGBA, Magnum::ColorType::UnsignedByte,
{data.width, data.height}, (void*)rawData};
Magnum::Texture2D* texture = new Magnum::Texture2D;
texture->setImage(0, Magnum::TextureFormat::RGBA8, image);
I suggest, that instead of requiring to create a Magnum::Image object, you either:
util::ImageData data = util::loadImage(source.CString());
if(data.pixels.empty())
{
return false;
}
Image2D image{Magnum::ColorFormat::RGBA, Magnum::ColorType::UnsignedByte,
{data.width, data.height}, std::move(data.pixels)};
Magnum::Texture2D* texture = new Magnum::Texture2D;
texture->setImage(0, Magnum::TextureFormat::RGBA8, image);
I'm not aware of your opinions of using the STL in your library, but it would help a lot. Since std::vector
is quite commonly used for managing a buffer of memory.
Provide low-level (i.e. compile-time decision) SIMD support for whole Math
namespace. Because these classes are mostly PODs and the functions are pure and inlined at most places, I think it wouldn't be good to introduce some runtime CPU detection and code switching for each little function. This can be done in depending libraries, having each library compiled in more versions and dynamically load the most appropriate one after CPU capabilities are detected, but that's another thing.
The idea is to have basically this file structure:
Math/Vector.h
Math/Matrix.h
Math/RectangularMatrix.h
...
Math/Simd/Scalar.h
Math/Simd/Sse.h
Math/Simd/Sse2.h
...
Math/Simd/Avx2.h
Math/Simd/Neon.h
...
Every class which is currently in Math
namespace will move the current scalar implementation of vectorizable functions into Math/Simd/Scalar.h
. When some function can be vectorized using instruction set Xyz
, its specialization will be implemented in Math/Simd/Xyz.h
. If any more advanced instruction set Abc
provides better implementation, it implements its own version of the function in its Math/Simd/Abc.h
, effectively overriding the one from Xyz
.
Each header in Math/Simd/
must provide implementation for all functions. If the function cannot be vectorized using given instruction set, the file includes header of inferior instruction set (which must also be available on given platform), which might provide the implementation, this way all down to Math/Simd/Scalar.h
in tree-like hierarchy.
The build system then includes proper header from Math/Simd
into original Math/*.h
files based on the configuration.
Issues to think about:
glext.h
files?Making use of texture atlases (#2) and distance field rendering (#3).
GCC 4.7 has nearly complete C++11 support with many useful features not present in 4.6. These features are already conditinally used for public API (surrounded with #ifndef CORRADE_GCC46_COMPATIBILITY
), but using them also internally would greatly simplify the maintenance.
initialize()
methods or, in Math
namespace, with assignment operators. It is unsafe (nothing prevents us from calling initialize()
twice), leads to code duplication, causes double initialization and hurts constexpr
optimizations.BasicAnimable3D<T>
instead of Animable<3, T>
) it would shorten type traits a lot. C++14 introduces aliases for many STL type traits, so if we would inspire with that and write VectorTypeFor<dimensions, T>
instead of typename DimensionTraits<dimensions, T>::VectorType
everywhere, it would lighten up many dark corners.#define override
for GCC 4.6 is too fragile and I don't want this type of workaround in master.std::underlying_type
for "downcasts" of strongly-typed enums instead of explicitly mentioning the type every time we need to convert it to GL*
type. Also this will simplify usage of Corrade::Containers::EnumSet
class.const
and constexpr
for variables (forward compatibility with C++14).std::unordered_map::emplace()
.-std=c++11
instead of -std=c++0x
.Support for GCC 4.6 would be moved to compatibility
branch to live there with 4.4 and 4.5 compatibility workarounds. These are maintained mainly for Google Chrome Native Client toolchain.
It's awesome that all these features are already supported in Clang 3.1, so we can stay with current Clang requirements. Visual Studio 2013 needs compatibility
branch anyway.
Goal is to not force users on important platforms to develop from compatibility
branch. Doing development on it is less convenient, it gets less frequent updates and is generally not advisable, as the workarounds there might cause subtle issues when compiling the code on master branch.
MinGW has 4.7 since a long time, OSX users are using Clang exclusively.
The only distribution I know of which still has GCC 4.6 is Ubuntu 12.04 LTS. Is there any other distro I forgot? Next LTS will be 14.04 which is still some time ahead, would it be worth it to keep the compatibility until 14.04 is released and at least partially adopted (Q2 2014)?
GCC 4.8 is supported since NDK r9
, 4.7 since r8d
(which was then dropped in r9c
) and 4.6 since r8b
(until r8b
there was only 4.4). Clang is supported since r8c
. Thus the minimal supported version would be r8d
(because even with Clang we need at least libstdc++ from GCC 4.7), need to make sure that all older Androids down to 2.3 are supported by r8c
.
The x86 toolchain still uses 4.4 (and thus needs compatibility
branch anyway), the PNaCl uses Clang and ARM toolchain uses 4.7.
Even that the library doesn't yet support it, we need to check things to not make the later port too inconvenient by requiring compatibility
branch. The showstopper would be if the toolchain uses libstdc++ from GCC 4.6, but I think they are on Clang and libc++.
I got an error from building the library with audio enabled:
/Users/miguel/Documents/Programming/Projects/Repos/magnum/src/Audio/Audio.cpp: 34:1: error:
static_assert failed "ALbyte is not the same as Byte"
static_assert(std::is_same<ALbyte, Byte>::value, "ALbyte is not the same...
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
make[2]: *** [src/Audio/CMakeFiles/MagnumAudio.dir/Audio.cpp.o] Error 1
make[1]: *** [src/Audio/CMakeFiles/MagnumAudio.dir/all] Error 2
make: *** [all] Error 2
Also without audio enabled it compiles, but there is quite a few warnings, such as (there's 820 warnings of this):
expanded from macro 'IntGetProcAddress'
#define IntGetProcAddress(name) AppleGLGetProcAddress(name)
^
I'm currently trying to cover the majority of OpenGL functionality with tests to make further development less error-prone. The tests must be run with valid OpenGL context and the rendering is done only offscreen (if at all), thus the tests use windowless contexts. Also there are a few command-line utilities (magnum-info
, magnum-fontconverter
, magnum-distancefieldconverter
) which use windowless context.
Now the tests and utilities can be run only on desktop Linux, because the only windowless application implemented is Platform::WindowlessGlxApplication
(using pure GLX and X11). I have Windows box, so I can implement Platform::WindowlessWglApplication
(with WGL) when I have some time and also other windowless Linux applications for testing on EGL, Wayland etc.
But I don't have OS X to implement and test Platform::WindowlessCglApplication
using CGL. Some information is on http://renderingpipeline.com/2012/05/windowless-opengl-on-macos-x/ , it will probably be only matter of copying over contents of WindowlessGlxApplication
class and replacing the platform-specific code.
Anyone with OSX willing to help with this?
Barebone joke implementation is now in https://github.com/mosra/magnum/blob/master/src/TextureTools/Atlas.cpp. Also -- would it be possible to preestimate atlas size to avoid specifying it manually?
Tested with clang 3.2.1
on Ubuntu 13.04:
[ 94%] Building CXX object src/Text/Test/CMakeFiles/TextRendererGLTest.dir/TextRendererGLTest.cpp.o
In file included from /home/lemaigna/src/magnum/src/Text/Test/TextRendererGLTest.cpp:26:
In file included from /home/lemaigna/src/magnum/src/Text/AbstractFont.h:36:
In file included from /home/lemaigna/src/magnum/src/Texture.h:31:
In file included from /home/lemaigna/src/magnum/src/AbstractTexture.h:33:
/home/lemaigna/src/magnum/src/Buffer.h:947:177: error: chosen constructor is explicit in copy-initialization
...== 0, "Buffer::data(): the buffer size is" << bufferSize << "bytes, which can't be expressed as array of types with size" << sizeof(T), {});
^~
/usr/local/include/Corrade/Utility/Assert.h:101:20: note: expanded from macro 'CORRADE_ASSERT'
return returnValue; \
^
/home/lemaigna/src/magnum/src/Text/Test/TextRendererGLTest.cpp:174:54: note: in instantiation of function template specialization 'Magnum::Buffer::data<float>' requested here
Containers::Array<Float> vertices = vertexBuffer.data<Float>();
^
/usr/local/include/Corrade/Containers/Array.h:79:18: note: constructor declared here
explicit Array() noexcept: _data(nullptr), _size(0) {}
^
In file included from /home/lemaigna/src/magnum/src/Text/Test/TextRendererGLTest.cpp:26:
In file included from /home/lemaigna/src/magnum/src/Text/AbstractFont.h:36:
In file included from /home/lemaigna/src/magnum/src/Texture.h:31:
In file included from /home/lemaigna/src/magnum/src/AbstractTexture.h:33:
/home/lemaigna/src/magnum/src/Buffer.h:947:177: error: chosen constructor is explicit in copy-initialization
...== 0, "Buffer::data(): the buffer size is" << bufferSize << "bytes, which can't be expressed as array of types with size" << sizeof(T), {});
^~
/usr/local/include/Corrade/Utility/Assert.h:101:20: note: expanded from macro 'CORRADE_ASSERT'
return returnValue; \
^
/home/lemaigna/src/magnum/src/Text/Test/TextRendererGLTest.cpp:192:59: note: in instantiation of function template specialization 'Magnum::Buffer::data<unsigned char>'
requested here
Containers::Array<UnsignedByte> indices = indexBuffer.data<UnsignedByte>();
^
/usr/local/include/Corrade/Containers/Array.h:79:18: note: constructor declared here
explicit Array() noexcept: _data(nullptr), _size(0) {}
^
2 errors generated.
Hi, when i use the newest version mangnum and corrade, I got a link error, the error message is below:
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../../lib/libMagnum.so: undefined reference to
Corrade::Utility::Implementation::BasicConfigurationValue::toString(int const&, Corrade::Containers::EnumSet<Corrade::Utility::ConfigurationValueFlag, unsigned char, (unsigned char)255>)'`
can you help me to handle with it? Thank u!
Just a small feature to consider: support Instanced versions of DrawArrays, DrawElements functions in Mesh class.
as a subfeature: allow user to set glVertexAttribDivisor for vertex attributes, perhaps as additional option in AbstractShaderAttribute::Attribute.
Compiled with clang 3.2
on Ubuntu 13.04.
Error message:
[ 1%] Building CXX object src/CMakeFiles/MagnumObjects.dir/AbstractFramebuffer.cpp.o
magnum/src/AbstractFramebuffer.cpp:177:5: error: use of undeclared identifier 'glInvalidateFramebuffer'
glInvalidateFramebuffer(GLenum(bindInternal()), count, attachments);
CMakeCache
is here: http://pastebin.com/v0ck6gvE (main options: BUILD_GL_TESTS=ON, WITH_SDL2APPLICATION=ON)
Trying to use the code from the triangle example to ensure I have everything ready to go, and the following error message occurred during run-time.
Shader: vertex shader failed to compile with the following message:
ERROR: 2:42: '0' : syntax error syntax error
ERROR: 2:43: '1' : syntax error syntax error
Here are is the OpenGL context I used that made this error occur:
Vender: Intel Inc.
Renderer: Intel HD Graphics 3000 OpenGL Engine
Version: 3.3 INTEL-8.18.27
I'm on OS X 10.9, MacBookPro8,1, using SDL 2.
Hi there,
I'm using makefiles and when I try to use the install target it looks like it's missing the AbstractObject.h header file when it's deploying itself.
When compiling an example it says:
/x/x/x/libs/include/Magnum/Buffer.h:38:28: fatal error: AbstractObject.h: No such file or directory
If I manually postprocess and copy the file it resolves the problem.
Looks like the header file is not listed here:
https://github.com/mosra/magnum/blob/master/src/CMakeLists.txt#L105
I can make a pull request if you can confirm the problem.
Regards,
Adam
Is there any way to add PngImporter functionality to ColladaImporter? It seems to be hard-coded for TGAs only. Is there any reasonable way to get around this?
When trying to compile the magnum-examples repo, the gl_loadFunctions symbol is never found. The symbol is included in libMagnum but not exported. Modifying CMakefiles to include the objects with GlutApplication allows examples to be built.
Error:
Shader: fragment shader failed to compile with the following message:
0:0(0): error: no matching function for call to `texture(sampler2D, vec2)'
0:110(81): error: type mismatch
0:110(81): error: initializer of const variable `diffuseColor' must be a constant expression
Assertion frag.compile() failed in /home/lemaigna/src/magnum/src/Shaders/Phong.cpp on line 56
Magnum is compiled for desktop GL. The driver reports OpenGL 3.0/GLSL 1.30 support.
Output of magnum-info
: http://code.solusipse.net/0hrk/
Steps to reproduce: run the sample application viewer
with any model.
Would it be possible to use postfix "tags" for the compiled binaries? Such as _d
for debug, _s
for static or _d_s
for debug static. That way it is possible to differentiate debug from release and static from shared. I know there is a directory postfix "tag" already (for 32/64 bit builds(?)), however I would much prefer it to be for the actual binaries.
A quick fix could be this in the CMakeTextLists.txt:
# Determine if we're building a shared (dynamic) library
# And set appropriate suffixes for the executables
if(NOT BUILD_STATIC)
set(CMAKE_DEBUG_POSTFIX "_d")
else()
add_definitions(-DSTATIC_LIB)
set(CMAKE_DEBUG_POSTFIX "_d_s")
set(CMAKE_RELEASE_POSTFIX "_s")
endif()
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.