#pragma region CPL License
/*
Nuclex Native Framework
Copyright (C) 2002-2013 Nuclex Development Labs
This library is free software; you can redistribute it and/or
modify it under the terms of the IBM Common Public License as
published by the IBM Corporation; either version 1.0 of the
License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
IBM Common Public License for more details.
You should have received a copy of the IBM Common Public
License along with this library
*/
#pragma endregion // CPL License
#ifndef NUCLEX_GRAPHICS_CONFIG_H
#define NUCLEX_GRAPHICS_CONFIG_H
// --------------------------------------------------------------------------------------------- //
/// \mainpage
///
/// Nuclex.Graphics.Native wraps modern 3D graphics APIs into a convenient and portable
/// C++ interface. Unlike other abstractions which still expose the rest of the application
/// to implementation details such as lost devices, device resets and context switches,
/// this library has a clean ISO C++ interface whose objects remain valid even if you
/// switch from one graphics API to another. Application code uses graphics resources like
/// standard C++ objects, exactly like std::vector<> or std::string.
///
///
/// -
///
/// Graphics resources and interfaces use only ISO C++ headers. This means you can
/// create a Direct3D 11 or OpenGL 3 renderer without needing the DirectX SDK or
/// up-to-date OpenGL headers. Your application code will compile insanely fast
/// without requiring chunky headers like Windows.h or Boost.
///
///
/// -
///
/// You can create vertex buffers, shaders, textures, render targets and so on without
/// having to pass a factory interface around. No more CreateVertexBuffer() or
/// LoadTexture() -- all graphics resources are plain, concrete classes. If your
/// model loading code wants to create a new vertex buffer, just create one using
/// the C++ new operator.
///
///
/// -
///
/// No hazzle with destruction order. Graphics resources are plain objects. If you
/// kill the rasterizer, that doesn't mean your vertex buffers and textures become
/// invalid. Keep them, use them in a different rasterizer or delete them at any
/// time you please.
///
///
/// -
///
/// You are completely isolated from implementation-specific issues like lost devices.
/// Instead of requiring your game to seek out every single graphics resource user
/// and notify them to destroy and then rebuild their graphics resources, you do not
/// have to do a thing. Your graphics resources remain valid and usable.
///
///
/// -
///
/// Switch between graphics APIs or use multiple rasterizers at the same time with
/// the same resources. You can pass the same vertex buffer, texture or other graphics
/// resource to an OpenGL-based rasterizer and at the same time use it in
/// a Direct3D-based rasterizer. It will just work.
///
///
/// -
///
/// Designed for speed with almost no overhead compared to other graphics API wrappers.
/// There is a minimal price to pay for the observer lookup (pure call dispatching is
/// from 5% to 21% slower than a standard virtual method call, the rest is identical
/// with classical wrappers), so you don't loose any performance for having a sane
/// interface to your graphics API.
///
///
/// -
///
/// Portability. Did I mention that you can use the same code on Windows, WinRT
/// (Microsoft's new tiled UI), Linux, Android and iOS? Specific rasterizer
/// implementations mutate their constructors depending on which platform you
/// compile them on (eg. the Direct3D11Rasterizer expects a HWND in Win32 but
/// a (Windows::UI::Core::CoreWindow ^) on WinRT. Once created, forget what API
/// it is and use the rasterizer under its ISO C++ interface.
///
///
///
// --------------------------------------------------------------------------------------------- //
// Platform recognition
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
#define NUCLEX_GRAPHICS_WINRT
#elif defined(WIN32) || defined(_WIN32)
#define NUCLEX_GRAPHICS_WIN32
#else
#define NUCLEX_GRAPHICS_LINUX
#endif
// --------------------------------------------------------------------------------------------- //
// Whether to use Direct3D 11.1 (requires Windows 8)
#if defined(NUCLEX_GRAPHICS_WINRT)
#define NUCLEX_GRAPHICS_DIRECT3D11_1
#endif
// --------------------------------------------------------------------------------------------- //
// C++ language features
#if defined(_MSC_VER) && (_MSC_VER >= 1700) // Visual Studio 2012 has the C++11 features we use
#define NUCLEX_GRAPHICS_CXX11
#elif defined(__GNUG__) && ((__GNUC__ * 1000 * __GNUC_MINOR) >= 4007) // GCC 4.7 has, too
#define NUCLEX_GRAPHICS_CXX11
#else
#define NUCLEX_GRAPHICS_CXX03
#endif
// --------------------------------------------------------------------------------------------- //
// Endianness detection
#if defined(_MSC_VER) // MSVC is always little endian, including Windows on ARM
#define NUCLEX_GRAPHICS_LITTLE_ENDIAN
#elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) // GCC
#define NUCLEX_GRAPHICS_LITTLE_ENDIAN
#elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) // GCC
#define NUCLEX_GRAPHICS_BIG_ENDIAN
#else
#error Could not determine whether platform is big or little endian
#endif
// --------------------------------------------------------------------------------------------- //
// Decides whether symbols are imported from a dll (client app) or exported to
// a dll (Nuclex.Storage.Native library). The NUCLEX_GRAPHICS_SOURCE symbol is defined by
// all source files of the library, so you don't have to worry about a thing.
#if defined(_MSC_VER)
#if defined(NUCLEX_GRAPHICS_STATICLIB)
#define NUCLEX_GRAPHICS_API
#else
#if defined(NUCLEX_GRAPHICS_SOURCE)
// If we are building the DLL, export the symbols tagged like this
#define NUCLEX_GRAPHICS_API __declspec(dllexport)
#else
// If we are consuming the DLL, import the symbols tagged like this
#define NUCLEX_GRAPHICS_API __declspec(dllimport)
#endif
#endif
#elif defined(__GNUC__)
#if defined(NUCLEX_GRAPHICS_STATICLIB)
#define NUCLEX_GRAPHICS_API
#else
#if defined(NUCLEX_GRAPHICS_SOURCE)
#define NUCLEX_GRAPHICS_API __attribute__ ((visibility ("default")))
#else
// If you use -fvisibility=hidden in GCC, exception handling and RTTI would break
// if visibility wasn't set during export _and_ import because GCC would immediately
// forget all type infos encountered. See http://gcc.gnu.org/wiki/Visibility
#define NUCLEX_GRAPHICS_API __attribute__ ((visibility ("default")))
#endif
#endif
#else
#error Unknown compiler, please implement shared library macros for your system
#endif
// --------------------------------------------------------------------------------------------- //
#endif // NUCLEX_GRAPHICS_CONFIG_H