mirror of https://github.com/mosra/magnum.git
108 changed files with 4420 additions and 354 deletions
|
After Width: | Height: | Size: 8.0 KiB |
@ -0,0 +1,202 @@ |
|||||||
|
/* |
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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 getting-started Getting started |
||||||
|
@brief Get started with %Magnum in matter of minutes. |
||||||
|
|
||||||
|
@tableofcontents |
||||||
|
|
||||||
|
@section getting-started-download Download, build and install Magnum |
||||||
|
|
||||||
|
Get latest version from GitHub and install it. Read full guide on |
||||||
|
@ref building "how to download, build and install Magnum" on platform of your |
||||||
|
choice. For our first project we will use GLUT toolkit, don't forget to enable |
||||||
|
it for building using `WITH_GLUTAPPLICATION` CMake parameter. |
||||||
|
|
||||||
|
@section getting-started-bootstrap Download bootstrap project |
||||||
|
|
||||||
|
Setting up a new project can be pretty gruesome and nobody likes repeating the |
||||||
|
same process every time. %Magnum provides "bootstrap" project structures for |
||||||
|
many use cases, helping you get up and running in no time. |
||||||
|
|
||||||
|
The [bootstrap repository](https://github.com/mosra/magnum-bootstrap) is |
||||||
|
located on GitHub. The `master` branch contains just an README file and the |
||||||
|
actual bootstrap projects are in various other branches, each covering some |
||||||
|
particular use case. For your first project you would need the `base` branch, |
||||||
|
which contains only the essential files you need. Download the branch [as an |
||||||
|
archive](https://github.com/mosra/magnum-bootstrap/archive/base.zip) and |
||||||
|
extract it somewhere. Do it rather than cloning the full repository, as it's |
||||||
|
better to init your own repository from scratch to avoid having the history |
||||||
|
polluted. |
||||||
|
|
||||||
|
@section getting-started-review Review project structure |
||||||
|
|
||||||
|
The base project consists of just seven files in two subfolders. %Magnum uses |
||||||
|
CMake build system, see @ref cmake for more information. |
||||||
|
|
||||||
|
modules/FindCorrade.cmake |
||||||
|
modules/FindMagnum.cmake |
||||||
|
modules/FindGLEW.cmake |
||||||
|
src/MyApplication.cpp |
||||||
|
src/CMakeLists.txt |
||||||
|
CMakeLists.txt |
||||||
|
.gitignore |
||||||
|
|
||||||
|
In root there is pre-filled `.gitignore` for your Git project and also |
||||||
|
project-wide `CMakeLists.txt`. It just sets up project name, specifies module |
||||||
|
directory and delegates everything important to `CMakeLists.txt` in `src/` |
||||||
|
subdirectory. |
||||||
|
@code |
||||||
|
cmake_minimum_required(VERSION 2.8.8) |
||||||
|
project(MyApplication) |
||||||
|
|
||||||
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/modules/") |
||||||
|
|
||||||
|
add_subdirectory(src) |
||||||
|
@endcode |
||||||
|
|
||||||
|
Directory `modules/` contains CMake modules for finding the needed |
||||||
|
dependencies. Unlike modules for finding e.g. GLUT and OpenGL, which are part |
||||||
|
of standard CMake installation, these aren't part of it and thus must be |
||||||
|
distributed with the project. These files are just verbatim copied from %Magnum |
||||||
|
repository. |
||||||
|
|
||||||
|
Directory `src/` contains the actual project. To keep things simple, the |
||||||
|
project consists of just one source file with the most minimal code possible: |
||||||
|
@code |
||||||
|
#include <Platform/GlutApplication.h> |
||||||
|
#include <DefaultFramebuffer.h> |
||||||
|
|
||||||
|
using namespace Magnum; |
||||||
|
|
||||||
|
class MyApplication: public Platform::Application { |
||||||
|
public: |
||||||
|
explicit MyApplication(const Arguments& arguments); |
||||||
|
|
||||||
|
protected: |
||||||
|
void viewportEvent(const Vector2i& size) override; |
||||||
|
void drawEvent() override; |
||||||
|
}; |
||||||
|
|
||||||
|
MyApplication::MyApplication(const Arguments& arguments): Platform::Application(arguments) {} |
||||||
|
|
||||||
|
void MyApplication::viewportEvent(const Vector2i& size) { |
||||||
|
defaultFramebuffer.setViewport({{}, size}); |
||||||
|
} |
||||||
|
|
||||||
|
void MyApplication::drawEvent() { |
||||||
|
defaultFramebuffer.clear(FramebufferClear::Color); |
||||||
|
swapBuffers(); |
||||||
|
} |
||||||
|
|
||||||
|
MAGNUM_APPLICATION_MAIN(MyApplication) |
||||||
|
@endcode |
||||||
|
|
||||||
|
The application essentially does nothing, just clears properly sized screen |
||||||
|
framebuffer to default (black) color and then does buffer swap to actually |
||||||
|
display it on the screen. `CMakeLists.txt` finds %Magnum, sets up compiler |
||||||
|
flags, creates the executable and links it to all needed libraries: |
||||||
|
@code |
||||||
|
find_package(Magnum REQUIRED GlutApplication) |
||||||
|
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CORRADE_CXX_FLAGS}") |
||||||
|
include_directories(${MAGNUM_INCLUDE_DIRS} ${MAGNUM_APPLICATION_INCLUDE_DIRS}) |
||||||
|
|
||||||
|
add_executable(MyApplication MyApplication.cpp) |
||||||
|
target_link_libraries(MyApplication |
||||||
|
${MAGNUM_LIBRARIES} |
||||||
|
${MAGNUM_APPLICATION_LIBRARIES}) |
||||||
|
@endcode |
||||||
|
|
||||||
|
In the following tutorials the code will be explained more thoroughly. |
||||||
|
|
||||||
|
@section getting-started-build Build it and run |
||||||
|
|
||||||
|
In Linux (and other Unix-based OSs) you can build the example using the |
||||||
|
following three commands: create out-of-source build directory, run cmake in it |
||||||
|
and then run make. The application binary will then appear in src/ subdirectory |
||||||
|
of build dir: |
||||||
|
|
||||||
|
mkdir -p build && cd build |
||||||
|
cmake .. |
||||||
|
make |
||||||
|
./src/MyApplication |
||||||
|
|
||||||
|
On Windows, if you don't want to touch the command-line, the easiest way is to |
||||||
|
open root `CMakeLists.txt` in QtCreator, let it import the project and then |
||||||
|
just build and run the application. If CMake isn't able to find the |
||||||
|
dependencies or the building fails for some reason, you might want to look at |
||||||
|
@ref building-windows-troubleshooting. |
||||||
|
|
||||||
|
@image html getting-started.png |
||||||
|
@image latex getting-started.png |
||||||
|
|
||||||
|
Now you can try to change something in the code. Without going too deep into |
||||||
|
the concepts of graphics programming, we can change clear color to something |
||||||
|
else and also print basic information about the GPU the engine is running on. |
||||||
|
First include the needed headers: |
||||||
|
@code |
||||||
|
#include <Color.h> |
||||||
|
#include <Context.h> |
||||||
|
#include <Renderer.h> |
||||||
|
@endcode |
||||||
|
|
||||||
|
And in the constructor (which is currently empty) change the clear color and |
||||||
|
print something to debug output: |
||||||
|
@code |
||||||
|
Renderer::setClearColor({0.07f, 0.44f, 0.73f}); |
||||||
|
|
||||||
|
Debug() << "Hello! This application is running on" << Context::current()->version() |
||||||
|
<< "using" << Context::current()->rendererString(); |
||||||
|
@endcode |
||||||
|
|
||||||
|
After rebuilding and starting the application, the clear color changes to |
||||||
|
blueish one and something like this would be printed to the console: |
||||||
|
@code |
||||||
|
Hello! This application is running on OpenGL 3.3 using Geforce GT 330M |
||||||
|
@endcode |
||||||
|
|
||||||
|
@image html getting-started-blue.png |
||||||
|
@image latex getting-started-blue.png |
||||||
|
|
||||||
|
@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 in @ref example-index "step-by-step tutorial". |
||||||
|
Then you can dig deeper and try other examples, read about |
||||||
|
@ref features "fundamental principles" in the documentation and start |
||||||
|
experimenting on your own! |
||||||
|
|
||||||
|
@section getting-started-more Additional information |
||||||
|
|
||||||
|
- @subpage building |
||||||
|
- @subpage building-plugins |
||||||
|
- @subpage building-integration |
||||||
|
- @subpage cmake |
||||||
|
- @subpage cmake-plugins |
||||||
|
- @subpage cmake-integration |
||||||
|
|
||||||
|
*/ |
||||||
|
} |
||||||
|
After Width: | Height: | Size: 8.0 KiB |
@ -0,0 +1,97 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "AbstractImporter.h" |
||||||
|
|
||||||
|
#include <fstream> |
||||||
|
#include <Containers/Array.h> |
||||||
|
#include <Utility/Assert.h> |
||||||
|
|
||||||
|
namespace Magnum { namespace Audio { |
||||||
|
|
||||||
|
AbstractImporter::AbstractImporter() = default; |
||||||
|
|
||||||
|
AbstractImporter::AbstractImporter(PluginManager::AbstractManager* manager, std::string plugin): PluginManager::AbstractPlugin(manager, std::move(plugin)) {} |
||||||
|
|
||||||
|
bool AbstractImporter::openData(Containers::ArrayReference<const unsigned char> data) { |
||||||
|
CORRADE_ASSERT(features() & Feature::OpenData, |
||||||
|
"Audio::AbstractImporter::openData(): feature not supported", nullptr); |
||||||
|
|
||||||
|
close(); |
||||||
|
doOpenData(data); |
||||||
|
return isOpened(); |
||||||
|
} |
||||||
|
|
||||||
|
void AbstractImporter::doOpenData(Containers::ArrayReference<const unsigned char>) { |
||||||
|
CORRADE_ASSERT(false, "Audio::AbstractImporter::openData(): feature advertised but not implemented", ); |
||||||
|
} |
||||||
|
|
||||||
|
bool AbstractImporter::openFile(const std::string& filename) { |
||||||
|
close(); |
||||||
|
doOpenFile(filename); |
||||||
|
return isOpened(); |
||||||
|
} |
||||||
|
|
||||||
|
void AbstractImporter::doOpenFile(const std::string& filename) { |
||||||
|
CORRADE_ASSERT(features() & Feature::OpenData, "Audio::AbstractImporter::openFile(): not implemented", ); |
||||||
|
|
||||||
|
/* Open file */ |
||||||
|
std::ifstream in(filename.data(), std::ios::binary); |
||||||
|
if(!in.good()) { |
||||||
|
Error() << "Trade::AbstractImporter::openFile(): cannot open file" << filename; |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
/* Create array to hold file contents */ |
||||||
|
in.seekg(0, std::ios::end); |
||||||
|
Containers::Array<unsigned char> data(in.tellg()); |
||||||
|
|
||||||
|
/* Read data, close */ |
||||||
|
in.seekg(0, std::ios::beg); |
||||||
|
in.read(reinterpret_cast<char*>(data.begin()), data.size()); |
||||||
|
in.close(); |
||||||
|
|
||||||
|
doOpenData(data); |
||||||
|
} |
||||||
|
|
||||||
|
void AbstractImporter::close() { |
||||||
|
if(isOpened()) doClose(); |
||||||
|
} |
||||||
|
|
||||||
|
Buffer::Format AbstractImporter::format() const { |
||||||
|
CORRADE_ASSERT(isOpened(), "Audio::AbstractImporter::format(): no file opened", {}); |
||||||
|
return doFormat(); |
||||||
|
} |
||||||
|
|
||||||
|
UnsignedInt AbstractImporter::frequency() const { |
||||||
|
CORRADE_ASSERT(isOpened(), "Audio::AbstractImporter::frequency(): no file opened", {}); |
||||||
|
return doFrequency(); |
||||||
|
} |
||||||
|
|
||||||
|
Containers::Array<unsigned char> AbstractImporter::data() { |
||||||
|
CORRADE_ASSERT(isOpened(), "Audio::AbstractImporter::data(): no file opened", {}); |
||||||
|
return doData(); |
||||||
|
} |
||||||
|
|
||||||
|
}} |
||||||
@ -0,0 +1,163 @@ |
|||||||
|
#ifndef Magnum_Audio_AbstractImporter_h |
||||||
|
#define Magnum_Audio_AbstractImporter_h |
||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
/** @file Audio/AbstractImporter.h
|
||||||
|
* @brief Class Magnum::Audio::AbstractImporter |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <PluginManager/AbstractPlugin.h> |
||||||
|
|
||||||
|
#include "Magnum.h" |
||||||
|
#include "Audio/Buffer.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace Audio { |
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Base for audio importer plugins |
||||||
|
|
||||||
|
@section Audio-AbstractImporter-subclassing Subclassing |
||||||
|
|
||||||
|
Plugin implements function doFeatures(), doIsOpened(), one of or both |
||||||
|
doOpenData() and doOpenFile() functions, function doClose() and data access |
||||||
|
functions doFormat(), doFrequency() and doData(). |
||||||
|
|
||||||
|
You don't need to do most of the redundant sanity checks, these things are |
||||||
|
checked by the implementation: |
||||||
|
|
||||||
|
- Functions doOpenData() and doOpenFile() are called after the previous file |
||||||
|
was closed, function doClose() is called only if there is any file opened. |
||||||
|
- Function doOpenData() is called only if @ref Feature "Feature::OpenData" |
||||||
|
is supported. |
||||||
|
- All `do*()` implementations working on opened file are called only if |
||||||
|
there is any file opened. |
||||||
|
*/ |
||||||
|
class MAGNUM_AUDIO_EXPORT AbstractImporter: public PluginManager::AbstractPlugin { |
||||||
|
CORRADE_PLUGIN_INTERFACE("cz.mosra.magnum.Audio.AbstractImporter/0.1") |
||||||
|
|
||||||
|
public: |
||||||
|
/**
|
||||||
|
* @brief Features supported by this importer |
||||||
|
* |
||||||
|
* @see Features, features() |
||||||
|
*/ |
||||||
|
enum class Feature: UnsignedByte { |
||||||
|
/** Opening files from raw data using openData() */ |
||||||
|
OpenData = 1 << 0 |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Features supported by this importer |
||||||
|
* |
||||||
|
* @see features() |
||||||
|
*/ |
||||||
|
typedef Containers::EnumSet<Feature, UnsignedByte> Features; |
||||||
|
|
||||||
|
/** @brief Default constructor */ |
||||||
|
explicit AbstractImporter(); |
||||||
|
|
||||||
|
/** @brief Plugin manager constructor */ |
||||||
|
explicit AbstractImporter(PluginManager::AbstractManager* manager, std::string plugin); |
||||||
|
|
||||||
|
/** @brief Features supported by this importer */ |
||||||
|
Features features() const { return doFeatures(); } |
||||||
|
|
||||||
|
/** @brief Whether any file is opened */ |
||||||
|
bool isOpened() const { return doIsOpened(); } |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Open raw data |
||||||
|
* |
||||||
|
* Closes previous file, if it was opened, and tries to open given |
||||||
|
* file. Available only if @ref Feature "Feature::OpenData" is |
||||||
|
* supported. Returns `true` on success, `false` otherwise. |
||||||
|
* @see features(), openFile() |
||||||
|
*/ |
||||||
|
bool openData(Containers::ArrayReference<const unsigned char> data); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Open file |
||||||
|
* |
||||||
|
* Closes previous file, if it was opened, and tries to open given |
||||||
|
* file. Returns `true` on success, `false` otherwise. |
||||||
|
* @see features(), openData() |
||||||
|
*/ |
||||||
|
bool openFile(const std::string& filename); |
||||||
|
|
||||||
|
/** @brief Close file */ |
||||||
|
void close(); |
||||||
|
|
||||||
|
/** @{ @name Data access */ |
||||||
|
|
||||||
|
/** @brief Sample format */ |
||||||
|
Buffer::Format format() const; |
||||||
|
|
||||||
|
/** @brief Sample frequency */ |
||||||
|
UnsignedInt frequency() const; |
||||||
|
|
||||||
|
/** @brief Sample data */ |
||||||
|
Containers::Array<unsigned char> data(); |
||||||
|
|
||||||
|
/*@}*/ |
||||||
|
|
||||||
|
#ifndef DOXYGEN_GENERATING_OUTPUT |
||||||
|
private: |
||||||
|
#else |
||||||
|
protected: |
||||||
|
#endif |
||||||
|
/** @brief Implementation for features() */ |
||||||
|
virtual Features doFeatures() const = 0; |
||||||
|
|
||||||
|
/** @brief Implementation for isOpened() */ |
||||||
|
virtual bool doIsOpened() const = 0; |
||||||
|
|
||||||
|
/** @brief Implementation for openData() */ |
||||||
|
virtual void doOpenData(Containers::ArrayReference<const unsigned char> data); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Implementation for openFile() |
||||||
|
* |
||||||
|
* If @ref Feature "Feature::OpenData" is supported, default |
||||||
|
* implementation opens the file and calls doOpenData() with its |
||||||
|
* contents. |
||||||
|
*/ |
||||||
|
virtual void doOpenFile(const std::string& filename); |
||||||
|
|
||||||
|
/** @brief Implementation for close() */ |
||||||
|
virtual void doClose() = 0; |
||||||
|
|
||||||
|
/** @brief Implementation for format() */ |
||||||
|
virtual Buffer::Format doFormat() const = 0; |
||||||
|
|
||||||
|
/** @brief Implementation for frequency() */ |
||||||
|
virtual UnsignedInt doFrequency() const = 0; |
||||||
|
|
||||||
|
/** @brief Implementation for data() */ |
||||||
|
virtual Containers::Array<unsigned char> doData() = 0; |
||||||
|
}; |
||||||
|
|
||||||
|
}} |
||||||
|
|
||||||
|
#endif |
||||||
@ -0,0 +1,49 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <type_traits> |
||||||
|
#include <al.h> |
||||||
|
|
||||||
|
#include "Types.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace Audio { |
||||||
|
|
||||||
|
/* Verify types */ |
||||||
|
static_assert(std::is_same<ALubyte, UnsignedByte>::value, "ALubyte is not the same as UnsignedByte"); |
||||||
|
static_assert(std::is_same<ALbyte, Byte>::value, "ALbyte is not the same as Byte"); |
||||||
|
static_assert(std::is_same<ALushort, UnsignedShort>::value, "ALushort is not the same as UnsignedShort"); |
||||||
|
static_assert(std::is_same<ALshort, Short>::value, "ALshort is not the same as Short"); |
||||||
|
static_assert(std::is_same<ALuint, UnsignedInt>::value, "ALuint is not the same as UnsignedInt"); |
||||||
|
static_assert(std::is_same<ALint, Int>::value, "ALint is not the same as Int"); |
||||||
|
static_assert(std::is_same<ALsizei, Int>::value, "ALsizei is not the same as Int"); |
||||||
|
static_assert(std::is_same<ALfloat, Float>::value, "ALfloat is not the same as Float"); |
||||||
|
#ifndef MAGNUM_TARGET_GLES |
||||||
|
static_assert(std::is_same<ALdouble, Double>::value, "ALdouble is not the same as Double"); |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Verify boolean values */ |
||||||
|
static_assert(AL_FALSE == false, "AL_FALSE is not the same as false"); |
||||||
|
static_assert(AL_TRUE == true, "AL_TRUE is not the same as true"); |
||||||
|
|
||||||
|
}} |
||||||
@ -0,0 +1,41 @@ |
|||||||
|
#ifndef Magnum_Audio_Audio_h |
||||||
|
#define Magnum_Audio_Audio_h |
||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
/** @file
|
||||||
|
* @brief Forward declarations for Magnum::Audio namespace |
||||||
|
*/ |
||||||
|
|
||||||
|
namespace Magnum { namespace Audio { |
||||||
|
|
||||||
|
class AbstractImporter; |
||||||
|
class Buffer; |
||||||
|
class Context; |
||||||
|
class Source; |
||||||
|
/* Renderer used only statically */ |
||||||
|
|
||||||
|
}} |
||||||
|
|
||||||
|
#endif |
||||||
@ -0,0 +1,44 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "Buffer.h" |
||||||
|
|
||||||
|
#include <Utility/Debug.h> |
||||||
|
|
||||||
|
namespace Magnum { namespace Audio { |
||||||
|
|
||||||
|
Debug operator<<(Debug debug, const Buffer::Format value) { |
||||||
|
switch(value) { |
||||||
|
#define _c(value) case Buffer::Format::value: return debug << "Audio::Buffer::Format::" #value; |
||||||
|
_c(Mono8) |
||||||
|
_c(Mono16) |
||||||
|
_c(Stereo8) |
||||||
|
_c(Stereo16) |
||||||
|
#undef _c |
||||||
|
} |
||||||
|
|
||||||
|
return debug << "Audio::Buffer::Format::(invalid)"; |
||||||
|
} |
||||||
|
|
||||||
|
}} |
||||||
@ -0,0 +1,120 @@ |
|||||||
|
#ifndef Magnum_Audio_Buffer_h |
||||||
|
#define Magnum_Audio_Buffer_h |
||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
/** @file
|
||||||
|
* @brief Class Magnum::Audio::Buffer |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <utility> |
||||||
|
#include <al.h> |
||||||
|
#include <Containers/Array.h> |
||||||
|
|
||||||
|
#include "Magnum.h" |
||||||
|
#include "Audio/magnumAudioVisibility.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace Audio { |
||||||
|
|
||||||
|
/** @brief Sample buffer */ |
||||||
|
class Buffer { |
||||||
|
public: |
||||||
|
/**
|
||||||
|
* @brief Sample format |
||||||
|
* |
||||||
|
* @note Multi-channel format is played without 3D spatialization |
||||||
|
* (useful for background music) |
||||||
|
* @see @ref setData() |
||||||
|
*/ |
||||||
|
enum class Format: ALenum { |
||||||
|
Mono8 = AL_FORMAT_MONO8, /**< 8-bit unsigned mono */ |
||||||
|
Mono16 = AL_FORMAT_MONO16, /**< 16-bit signed mono */ |
||||||
|
Stereo8 = AL_FORMAT_STEREO8, /**< 8-bit interleaved unsigned stereo */ |
||||||
|
Stereo16 = AL_FORMAT_STEREO16 /**< 16-bit interleaved signed stereo */ |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constructor |
||||||
|
* |
||||||
|
* Creates OpenAL buffer object. |
||||||
|
* @see @fn_al{GenBuffers} |
||||||
|
*/ |
||||||
|
explicit Buffer() { alGenBuffers(1, &_id); } |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destructor |
||||||
|
* |
||||||
|
* Deletes OpenAL buffer object. |
||||||
|
* @see @fn_al{DeleteBuffers} |
||||||
|
*/ |
||||||
|
~Buffer() { if(_id) alDeleteBuffers(1, &_id); } |
||||||
|
|
||||||
|
/** @brief Copying is not allowed */ |
||||||
|
Buffer(const Buffer&) = delete; |
||||||
|
|
||||||
|
/** @brief Move constructor */ |
||||||
|
Buffer(Buffer&& other); |
||||||
|
|
||||||
|
/** @brief Copying is not allowed */ |
||||||
|
Buffer& operator=(const Buffer&) = delete; |
||||||
|
|
||||||
|
/** @brief Move assignment */ |
||||||
|
Buffer& operator=(Buffer&& other); |
||||||
|
|
||||||
|
/** @brief OpenAL buffer ID */ |
||||||
|
ALuint id() const { return _id; } |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set buffer data |
||||||
|
* @param format Sample format |
||||||
|
* @param data Data |
||||||
|
* @param frequency Frequency |
||||||
|
* @return Reference to self (for method chaining) |
||||||
|
* |
||||||
|
* @see @fn_al{BufferData} |
||||||
|
*/ |
||||||
|
Buffer& setData(Format format, Containers::ArrayReference<const void> data, ALsizei frequency) { |
||||||
|
alBufferData(_id, ALenum(format), data, data.size(), frequency); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
private: |
||||||
|
ALuint _id; |
||||||
|
}; |
||||||
|
|
||||||
|
/** @debugoperator{Magnum::Audio::Buffer} */ |
||||||
|
Debug MAGNUM_AUDIO_EXPORT operator<<(Debug debug, Buffer::Format value); |
||||||
|
|
||||||
|
inline Buffer::Buffer(Buffer&& other): _id(other._id) { |
||||||
|
other._id = 0; |
||||||
|
} |
||||||
|
|
||||||
|
inline Buffer& Buffer::operator=(Buffer&& other) { |
||||||
|
std::swap(_id, other._id); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
}} |
||||||
|
|
||||||
|
#endif |
||||||
@ -0,0 +1,55 @@ |
|||||||
|
# |
||||||
|
# This file is part of Magnum. |
||||||
|
# |
||||||
|
# Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
# |
||||||
|
|
||||||
|
find_package(OpenAL REQUIRED) |
||||||
|
|
||||||
|
include_directories(${OPENAL_INCLUDE_DIR}) |
||||||
|
|
||||||
|
set(MagnumAudio_SOURCES |
||||||
|
AbstractImporter.cpp |
||||||
|
Audio.cpp |
||||||
|
Buffer.cpp |
||||||
|
Context.cpp |
||||||
|
Renderer.cpp |
||||||
|
Source.cpp) |
||||||
|
|
||||||
|
set(MagnumAudio_HEADERS |
||||||
|
AbstractImporter.h |
||||||
|
Audio.h |
||||||
|
Buffer.h |
||||||
|
Context.h |
||||||
|
Renderer.h |
||||||
|
Source.h |
||||||
|
|
||||||
|
magnumAudioVisibility.h) |
||||||
|
|
||||||
|
add_library(MagnumAudio ${SHARED_OR_STATIC} ${MagnumAudio_SOURCES}) |
||||||
|
target_link_libraries(MagnumAudio ${CORRADE_PLUGINMANAGER_LIBRARIES} ${OPENAL_LIBRARY}) |
||||||
|
|
||||||
|
install(TARGETS MagnumAudio DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) |
||||||
|
install(FILES ${MagnumAudio_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Audio) |
||||||
|
|
||||||
|
if(BUILD_TESTS) |
||||||
|
add_subdirectory(Test) |
||||||
|
endif() |
||||||
@ -0,0 +1,65 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "Context.h" |
||||||
|
|
||||||
|
#include <alc.h> |
||||||
|
#include <Utility/Assert.h> |
||||||
|
#include <Utility/Debug.h> |
||||||
|
|
||||||
|
#include "Magnum.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace Audio { |
||||||
|
|
||||||
|
Context* Context::_current = nullptr; |
||||||
|
|
||||||
|
Context::Context() { |
||||||
|
CORRADE_ASSERT(!_current, "Audio::Context: context already created", ); |
||||||
|
|
||||||
|
/* Open default device */ |
||||||
|
const ALCchar* const defaultDevice = alcGetString(nullptr, ALC_DEFAULT_DEVICE_SPECIFIER); |
||||||
|
_device = alcOpenDevice(defaultDevice); |
||||||
|
if(!_device) { |
||||||
|
Error() << "Audio::Context: cannot open sound device" << defaultDevice; |
||||||
|
std::exit(1); |
||||||
|
} |
||||||
|
|
||||||
|
_context = alcCreateContext(_device, nullptr); |
||||||
|
if(!_context) { |
||||||
|
Error() << "Audio::Context: cannot create context:" << alcGetError(_device); |
||||||
|
std::exit(1); |
||||||
|
} |
||||||
|
|
||||||
|
alcMakeContextCurrent(_context); |
||||||
|
_current = this; |
||||||
|
} |
||||||
|
|
||||||
|
Context::~Context() { |
||||||
|
CORRADE_INTERNAL_ASSERT(_current == this); |
||||||
|
|
||||||
|
alcDestroyContext(_context); |
||||||
|
alcCloseDevice(_device); |
||||||
|
} |
||||||
|
|
||||||
|
}} |
||||||
@ -0,0 +1,95 @@ |
|||||||
|
#ifndef Magnum_Audio_Context_h |
||||||
|
#define Magnum_Audio_Context_h |
||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
/** @file
|
||||||
|
* @brief Class Magnum::Audio::Context |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <al.h> |
||||||
|
#include <string> |
||||||
|
|
||||||
|
#include "Audio/magnumAudioVisibility.h" |
||||||
|
|
||||||
|
#ifndef DOXYGEN_GENERATING_OUTPUT |
||||||
|
typedef struct ALCdevice_struct ALCdevice; |
||||||
|
typedef struct ALCcontext_struct ALCcontext; |
||||||
|
#endif |
||||||
|
|
||||||
|
namespace Magnum { namespace Audio { |
||||||
|
|
||||||
|
/**
|
||||||
|
@brief OpenAL context |
||||||
|
*/ |
||||||
|
class MAGNUM_AUDIO_EXPORT Context { |
||||||
|
public: |
||||||
|
/** @brief Current context */ |
||||||
|
static Context* current() { return _current; } |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constructor |
||||||
|
* |
||||||
|
* Creates OpenAL context. |
||||||
|
*/ |
||||||
|
explicit Context(); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destructor |
||||||
|
* |
||||||
|
* Destroys OpenAL context. |
||||||
|
*/ |
||||||
|
~Context(); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Vendor string |
||||||
|
* |
||||||
|
* @see rendererString(), @fn_al{GetString} with @def_al{VENDOR} |
||||||
|
*/ |
||||||
|
std::string vendorString() const { return alGetString(AL_VENDOR); } |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief %Renderer string |
||||||
|
* |
||||||
|
* @see vendorString(), @fn_al{GetString} with @def_al{RENDERER} |
||||||
|
*/ |
||||||
|
std::string rendererString() const { return alGetString(AL_RENDERER); } |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Version string |
||||||
|
* |
||||||
|
* @see @fn_al{GetString} with @def_al{VERSION} |
||||||
|
*/ |
||||||
|
std::string versionString() const { return alGetString(AL_VERSION); } |
||||||
|
|
||||||
|
private: |
||||||
|
static Context* _current; |
||||||
|
|
||||||
|
ALCdevice* _device; |
||||||
|
ALCcontext* _context; |
||||||
|
}; |
||||||
|
|
||||||
|
}} |
||||||
|
|
||||||
|
#endif |
||||||
@ -0,0 +1,46 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "Renderer.h" |
||||||
|
|
||||||
|
#include <Utility/Debug.h> |
||||||
|
|
||||||
|
namespace Magnum { namespace Audio { |
||||||
|
|
||||||
|
Debug operator<<(Debug debug, const Renderer::Error value) { |
||||||
|
switch(value) { |
||||||
|
#define _c(value) case Renderer::Error::value: return debug << "Audio::Renderer::Error::" #value; |
||||||
|
_c(NoError) |
||||||
|
_c(InvalidName) |
||||||
|
_c(InvalidEnum) |
||||||
|
_c(InvalidValue) |
||||||
|
_c(InvalidOperation) |
||||||
|
_c(OutOfMemory) |
||||||
|
#undef _c |
||||||
|
} |
||||||
|
|
||||||
|
return debug << "Audio::Renderer::Error::(invalid)"; |
||||||
|
} |
||||||
|
|
||||||
|
}} |
||||||
@ -0,0 +1,202 @@ |
|||||||
|
#ifndef Magnum_Audio_Renderer_h |
||||||
|
#define Magnum_Audio_Renderer_h |
||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
/** @file
|
||||||
|
* @brief Class Magnum::Audio::Renderer |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <al.h> |
||||||
|
|
||||||
|
#include "Math/Vector3.h" |
||||||
|
#include "Magnum.h" |
||||||
|
#include "Audio/magnumAudioVisibility.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace Audio { |
||||||
|
|
||||||
|
/** @brief Global renderer configuration */ |
||||||
|
class Renderer { |
||||||
|
public: |
||||||
|
Renderer() = delete; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Error status |
||||||
|
* |
||||||
|
* @see error() |
||||||
|
*/ |
||||||
|
enum class Error: ALenum { |
||||||
|
NoError = AL_NO_ERROR, /**< No error occured */ |
||||||
|
InvalidName = AL_INVALID_NAME, /**< Invalid name parameter */ |
||||||
|
InvalidEnum = AL_INVALID_ENUM, /**< Invalid enum parameter */ |
||||||
|
InvalidValue = AL_INVALID_VALUE, /**< Invalid enum value parameter */ |
||||||
|
InvalidOperation = AL_INVALID_OPERATION, /**< Illegal call */ |
||||||
|
OutOfMemory = AL_OUT_OF_MEMORY /**< Unable to allocate memory */ |
||||||
|
}; |
||||||
|
|
||||||
|
/** @brief Error status */ |
||||||
|
static Error error() { return Error(alGetError()); } |
||||||
|
|
||||||
|
/** @{ @name Listener positioning */ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set listener position |
||||||
|
* |
||||||
|
* Default is `{0.0f, 0.0f, 0.0f}`. |
||||||
|
* @see @fn_al{Listenerfv} with @def_al{POSITION} |
||||||
|
*/ |
||||||
|
static void setListenerPosition(const Vector3& position) { |
||||||
|
alListenerfv(AL_POSITION, position.data()); |
||||||
|
} |
||||||
|
|
||||||
|
/** @overload
|
||||||
|
* @see @fn_al{Listeneriv} with @def_al{POSITION} |
||||||
|
*/ |
||||||
|
static void setListenerPosition(const Vector3i& position) { |
||||||
|
alListeneriv(AL_POSITION, position.data()); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set listener orientation |
||||||
|
* |
||||||
|
* The values must be linearly independent and don't need to be |
||||||
|
* normalized. Default is -Z and +Y. |
||||||
|
* @see @fn_al{Listenerfv} with @def_al{ORIENTATION} |
||||||
|
*/ |
||||||
|
static void setListenerOrientation(const Vector3& forward, const Vector3& up); |
||||||
|
|
||||||
|
/** @overload
|
||||||
|
* @see @fn_al{Listeneriv} with @def_al{ORIENTATION} |
||||||
|
*/ |
||||||
|
static void setListenerOrientation(const Vector3i& forward, const Vector3i& up); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set listener velocity |
||||||
|
* |
||||||
|
* Default is `{0.0f, 0.0f, 0.0f}`. |
||||||
|
* @see @fn_al{Listenerfv} with @def_al{VELOCITY} |
||||||
|
*/ |
||||||
|
static void setListenerVelocity(const Vector3& velocity) { |
||||||
|
alListenerfv(AL_VELOCITY, velocity.data()); |
||||||
|
} |
||||||
|
|
||||||
|
/** @overload
|
||||||
|
* @see @fn_al{Listeneriv} with @def_al{VELOCITY} |
||||||
|
*/ |
||||||
|
static void setListenerVelocity(const Vector3i& velocity) { |
||||||
|
alListeneriv(AL_VELOCITY, velocity.data()); |
||||||
|
} |
||||||
|
|
||||||
|
/*@}*/ |
||||||
|
|
||||||
|
/** @{ @name Global behavior */ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Distance model |
||||||
|
* |
||||||
|
* @see setDistanceModel() |
||||||
|
*/ |
||||||
|
enum class DistanceModel: ALenum { |
||||||
|
/** No distance attenuation calculation */ |
||||||
|
None = AL_NONE, |
||||||
|
|
||||||
|
/** Inverse distance */ |
||||||
|
Inverse = AL_INVERSE_DISTANCE, |
||||||
|
|
||||||
|
/** Inverse distance, clamped */ |
||||||
|
InverseClamped = AL_INVERSE_DISTANCE_CLAMPED, |
||||||
|
|
||||||
|
/** Linear distance */ |
||||||
|
Linear = AL_LINEAR_DISTANCE, |
||||||
|
|
||||||
|
/** Linear distance, clamped */ |
||||||
|
LinearClamped = AL_LINEAR_DISTANCE_CLAMPED, |
||||||
|
|
||||||
|
/** Exponential distance */ |
||||||
|
Exponent = AL_EXPONENT_DISTANCE, |
||||||
|
|
||||||
|
/** Exponential distance, clamped */ |
||||||
|
ExponentClamped = AL_EXPONENT_DISTANCE_CLAMPED |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set listener gain |
||||||
|
* |
||||||
|
* Default is `1.0f`, which means that the sound is unattenuated. |
||||||
|
* If set to `0.0f`, all sound is muted. |
||||||
|
* @see @fn_al{Listenerf} with @def_al{GAIN} |
||||||
|
*/ |
||||||
|
static void setListenerGain(Float gain) { |
||||||
|
alListenerf(AL_GAIN, gain); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set Doppler factor |
||||||
|
* |
||||||
|
* Default is `1.0f`. If set to `0.0f`, the effect is disabled. |
||||||
|
* @see @ref setSpeedOfSound(), @fn_al{DopplerFactor} |
||||||
|
*/ |
||||||
|
static void setDopplerFactor(Float factor) { |
||||||
|
alDopplerFactor(factor); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set speed of sound |
||||||
|
* |
||||||
|
* Default is `343.3f` (meters per second). |
||||||
|
* @see @ref setDopplerFactor(), @fn_al{SpeedOfSound} |
||||||
|
*/ |
||||||
|
static void setSpeedOfSound(Float speed) { |
||||||
|
alSpeedOfSound(speed); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set distance model |
||||||
|
* |
||||||
|
* Default is @ref DistanceModel "DistanceModel::InverseClamped". |
||||||
|
* @see @fn_al{DistanceModel} |
||||||
|
*/ |
||||||
|
static void setDistanceModel(DistanceModel model) { |
||||||
|
alDistanceModel(ALenum(model)); |
||||||
|
} |
||||||
|
|
||||||
|
/*@}*/ |
||||||
|
}; |
||||||
|
|
||||||
|
/** @debugoperator{Magnum::Audio::Renderer} */ |
||||||
|
Debug MAGNUM_AUDIO_EXPORT operator<<(Debug debug, Renderer::Error value); |
||||||
|
|
||||||
|
inline void Renderer::setListenerOrientation(const Vector3& forward, const Vector3& up) { |
||||||
|
const Vector3 data[] = {forward, up}; |
||||||
|
alListenerfv(AL_ORIENTATION, data[0].data()); |
||||||
|
} |
||||||
|
|
||||||
|
inline void Renderer::setListenerOrientation(const Vector3i& forward, const Vector3i& up) { |
||||||
|
const Vector3i data[] = {forward, up}; |
||||||
|
alListeneriv(AL_ORIENTATION, data[0].data()); |
||||||
|
} |
||||||
|
|
||||||
|
}} |
||||||
|
|
||||||
|
#endif |
||||||
@ -0,0 +1,123 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "Source.h" |
||||||
|
|
||||||
|
#include "Audio/Buffer.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace Audio { |
||||||
|
|
||||||
|
/** @todo C++14: use VLA to avoid unnecessary allocations */ |
||||||
|
|
||||||
|
Source& Source::setBuffer(Buffer* buffer) { |
||||||
|
alSourcei(_id, AL_BUFFER, buffer ? buffer->id() : 0); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
namespace { |
||||||
|
|
||||||
|
const ALuint* sourceIds(const std::initializer_list<Source*>& sources) { |
||||||
|
ALuint* const ids = new ALuint[sources.size()]; |
||||||
|
for(auto it = sources.begin(); it != sources.end(); ++it) { |
||||||
|
CORRADE_INTERNAL_ASSERT(*it); |
||||||
|
ids[it-sources.begin()] = (*it)->id(); |
||||||
|
} |
||||||
|
return ids; |
||||||
|
} |
||||||
|
|
||||||
|
const ALuint* sourceIds(const std::vector<Source*>& sources) { |
||||||
|
ALuint* const ids = new ALuint[sources.size()]; |
||||||
|
for(auto it = sources.begin(); it != sources.end(); ++it) { |
||||||
|
CORRADE_INTERNAL_ASSERT(*it); |
||||||
|
ids[it-sources.begin()] = (*it)->id(); |
||||||
|
} |
||||||
|
return ids; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** @todo Okay, this is too much code copying even for me */ |
||||||
|
|
||||||
|
void Source::play(std::initializer_list<Source*> sources) { |
||||||
|
const ALuint* const ids = sourceIds(sources); |
||||||
|
alSourcePlayv(sources.size(), ids); |
||||||
|
delete[] ids; |
||||||
|
} |
||||||
|
|
||||||
|
void Source::play(const std::vector<Source*>& sources) { |
||||||
|
const ALuint* const ids = sourceIds(sources); |
||||||
|
alSourcePlayv(sources.size(), ids); |
||||||
|
delete[] ids; |
||||||
|
} |
||||||
|
|
||||||
|
void Source::pause(std::initializer_list<Source*> sources) { |
||||||
|
const ALuint* const ids = sourceIds(sources); |
||||||
|
alSourcePausev(sources.size(), ids); |
||||||
|
delete[] ids; |
||||||
|
} |
||||||
|
|
||||||
|
void Source::pause(const std::vector<Source*>& sources) { |
||||||
|
const ALuint* const ids = sourceIds(sources); |
||||||
|
alSourcePausev(sources.size(), ids); |
||||||
|
delete[] ids; |
||||||
|
} |
||||||
|
|
||||||
|
void Source::stop(std::initializer_list<Source*> sources) { |
||||||
|
const ALuint* const ids = sourceIds(sources); |
||||||
|
alSourceStopv(sources.size(), ids); |
||||||
|
delete[] ids; |
||||||
|
} |
||||||
|
|
||||||
|
void Source::stop(const std::vector<Source*>& sources) { |
||||||
|
const ALuint* const ids = sourceIds(sources); |
||||||
|
alSourceStopv(sources.size(), ids); |
||||||
|
delete[] ids; |
||||||
|
} |
||||||
|
|
||||||
|
void Source::rewind(std::initializer_list<Source*> sources) { |
||||||
|
const ALuint* const ids = sourceIds(sources); |
||||||
|
alSourceRewindv(sources.size(), ids); |
||||||
|
delete[] ids; |
||||||
|
} |
||||||
|
|
||||||
|
void Source::rewind(const std::vector<Source*>& sources) { |
||||||
|
const ALuint* const ids = sourceIds(sources); |
||||||
|
alSourceRewindv(sources.size(), ids); |
||||||
|
delete[] ids; |
||||||
|
} |
||||||
|
|
||||||
|
Debug operator<<(Debug debug, const Source::State value) { |
||||||
|
switch(value) { |
||||||
|
#define _c(value) case Source::State::value: return debug << "Audio::Source::State::" #value; |
||||||
|
_c(Initial) |
||||||
|
_c(Playing) |
||||||
|
_c(Paused) |
||||||
|
_c(Stopped) |
||||||
|
#undef _c |
||||||
|
} |
||||||
|
|
||||||
|
return debug << "Audio::Source::State::(invalid)"; |
||||||
|
} |
||||||
|
|
||||||
|
}} |
||||||
@ -0,0 +1,596 @@ |
|||||||
|
#ifndef Magnum_Audio_Source_h |
||||||
|
#define Magnum_Audio_Source_h |
||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
/** @file
|
||||||
|
* @brief Class Magnum::Audio::Source |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <initializer_list> |
||||||
|
#include <vector> |
||||||
|
#include <al.h> |
||||||
|
|
||||||
|
#include "Math/Vector3.h" |
||||||
|
#include "Magnum.h" |
||||||
|
#include "Audio/Audio.h" |
||||||
|
#include "Audio/magnumAudioVisibility.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace Audio { |
||||||
|
|
||||||
|
/**
|
||||||
|
@brief %Source |
||||||
|
|
||||||
|
Manages positional audio source. |
||||||
|
@todo Expose convenient API for buffer queuing |
||||||
|
*/ |
||||||
|
class MAGNUM_AUDIO_EXPORT Source { |
||||||
|
public: |
||||||
|
/**
|
||||||
|
* @brief Constructor |
||||||
|
* |
||||||
|
* Creates OpenAL source object. |
||||||
|
* @see @fn_al{GenSources} |
||||||
|
*/ |
||||||
|
explicit Source() { alGenSources(1, &_id); } |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destructor |
||||||
|
* |
||||||
|
* Deletes OpenAL source object. |
||||||
|
* @see @fn_al{DeleteSources} |
||||||
|
*/ |
||||||
|
~Source() { if(_id) alDeleteSources(1, &_id); } |
||||||
|
|
||||||
|
/** @brief Copying is not allowed */ |
||||||
|
Source(const Source&) = delete; |
||||||
|
|
||||||
|
/** @brief Move constructor */ |
||||||
|
Source(Source&& other); |
||||||
|
|
||||||
|
/** @brief Copying is not allowed */ |
||||||
|
Source& operator=(const Source&) = delete; |
||||||
|
|
||||||
|
/** @brief Move assignment */ |
||||||
|
Source& operator=(Source&& other); |
||||||
|
|
||||||
|
/** @brief OpenAL source ID */ |
||||||
|
ALuint id() const { return _id; } |
||||||
|
|
||||||
|
/** @{ @name Source positioning */ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set position |
||||||
|
* @return Reference to self (for method chaining) |
||||||
|
* |
||||||
|
* Default is `{0.0f, 0.0f, 0.0f}`. |
||||||
|
* @see @ref setRelative(), @fn_al{Sourcefv} with @def_al{POSITION} |
||||||
|
*/ |
||||||
|
Source& setPosition(const Vector3& position) { |
||||||
|
alSourcefv(_id, AL_POSITION, position.data()); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/** @overload
|
||||||
|
* @see @fn_al{Sourceiv} with @def_al{POSITION} |
||||||
|
*/ |
||||||
|
Source& setPosition(const Vector3i& position) { |
||||||
|
alSourceiv(_id, AL_POSITION, position.data()); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set velocity |
||||||
|
* @return Reference to self (for method chaining) |
||||||
|
* |
||||||
|
* Default is `{0.0f, 0.0f, 0.0f}`. |
||||||
|
* @see @ref setRelative(), @fn_al{Sourcefv} with @def_al{VELOCITY} |
||||||
|
*/ |
||||||
|
Source& setVelocity(const Vector3& velocity) { |
||||||
|
alSourcefv(_id, AL_VELOCITY, velocity.data()); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/** @overload
|
||||||
|
* @see @fn_al{Sourceiv} with @def_al{VELOCITY} |
||||||
|
*/ |
||||||
|
Source& setVelocity(const Vector3i& velocity) { |
||||||
|
alSourceiv(_id, AL_VELOCITY, velocity.data()); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Interpret source relatively to listener |
||||||
|
* |
||||||
|
* When enabled, source position, direction and velocity will be |
||||||
|
* interpreted relatively to listener. Default is `false`. |
||||||
|
* @see @ref setPosition(), @ref setDirection(), @ref setVelocity(), |
||||||
|
* @fn_al{Sourcei} with @def_al{SOURCE_RELATIVE} |
||||||
|
*/ |
||||||
|
Source& setRelative(bool relative) { |
||||||
|
alSourcei(_id, AL_SOURCE_RELATIVE, relative); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/*@}*/ |
||||||
|
|
||||||
|
/** @{ @name Source behavior */ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set gain |
||||||
|
* @return Reference to self (for method chaining) |
||||||
|
* |
||||||
|
* Default is `1.0f`, which means that the sound is unattenuated. |
||||||
|
* If set to `0.0f`, the source is muted. |
||||||
|
* @see @ref setMinGain(), @ref setMaxGain(), @fn_al{Sourcef} with |
||||||
|
* @def_al{GAIN} |
||||||
|
*/ |
||||||
|
Source& setGain(Float gain) { |
||||||
|
alSourcef(_id, AL_GAIN, gain); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set min gain |
||||||
|
* @return Reference to self (for method chaining) |
||||||
|
* |
||||||
|
* If effective gain is lower than min gain, min gain is used. Note |
||||||
|
* that this is done before listener gain is applied. Default is |
||||||
|
* `0.0f`. |
||||||
|
* @see @ref setMinGain(), @ref setGain(), @fn_al{Sourcef} with |
||||||
|
* @def_al{MIN_GAIN} |
||||||
|
*/ |
||||||
|
Source& setMinGain(Float gain) { |
||||||
|
alSourcef(_id, AL_MIN_GAIN, gain); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set max gain |
||||||
|
* @return Reference to self (for method chaining) |
||||||
|
* |
||||||
|
* If effective gain is higher than max gain, max gain is used. Note |
||||||
|
* that this is done before listener gain is applied. Default is |
||||||
|
* `1.0f`. If set to `0.0f`, the source is muted. |
||||||
|
* @see @ref setMinGain(), @ref setGain(), @fn_al{Sourcef} with |
||||||
|
* @def_al{MIN_GAIN} |
||||||
|
*/ |
||||||
|
Source& setMaxGain(Float gain) { |
||||||
|
alSourcef(_id, AL_MAX_GAIN, gain); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set reference distance |
||||||
|
* @return Reference to self (for method chaining) |
||||||
|
* |
||||||
|
* Default is `1.0f`. |
||||||
|
* @see @ref setRolloffFactor(), @fn_al{Sourcef} with |
||||||
|
* @def_al{REFERENCE_DISTANCE} |
||||||
|
*/ |
||||||
|
Source& setReferenceDistance(Float distance) { |
||||||
|
alSourcef(_id, AL_REFERENCE_DISTANCE, distance); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/** @overload
|
||||||
|
* @see @fn_al{Sourcei} with @def_al{REFERENCE_DISTANCE} |
||||||
|
*/ |
||||||
|
Source& setReferenceDistance(Int distance) { |
||||||
|
alSourcei(_id, AL_REFERENCE_DISTANCE, distance); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set rolloff factor |
||||||
|
* @return Reference to self (for method chaining) |
||||||
|
* |
||||||
|
* Default is `1.0f`. |
||||||
|
* @see @ref setReferenceDistance(), @fn_al{Sourcef} with |
||||||
|
* @def_al{ROLLOFF_FACTOR} |
||||||
|
*/ |
||||||
|
Source& setRolloffFactor(Float factor) { |
||||||
|
alSourcef(_id, AL_ROLLOFF_FACTOR, factor); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/** @overload
|
||||||
|
* @see @fn_al{Sourcei} with @def_al{ROLLOFF_FACTOR} |
||||||
|
*/ |
||||||
|
Source& setRolloffFactor(Int factor) { |
||||||
|
alSourcei(_id, AL_ROLLOFF_FACTOR, factor); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set max distance |
||||||
|
* @return Reference to self (for method chaining) |
||||||
|
* |
||||||
|
* Default is max representable value. |
||||||
|
* @see @fn_al{Sourcef} with @def_al{MAX_DISTANCE} |
||||||
|
*/ |
||||||
|
Source& setMaxDistance(Float distance) { |
||||||
|
alSourcef(_id, AL_MAX_DISTANCE, distance); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/** @overload
|
||||||
|
* @see @fn_al{Sourcei} with @def_al{MAX_DISTANCE} |
||||||
|
*/ |
||||||
|
Source& setMaxDistance(Int distance) { |
||||||
|
alSourcef(_id, AL_MAX_DISTANCE, distance); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set direction |
||||||
|
* @return Reference to self (for method chaining) |
||||||
|
* |
||||||
|
* Default is `{0.0f, 0.0f, 0.0f}`, which means that the source is not |
||||||
|
* directional. |
||||||
|
* @see @ref setInnerConeAngle(), @ref setOuterConeAngle(), |
||||||
|
* @ref setRelative(), @fn_al{Sourcefv} with @def_al{DIRECTION} |
||||||
|
*/ |
||||||
|
Source& setDirection(const Vector3& direction) { |
||||||
|
alSourcefv(_id, AL_DIRECTION, direction.data()); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/** @overload
|
||||||
|
* @see @fn_al{Sourceiv} with @def_al{DIRECTION} |
||||||
|
*/ |
||||||
|
Source& setDirection(const Vector3i& direction) { |
||||||
|
alSourceiv(_id, AL_DIRECTION, direction.data()); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set inner cone angle |
||||||
|
* @return Reference to self (for method chaining) |
||||||
|
* |
||||||
|
* Has effect only if the source is directional. Default is |
||||||
|
* `360.0_degf`. |
||||||
|
* @see @ref setOuterConeAngle(), @ref setDirection(), @fn_al{Sourcef} |
||||||
|
* with @def_al{CONE_INNER_ANGLE} |
||||||
|
*/ |
||||||
|
Source& setInnerConeAngle(Deg angle) { |
||||||
|
alSourcef(_id, AL_CONE_INNER_ANGLE, Float(angle)); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set outer cone angle |
||||||
|
* @return Reference to self (for method chaining) |
||||||
|
* |
||||||
|
* Has effect only if the source is directional. Default is |
||||||
|
* `360.0_degf`. |
||||||
|
* @see @ref setInnerConeAngle(), @ref setDirection(), |
||||||
|
* @ref setOuterConeGain() @fn_al{Sourcef} with |
||||||
|
* @def_al{CONE_OUTER_ANGLE} |
||||||
|
*/ |
||||||
|
Source& setOuterConeAngle(Deg angle) { |
||||||
|
alSourcef(_id, AL_CONE_OUTER_ANGLE, Float(angle)); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set outer cone gain multiplier |
||||||
|
* @return Reference to self (for method chaining) |
||||||
|
* |
||||||
|
* The factor with which the gain is multiplied outside the outer cone. |
||||||
|
* Default is `0.0f`. |
||||||
|
* @see @ref setGain(), @ref setOuterConeAngle(), @fn_al{Sourcef} with |
||||||
|
* @def_al{CONE_OUTER_GAIN} |
||||||
|
*/ |
||||||
|
Source& setOuterConeGain(Float multiplier) { |
||||||
|
alSourcef(_id, AL_CONE_OUTER_ANGLE, multiplier); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set pitch |
||||||
|
* @return Reference to self (for method chaining) |
||||||
|
* |
||||||
|
* Default is `1.0f`. |
||||||
|
* @see @fn_al{Sourcef} with @def_al{PITCH} |
||||||
|
*/ |
||||||
|
Source& setPitch(Float pitch) { |
||||||
|
alSourcef(_id, AL_PITCH, pitch); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/*@}*/ |
||||||
|
|
||||||
|
/** @{ @name Buffer management */ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief %Source type |
||||||
|
* |
||||||
|
* @see @ref type() |
||||||
|
*/ |
||||||
|
enum class Type: ALint { |
||||||
|
Undetermined = AL_UNDETERMINED, /**< Undetermined (default) */ |
||||||
|
Static = AL_STATIC, /**< Static source */ |
||||||
|
Streaming = AL_STREAMING /**< Streaming source */ |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Source type |
||||||
|
* |
||||||
|
* @see @ref setBuffer(), @fn_al{GetSourcei} with @def_al{SOURCE_TYPE} |
||||||
|
*/ |
||||||
|
Type type() const; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Attach buffer |
||||||
|
* @param buffer Buffer to attach or `nullptr` |
||||||
|
* @return Reference to self (for method chaining) |
||||||
|
* |
||||||
|
* If an buffer is attached, changes source type to |
||||||
|
* @ref Type "Type::Static", if detached, changes source type to |
||||||
|
* @ref Type "Type::Undetermined". The buffer must be already filled |
||||||
|
* with data. |
||||||
|
* @see @ref type(), @fn_al{Sourcei} with @def_al{BUFFER} |
||||||
|
*/ |
||||||
|
Source& setBuffer(Buffer* buffer); |
||||||
|
|
||||||
|
/*@}*/ |
||||||
|
|
||||||
|
/** @{ @name State management */ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief %Source state |
||||||
|
* |
||||||
|
* @see @ref state(), @ref play(), @ref pause(), @ref stop(), |
||||||
|
* @ref rewind() |
||||||
|
*/ |
||||||
|
enum class State: ALint { |
||||||
|
Initial = AL_INITIAL, /**< Initial state (default) */ |
||||||
|
Playing = AL_PLAYING, /**< The source is playing */ |
||||||
|
Paused = AL_PAUSED, /**< The source is paused */ |
||||||
|
Stopped = AL_STOPPED /**< The source is stopped */ |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Play more sources at once |
||||||
|
* |
||||||
|
* The operation is guaranteed to be done for all sources at the same |
||||||
|
* time. `nullptr` is not allowed. |
||||||
|
* @see @ref play(), @ref pause(std::initializer_list<Source*>), |
||||||
|
* @ref stop(std::initializer_list<Source*>), |
||||||
|
* @ref rewind(std::initializer_list<Source*>), |
||||||
|
* @fn_al{SourcePlayv} |
||||||
|
*/ |
||||||
|
static void play(std::initializer_list<Source*> sources); |
||||||
|
static void play(const std::vector<Source*>& sources); /**< @overload */ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pause more sources at once |
||||||
|
* |
||||||
|
* The operation is guaranteed to be done for all sources at the same |
||||||
|
* time. `nullptr` is not allowed. |
||||||
|
* @see @ref pause(), @ref play(std::initializer_list<Source*>), |
||||||
|
* @ref stop(std::initializer_list<Source*>), |
||||||
|
* @ref rewind(std::initializer_list<Source*>), |
||||||
|
* @fn_al{SourcePausev} |
||||||
|
*/ |
||||||
|
static void pause(std::initializer_list<Source*> sources); |
||||||
|
static void pause(const std::vector<Source*>& sources); /**< @overload */ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stop more sources at once |
||||||
|
* |
||||||
|
* The operation is guaranteed to be done for all sources at the same |
||||||
|
* time. `nullptr` is not allowed. |
||||||
|
* @see @ref stop(), @ref play(std::initializer_list<Source*>), |
||||||
|
* @ref pause(std::initializer_list<Source*>), |
||||||
|
* @ref rewind(std::initializer_list<Source*>), |
||||||
|
* @fn_al{SourceStopv} |
||||||
|
*/ |
||||||
|
static void stop(std::initializer_list<Source*> sources); |
||||||
|
static void stop(const std::vector<Source*>& sources); /**< @overload */ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Rewind more sources at once |
||||||
|
* |
||||||
|
* The operation is guaranteed to be done for all sources at the same |
||||||
|
* time. `nullptr` is not allowed. |
||||||
|
* @see @ref rewind(), @ref play(std::initializer_list<Source*>), |
||||||
|
* @ref pause(std::initializer_list<Source*>), |
||||||
|
* @ref stop(std::initializer_list<Source*>), |
||||||
|
* @fn_al{SourceRewindv} |
||||||
|
*/ |
||||||
|
static void rewind(std::initializer_list<Source*> sources); |
||||||
|
static void rewind(const std::vector<Source*>& sources); /**< @overload */ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief State |
||||||
|
* |
||||||
|
* @see @ref play(), @ref pause(), @ref stop(), @ref rewind(), |
||||||
|
* @fn_al{GetSourcei} with @def_al{SOURCE_STATE} |
||||||
|
*/ |
||||||
|
State state() const; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Play |
||||||
|
* |
||||||
|
* @see @ref play(std::initializer_list<Source*>), @ref state(), |
||||||
|
* @ref pause(), @ref stop(), @ref rewind(), @fn_al{SourcePlay} |
||||||
|
*/ |
||||||
|
void play() { alSourcePlay(_id); } |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pause |
||||||
|
* |
||||||
|
* @see @ref pause(std::initializer_list<Source*>), @ref state(), |
||||||
|
* @ref play(), @ref stop(), @ref rewind(), @fn_al{SourcePause} |
||||||
|
*/ |
||||||
|
void pause() { alSourcePause(_id); } |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stop |
||||||
|
* |
||||||
|
* @see @ref stop(std::initializer_list<Source*>), @ref state(), |
||||||
|
* @ref play(), @ref pause(), @ref rewind(), @fn_al{SourceStop} |
||||||
|
*/ |
||||||
|
void stop() { alSourceStop(_id); } |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Rewind |
||||||
|
* |
||||||
|
* @see @ref rewind(std::initializer_list<Source*>), @ref state(), |
||||||
|
* @ref play(), @ref pause(), @ref stop(), @fn_al{SourceRewind} |
||||||
|
*/ |
||||||
|
void rewind() { alSourceRewind(_id); } |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Whether the source is looping |
||||||
|
* |
||||||
|
* @see @fn_al{GetSourcei} with @def_al{LOOPING} |
||||||
|
*/ |
||||||
|
bool isLooping() const; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set source looping |
||||||
|
* @return Reference to self (for method chaining) |
||||||
|
* |
||||||
|
* Default is `false`. |
||||||
|
* @see @fn_al{Sourcei} with @def_al{LOOPING} |
||||||
|
*/ |
||||||
|
Source& setLooping(bool loop) { |
||||||
|
alSourcei(_id, AL_LOOPING, loop); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Offset in seconds |
||||||
|
* |
||||||
|
* @see @ref offsetInBytes(), @ref offsetInSamples(), |
||||||
|
* @fn_al{GetSourcef} with @def_al{SEC_OFFSET} |
||||||
|
*/ |
||||||
|
Float offsetInSeconds() const; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set offset in seconds |
||||||
|
* @return Reference to self (for method chaining) |
||||||
|
* |
||||||
|
* @see @ref setOffsetInBytes(), @ref setOffsetInSamples(), |
||||||
|
* @fn_al{Sourcef} with @def_al{SEC_OFFSET} |
||||||
|
*/ |
||||||
|
Source& setOffsetInSeconds(Float offset) { |
||||||
|
alSourcef(_id, AL_SEC_OFFSET, offset); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Offset in bytes |
||||||
|
* |
||||||
|
* @see @ref offsetInSeconds(), @ref offsetInSamples(), |
||||||
|
* @fn_al{GetSourcei} with @def_al{BYTE_OFFSET} |
||||||
|
*/ |
||||||
|
Int offsetInBytes() const; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set offset in bytes |
||||||
|
* @return Reference to self (for method chaining) |
||||||
|
* |
||||||
|
* @see @ref setOffsetInSeconds(), @ref setOffsetInSamples(), |
||||||
|
* @fn_al{Sourcei} with @def_al{SEC_OFFSET} |
||||||
|
*/ |
||||||
|
Source& setOffsetInBytes(Int offset) { |
||||||
|
alSourcei(_id, AL_BYTE_OFFSET, offset); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Offset in samples |
||||||
|
* |
||||||
|
* @see @ref offsetInSeconds(), @ref offsetInBytes(), |
||||||
|
* @fn_al{GetSourcei} with @def_al{SAMPLE_OFFSET} |
||||||
|
*/ |
||||||
|
Int offsetInSamples() const; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set offset in samples |
||||||
|
* @return Reference to self (for method chaining) |
||||||
|
* |
||||||
|
* @see @ref setOffsetInSeconds(), @ref setOffsetInBytes(), |
||||||
|
* @fn_al{Sourcei} with @def_al{SEC_OFFSET} |
||||||
|
*/ |
||||||
|
Source& setOffsetInSamples(Int offset) { |
||||||
|
alSourcei(_id, AL_SAMPLE_OFFSET, offset); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/*@}*/ |
||||||
|
|
||||||
|
private: |
||||||
|
ALuint _id; |
||||||
|
}; |
||||||
|
|
||||||
|
/** @debugoperator{Magnum::Audio::Source} */ |
||||||
|
Debug MAGNUM_AUDIO_EXPORT operator<<(Debug debug, Source::State value); |
||||||
|
|
||||||
|
inline Source::Source(Source&& other): _id(other._id) { |
||||||
|
other._id = 0; |
||||||
|
} |
||||||
|
|
||||||
|
inline Source& Source::operator=(Source&& other) { |
||||||
|
std::swap(_id, other._id); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
auto Source::state() const -> State { |
||||||
|
ALint state; |
||||||
|
alGetSourcei(_id, AL_SOURCE_STATE, &state); |
||||||
|
return State(state); |
||||||
|
} |
||||||
|
|
||||||
|
inline bool Source::isLooping() const { |
||||||
|
ALint looping; |
||||||
|
alGetSourcei(_id, AL_LOOPING, &looping); |
||||||
|
return looping; |
||||||
|
} |
||||||
|
|
||||||
|
inline Float Source::offsetInSeconds() const { |
||||||
|
Float offset; |
||||||
|
alGetSourcef(_id, AL_SEC_OFFSET, &offset); |
||||||
|
return offset; |
||||||
|
} |
||||||
|
|
||||||
|
inline Int Source::offsetInBytes() const { |
||||||
|
Int offset; |
||||||
|
alGetSourcei(_id, AL_BYTE_OFFSET, &offset); |
||||||
|
return offset; |
||||||
|
} |
||||||
|
|
||||||
|
inline Int Source::offsetInSamples() const { |
||||||
|
Int offset; |
||||||
|
alGetSourcei(_id, AL_SAMPLE_OFFSET, &offset); |
||||||
|
return offset; |
||||||
|
} |
||||||
|
|
||||||
|
}} |
||||||
|
|
||||||
|
#endif |
||||||
@ -0,0 +1,76 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <Containers/Array.h> |
||||||
|
#include <TestSuite/Tester.h> |
||||||
|
#include <Utility/Directory.h> |
||||||
|
|
||||||
|
#include "Audio/AbstractImporter.h" |
||||||
|
|
||||||
|
#include "testConfigure.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace Audio { namespace Test { |
||||||
|
|
||||||
|
class AbstractImporterTest: public TestSuite::Tester { |
||||||
|
public: |
||||||
|
explicit AbstractImporterTest(); |
||||||
|
|
||||||
|
void openFile(); |
||||||
|
}; |
||||||
|
|
||||||
|
AbstractImporterTest::AbstractImporterTest() { |
||||||
|
addTests({&AbstractImporterTest::openFile}); |
||||||
|
} |
||||||
|
|
||||||
|
void AbstractImporterTest::openFile() { |
||||||
|
class DataImporter: public Audio::AbstractImporter { |
||||||
|
public: |
||||||
|
explicit DataImporter(): opened(false) {} |
||||||
|
|
||||||
|
private: |
||||||
|
Features doFeatures() const override { return Feature::OpenData; } |
||||||
|
bool doIsOpened() const override { return opened; } |
||||||
|
void doClose() override {} |
||||||
|
|
||||||
|
void doOpenData(Containers::ArrayReference<const unsigned char> data) override { |
||||||
|
opened = (data.size() == 1 && data[0] == 0xa5); |
||||||
|
} |
||||||
|
|
||||||
|
Buffer::Format doFormat() const override { return {}; } |
||||||
|
UnsignedInt doFrequency() const override { return {}; } |
||||||
|
Corrade::Containers::Array<unsigned char> doData() override { return nullptr; } |
||||||
|
|
||||||
|
bool opened; |
||||||
|
}; |
||||||
|
|
||||||
|
/* doOpenFile() should call doOpenData() */ |
||||||
|
DataImporter importer; |
||||||
|
CORRADE_VERIFY(!importer.isOpened()); |
||||||
|
importer.openFile(Utility::Directory::join(AUDIO_TEST_DIR, "file.bin")); |
||||||
|
CORRADE_VERIFY(importer.isOpened()); |
||||||
|
} |
||||||
|
|
||||||
|
}}} |
||||||
|
|
||||||
|
CORRADE_TEST_MAIN(Magnum::Audio::Test::AbstractImporterTest) |
||||||
@ -0,0 +1,51 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <sstream> |
||||||
|
#include <TestSuite/Tester.h> |
||||||
|
|
||||||
|
#include "Audio/Buffer.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace Audio { namespace Test { |
||||||
|
|
||||||
|
class BufferTest: public TestSuite::Tester { |
||||||
|
public: |
||||||
|
explicit BufferTest(); |
||||||
|
|
||||||
|
void debugFormat(); |
||||||
|
}; |
||||||
|
|
||||||
|
BufferTest::BufferTest() { |
||||||
|
addTests({&BufferTest::debugFormat}); |
||||||
|
} |
||||||
|
|
||||||
|
void BufferTest::debugFormat() { |
||||||
|
std::ostringstream out; |
||||||
|
Debug(&out) << Buffer::Format::Stereo16; |
||||||
|
CORRADE_COMPARE(out.str(), "Audio::Buffer::Format::Stereo16\n"); |
||||||
|
} |
||||||
|
|
||||||
|
}}} |
||||||
|
|
||||||
|
CORRADE_TEST_MAIN(Magnum::Audio::Test::BufferTest) |
||||||
@ -0,0 +1,33 @@ |
|||||||
|
# |
||||||
|
# This file is part of Magnum. |
||||||
|
# |
||||||
|
# Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
# |
||||||
|
|
||||||
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/testConfigure.h.cmake |
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/testConfigure.h) |
||||||
|
|
||||||
|
include_directories(${CMAKE_CURRENT_BINARY_DIR}) |
||||||
|
|
||||||
|
corrade_add_test(AudioAbstractImporterTest AbstractImporterTest.cpp LIBRARIES MagnumAudio) |
||||||
|
corrade_add_test(AudioBufferTest BufferTest.cpp LIBRARIES MagnumAudio) |
||||||
|
corrade_add_test(AudioRendererTest RendererTest.cpp LIBRARIES MagnumAudio) |
||||||
|
corrade_add_test(AudioSourceTest SourceTest.cpp LIBRARIES MagnumAudio) |
||||||
@ -0,0 +1,51 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <sstream> |
||||||
|
#include <TestSuite/Tester.h> |
||||||
|
|
||||||
|
#include "Audio/Renderer.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace Audio { namespace Test { |
||||||
|
|
||||||
|
class RendererTest: public TestSuite::Tester { |
||||||
|
public: |
||||||
|
explicit RendererTest(); |
||||||
|
|
||||||
|
void debugError(); |
||||||
|
}; |
||||||
|
|
||||||
|
RendererTest::RendererTest() { |
||||||
|
addTests({&RendererTest::debugError}); |
||||||
|
} |
||||||
|
|
||||||
|
void RendererTest::debugError() { |
||||||
|
std::ostringstream out; |
||||||
|
Debug(&out) << Renderer::Error::InvalidOperation; |
||||||
|
CORRADE_COMPARE(out.str(), "Audio::Renderer::Error::InvalidOperation\n"); |
||||||
|
} |
||||||
|
|
||||||
|
}}} |
||||||
|
|
||||||
|
CORRADE_TEST_MAIN(Magnum::Audio::Test::RendererTest) |
||||||
@ -0,0 +1,51 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <sstream> |
||||||
|
#include <TestSuite/Tester.h> |
||||||
|
|
||||||
|
#include "Audio/Source.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace Audio { namespace Test { |
||||||
|
|
||||||
|
class SourceTest: public TestSuite::Tester { |
||||||
|
public: |
||||||
|
explicit SourceTest(); |
||||||
|
|
||||||
|
void debugState(); |
||||||
|
}; |
||||||
|
|
||||||
|
SourceTest::SourceTest() { |
||||||
|
addTests({&SourceTest::debugState}); |
||||||
|
} |
||||||
|
|
||||||
|
void SourceTest::debugState() { |
||||||
|
std::ostringstream out; |
||||||
|
Debug(&out) << Source::State::Playing; |
||||||
|
CORRADE_COMPARE(out.str(), "Audio::Source::State::Playing\n"); |
||||||
|
} |
||||||
|
|
||||||
|
}}} |
||||||
|
|
||||||
|
CORRADE_TEST_MAIN(Magnum::Audio::Test::SourceTest) |
||||||
@ -0,0 +1,25 @@ |
|||||||
|
/* |
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
#define AUDIO_TEST_DIR "${CMAKE_CURRENT_SOURCE_DIR}" |
||||||
@ -0,0 +1,35 @@ |
|||||||
|
#ifndef Magnum_Audio_magnumAudioVisibility_h |
||||||
|
#define Magnum_Audio_magnumAudioVisibility_h |
||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <Utility/Visibility.h> |
||||||
|
|
||||||
|
#ifdef MagnumAudio_EXPORTS |
||||||
|
#define MAGNUM_AUDIO_EXPORT CORRADE_VISIBILITY_EXPORT |
||||||
|
#else |
||||||
|
#define MAGNUM_AUDIO_EXPORT CORRADE_VISIBILITY_IMPORT |
||||||
|
#endif |
||||||
|
|
||||||
|
#endif |
||||||
@ -0,0 +1,116 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "CapsuleRenderer.h" |
||||||
|
|
||||||
|
#include "MeshView.h" |
||||||
|
#include "DebugTools/ResourceManager.h" |
||||||
|
#include "DebugTools/ShapeRenderer.h" |
||||||
|
#include "Primitives/Capsule.h" |
||||||
|
#include "Shapes/Capsule.h" |
||||||
|
#include "Shaders/Flat.h" |
||||||
|
#include "Trade/MeshData2D.h" |
||||||
|
#include "Trade/MeshData3D.h" |
||||||
|
|
||||||
|
#include "DebugTools/Implementation/CapsuleRendererTransformation.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace DebugTools { namespace Implementation { |
||||||
|
|
||||||
|
AbstractCapsuleRenderer<2>::AbstractCapsuleRenderer(): AbstractShapeRenderer<2>("capsule2d", "capsule2d-vertices", "capsule2d-indices") { |
||||||
|
constexpr UnsignedInt rings = 10; |
||||||
|
if(!wireframeMesh) createResources(Primitives::Capsule2D::wireframe(rings, 1, 1.0f)); |
||||||
|
|
||||||
|
/* Bottom hemisphere */ |
||||||
|
if(!(bottom = ResourceManager::instance().get<MeshView>("capsule2d-bottom"))) { |
||||||
|
auto view = new MeshView(wireframeMesh); |
||||||
|
view->setIndexRange(0, rings*4, 0, rings*2+1); |
||||||
|
ResourceManager::instance().set(bottom.key(), view, ResourceDataState::Final, ResourcePolicy::Manual); |
||||||
|
} |
||||||
|
|
||||||
|
/* Cylinder */ |
||||||
|
if(!(cylinder = ResourceManager::instance().get<MeshView>("capsule2d-cylinder"))) { |
||||||
|
auto view = new MeshView(wireframeMesh); |
||||||
|
view->setIndexRange(rings*4, 4, rings*2+1, rings*2+3); |
||||||
|
ResourceManager::instance().set(cylinder.key(), view, ResourceDataState::Final, ResourcePolicy::Manual); |
||||||
|
} |
||||||
|
|
||||||
|
/* Top hemisphere */ |
||||||
|
if(!(top = ResourceManager::instance().get<MeshView>("capsule2d-top"))) { |
||||||
|
auto view = new MeshView(wireframeMesh); |
||||||
|
view->setIndexRange(rings*4+4, rings*4, rings*2+3, rings*4+4); |
||||||
|
ResourceManager::instance().set(top.key(), view, ResourceDataState::Final, ResourcePolicy::Manual); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
AbstractCapsuleRenderer<3>::AbstractCapsuleRenderer(): AbstractShapeRenderer<3>("capsule3d", "capsule3d-vertices", "capsule3d-indices") { |
||||||
|
constexpr UnsignedInt rings = 10; |
||||||
|
constexpr UnsignedInt segments = 40; |
||||||
|
if(!wireframeMesh) createResources(Primitives::Capsule3D::wireframe(rings, 1, segments, 1.0f)); |
||||||
|
|
||||||
|
/* Bottom hemisphere */ |
||||||
|
if(!(bottom = ResourceManager::instance().get<MeshView>("capsule3d-bottom"))) { |
||||||
|
auto view = new MeshView(wireframeMesh); |
||||||
|
view->setIndexRange(0, rings*8, 0, rings*4+1); |
||||||
|
ResourceManager::instance().set(bottom.key(), view, ResourceDataState::Final, ResourcePolicy::Manual); |
||||||
|
} |
||||||
|
|
||||||
|
/* Cylinder */ |
||||||
|
if(!(cylinder = ResourceManager::instance().get<MeshView>("capsule3d-cylinder"))) { |
||||||
|
auto view = new MeshView(wireframeMesh); |
||||||
|
view->setIndexRange(rings*8, segments*4+8, rings*4+1, rings*4+segments*2+5); |
||||||
|
ResourceManager::instance().set(cylinder.key(), view, ResourceDataState::Final, ResourcePolicy::Manual); |
||||||
|
} |
||||||
|
|
||||||
|
/* Top */ |
||||||
|
if(!(top = ResourceManager::instance().get<MeshView>("capsule3d-top"))) { |
||||||
|
auto view = new MeshView(wireframeMesh); |
||||||
|
view->setIndexRange(rings*8+segments*4+8, rings*8, rings*4+segments*2+5, rings*8+segments*2+6); |
||||||
|
ResourceManager::instance().set(top.key(), view, ResourceDataState::Final, ResourcePolicy::Manual); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
template<UnsignedInt dimensions> CapsuleRenderer<dimensions>::CapsuleRenderer(const Shapes::Implementation::AbstractShape<dimensions>& capsule): capsule(static_cast<const Shapes::Implementation::Shape<Shapes::Capsule<dimensions>>&>(capsule).shape) {} |
||||||
|
|
||||||
|
template<UnsignedInt dimensions> void CapsuleRenderer<dimensions>::draw(Resource<ShapeRendererOptions>& options, const typename DimensionTraits<dimensions, Float>::MatrixType& projectionMatrix) { |
||||||
|
std::array<typename DimensionTraits<dimensions, Float>::MatrixType, 3> transformations = Implementation::capsuleRendererTransformation<dimensions>(capsule.a(), capsule.b(), capsule.radius()); |
||||||
|
AbstractShapeRenderer<dimensions>::wireframeShader->setColor(options->color()) |
||||||
|
.use(); |
||||||
|
|
||||||
|
/* Bottom */ |
||||||
|
AbstractShapeRenderer<dimensions>::wireframeShader->setTransformationProjectionMatrix(projectionMatrix*transformations[0]); |
||||||
|
AbstractCapsuleRenderer<dimensions>::bottom->draw(); |
||||||
|
|
||||||
|
/* Cylinder */ |
||||||
|
AbstractShapeRenderer<dimensions>::wireframeShader->setTransformationProjectionMatrix(projectionMatrix*transformations[1]); |
||||||
|
AbstractCapsuleRenderer<dimensions>::cylinder->draw(); |
||||||
|
|
||||||
|
/* Top */ |
||||||
|
AbstractShapeRenderer<dimensions>::wireframeShader->setTransformationProjectionMatrix(projectionMatrix*transformations[2]); |
||||||
|
AbstractCapsuleRenderer<dimensions>::top->draw(); |
||||||
|
} |
||||||
|
|
||||||
|
template class CapsuleRenderer<2>; |
||||||
|
template class CapsuleRenderer<3>; |
||||||
|
|
||||||
|
}}} |
||||||
@ -0,0 +1,66 @@ |
|||||||
|
#ifndef Magnum_DebugTools_Implementation_CapsuleRenderer_h |
||||||
|
#define Magnum_DebugTools_Implementation_CapsuleRenderer_h |
||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "AbstractShapeRenderer.h" |
||||||
|
|
||||||
|
#include "Shapes/Shapes.h" |
||||||
|
|
||||||
|
#include "corradeCompatibility.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace DebugTools { namespace Implementation { |
||||||
|
|
||||||
|
template<UnsignedInt dimensions> class AbstractCapsuleRenderer; |
||||||
|
|
||||||
|
template<> class AbstractCapsuleRenderer<2>: public AbstractShapeRenderer<2> { |
||||||
|
public: |
||||||
|
explicit AbstractCapsuleRenderer(); |
||||||
|
|
||||||
|
protected: |
||||||
|
Resource<MeshView> bottom, cylinder, top; |
||||||
|
}; |
||||||
|
|
||||||
|
template<> class AbstractCapsuleRenderer<3>: public AbstractShapeRenderer<3> { |
||||||
|
public: |
||||||
|
explicit AbstractCapsuleRenderer(); |
||||||
|
|
||||||
|
protected: |
||||||
|
Resource<MeshView> bottom, cylinder, top; |
||||||
|
}; |
||||||
|
|
||||||
|
template<UnsignedInt dimensions> class CapsuleRenderer: public AbstractCapsuleRenderer<dimensions> { |
||||||
|
public: |
||||||
|
explicit CapsuleRenderer(const Shapes::Implementation::AbstractShape<dimensions>& capsule); |
||||||
|
CapsuleRenderer(const Shapes::Implementation::AbstractShape<dimensions>&&) = delete; |
||||||
|
|
||||||
|
void draw(Resource<ShapeRendererOptions>& options, const typename DimensionTraits<dimensions, Float>::MatrixType& projectionMatrix) override; |
||||||
|
|
||||||
|
private: |
||||||
|
const Shapes::Capsule<dimensions>& capsule; |
||||||
|
}; |
||||||
|
|
||||||
|
}}} |
||||||
|
|
||||||
|
#endif |
||||||
@ -0,0 +1,106 @@ |
|||||||
|
#ifndef Magnum_DebugTools_Implementation_ForceRendererTransformation_h |
||||||
|
#define Magnum_DebugTools_Implementation_ForceRendererTransformation_h |
||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <array> |
||||||
|
|
||||||
|
#include "Math/Functions.h" |
||||||
|
#include "Math/Matrix3.h" |
||||||
|
#include "Math/Matrix4.h" |
||||||
|
#include "Magnum.h" |
||||||
|
#include "DimensionTraits.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace DebugTools { namespace Implementation { |
||||||
|
|
||||||
|
template<UnsignedInt dimensions> std::array<typename DimensionTraits<dimensions, Float>::MatrixType, 3> capsuleRendererTransformation(const typename DimensionTraits<dimensions, Float>::VectorType& a, const typename DimensionTraits<dimensions, Float>::VectorType& b, Float radius); |
||||||
|
|
||||||
|
template<> std::array<Matrix3, 3> capsuleRendererTransformation<2>(const Vector2& a, const Vector2& b, const Float radius) { |
||||||
|
/* Vector from capsule center to top hemisphere center */ |
||||||
|
const Vector2 direction = 0.5f*(b - a); |
||||||
|
const Float length = direction.length(); |
||||||
|
|
||||||
|
/* Capsule rotation and distance to caps after they are scaled to proper
|
||||||
|
radius (if nonzero cylinder length) */ |
||||||
|
Matrix3 rotation; |
||||||
|
Vector2 capDistance; |
||||||
|
if(length >= Math::TypeTraits<Float>::epsilon()) { |
||||||
|
rotation.up() = direction/length; |
||||||
|
rotation.right() = rotation.up().perpendicular(); |
||||||
|
CORRADE_INTERNAL_ASSERT(rotation.right().isNormalized()); |
||||||
|
|
||||||
|
capDistance = direction*(radius/length); |
||||||
|
} |
||||||
|
|
||||||
|
/* Scaling and translation of all parts */ |
||||||
|
const auto rotationScaling = rotation*Matrix3::scaling(Vector2(radius)); |
||||||
|
return {{ |
||||||
|
Matrix3::translation(a+capDistance)*rotationScaling, |
||||||
|
Matrix3::translation(0.5f*(a + b))*rotation*Matrix3::scaling({radius, length}), |
||||||
|
Matrix3::translation(b-capDistance)*rotationScaling |
||||||
|
}}; |
||||||
|
} |
||||||
|
|
||||||
|
template<> std::array<Matrix4, 3> capsuleRendererTransformation<3>(const Vector3& a, const Vector3& b, const Float radius) { |
||||||
|
/* Vector from capsule center to top hemisphere center */ |
||||||
|
const Vector3 direction = 0.5f*(b - a); |
||||||
|
const Float length = direction.length(); |
||||||
|
|
||||||
|
/* Capsule rotation and distance to caps after they are scaled to proper
|
||||||
|
radius (if nonzero cylinder length) */ |
||||||
|
Matrix4 rotation; |
||||||
|
Vector3 capDistance; |
||||||
|
if(length >= Math::TypeTraits<Float>::epsilon()) { |
||||||
|
const Vector3 directionNormalized = direction/length; |
||||||
|
const Float dot = Vector3::dot(directionNormalized, Vector3::zAxis()); |
||||||
|
|
||||||
|
/* Direction is parallel to Z axis, special rotation case */ |
||||||
|
if(Math::abs(dot) > 1.0f - Math::TypeTraits<Float>::epsilon()) { |
||||||
|
rotation.up() = dot*Vector3::zAxis(); |
||||||
|
rotation.right() = Vector3::xAxis(); |
||||||
|
rotation.backward() = -dot*Vector3::yAxis(); |
||||||
|
|
||||||
|
/* Common case */ |
||||||
|
} else { |
||||||
|
rotation.up() = directionNormalized; |
||||||
|
rotation.right() = Vector3::cross(rotation.up(), Vector3::zAxis()).normalized(); |
||||||
|
rotation.backward() = Vector3::cross(rotation.right(), rotation.up()); |
||||||
|
CORRADE_INTERNAL_ASSERT(rotation.up().isNormalized() && rotation.backward().isNormalized()); |
||||||
|
} |
||||||
|
|
||||||
|
capDistance = directionNormalized*radius; |
||||||
|
} |
||||||
|
|
||||||
|
/* Scaling and translation of all parts */ |
||||||
|
const auto rotationScaling = rotation*Matrix4::scaling(Vector3(radius)); |
||||||
|
return {{ |
||||||
|
Matrix4::translation(a+capDistance)*rotationScaling, |
||||||
|
Matrix4::translation(0.5f*(a + b))*rotation*Matrix4::scaling({radius, length, radius}), |
||||||
|
Matrix4::translation(b-capDistance)*rotationScaling |
||||||
|
}}; |
||||||
|
} |
||||||
|
|
||||||
|
}}} |
||||||
|
|
||||||
|
#endif |
||||||
@ -0,0 +1,61 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "CylinderRenderer.h" |
||||||
|
|
||||||
|
#include "Mesh.h" |
||||||
|
#include "DebugTools/ShapeRenderer.h" |
||||||
|
#include "Shapes/Cylinder.h" |
||||||
|
#include "Primitives/Cylinder.h" |
||||||
|
#include "Primitives/Square.h" |
||||||
|
#include "Shaders/Flat.h" |
||||||
|
#include "Trade/MeshData2D.h" |
||||||
|
#include "Trade/MeshData3D.h" |
||||||
|
|
||||||
|
#include "DebugTools/Implementation/CylinderRendererTransformation.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace DebugTools { namespace Implementation { |
||||||
|
|
||||||
|
AbstractCylinderRenderer<2>::AbstractCylinderRenderer(): AbstractShapeRenderer<2>("cylinder2d", "cylinder2d-vertices", {}) { |
||||||
|
if(!wireframeMesh) createResources(Primitives::Square::wireframe()); |
||||||
|
} |
||||||
|
|
||||||
|
AbstractCylinderRenderer<3>::AbstractCylinderRenderer(): AbstractShapeRenderer<3>("cylinder3d", "cylinder3d-vertices", "cylinder3d-indices") { |
||||||
|
if(!wireframeMesh) createResources(Primitives::Cylinder::wireframe(1, 40, 1.0f)); |
||||||
|
} |
||||||
|
|
||||||
|
template<UnsignedInt dimensions> CylinderRenderer<dimensions>::CylinderRenderer(const Shapes::Implementation::AbstractShape<dimensions>& cylinder): cylinder(static_cast<const Shapes::Implementation::Shape<Shapes::Cylinder<dimensions>>&>(cylinder).shape) {} |
||||||
|
|
||||||
|
template<UnsignedInt dimensions> void CylinderRenderer<dimensions>::draw(Resource<ShapeRendererOptions>& options, const typename DimensionTraits<dimensions, Float>::MatrixType& projectionMatrix) { |
||||||
|
AbstractShapeRenderer<dimensions>::wireframeShader->setTransformationProjectionMatrix(projectionMatrix* |
||||||
|
Implementation::cylinderRendererTransformation<dimensions>(cylinder.a(), cylinder.b(), cylinder.radius())) |
||||||
|
.setColor(options->color()) |
||||||
|
.use(); |
||||||
|
AbstractShapeRenderer<dimensions>::wireframeMesh->draw(); |
||||||
|
} |
||||||
|
|
||||||
|
template class CylinderRenderer<2>; |
||||||
|
template class CylinderRenderer<3>; |
||||||
|
|
||||||
|
}}} |
||||||
@ -0,0 +1,60 @@ |
|||||||
|
#ifndef Magnum_DebugTools_Implementation_CylinderRenderer_h |
||||||
|
#define Magnum_DebugTools_Implementation_CylinderRenderer_h |
||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "AbstractShapeRenderer.h" |
||||||
|
|
||||||
|
#include "Shapes/Shapes.h" |
||||||
|
|
||||||
|
#include "corradeCompatibility.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace DebugTools { namespace Implementation { |
||||||
|
|
||||||
|
template<UnsignedInt dimensions> class AbstractCylinderRenderer; |
||||||
|
|
||||||
|
template<> class AbstractCylinderRenderer<2>: public AbstractShapeRenderer<2> { |
||||||
|
public: |
||||||
|
explicit AbstractCylinderRenderer(); |
||||||
|
}; |
||||||
|
|
||||||
|
template<> class AbstractCylinderRenderer<3>: public AbstractShapeRenderer<3> { |
||||||
|
public: |
||||||
|
explicit AbstractCylinderRenderer(); |
||||||
|
}; |
||||||
|
|
||||||
|
template<UnsignedInt dimensions> class CylinderRenderer: public AbstractCylinderRenderer<dimensions> { |
||||||
|
public: |
||||||
|
explicit CylinderRenderer(const Shapes::Implementation::AbstractShape<dimensions>& cylinder); |
||||||
|
CylinderRenderer(const Shapes::Implementation::AbstractShape<dimensions>&&) = delete; |
||||||
|
|
||||||
|
void draw(Resource<ShapeRendererOptions>& options, const typename DimensionTraits<dimensions, Float>::MatrixType& projectionMatrix) override; |
||||||
|
|
||||||
|
private: |
||||||
|
const Shapes::Cylinder<dimensions>& cylinder; |
||||||
|
}; |
||||||
|
|
||||||
|
}}} |
||||||
|
|
||||||
|
#endif |
||||||
@ -0,0 +1,88 @@ |
|||||||
|
#ifndef Magnum_DebugTools_Implementation_ForceRendererTransformation_h |
||||||
|
#define Magnum_DebugTools_Implementation_ForceRendererTransformation_h |
||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "Math/Functions.h" |
||||||
|
#include "Math/Matrix3.h" |
||||||
|
#include "Math/Matrix4.h" |
||||||
|
#include "Magnum.h" |
||||||
|
#include "DimensionTraits.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace DebugTools { namespace Implementation { |
||||||
|
|
||||||
|
template<UnsignedInt dimensions> typename DimensionTraits<dimensions, Float>::MatrixType cylinderRendererTransformation(const typename DimensionTraits<dimensions, Float>::VectorType& a, const typename DimensionTraits<dimensions, Float>::VectorType& b, Float radius); |
||||||
|
|
||||||
|
template<> Matrix3 cylinderRendererTransformation<2>(const Vector2& a, const Vector2& b, const Float radius) { |
||||||
|
/* Vector from cylinder center to top hemisphere center */ |
||||||
|
const Vector2 direction = 0.5f*(b - a); |
||||||
|
const Float length = direction.length(); |
||||||
|
|
||||||
|
/* Capsule rotation and distance to caps after they are scaled to proper
|
||||||
|
radius (if nonzero cylinder length) */ |
||||||
|
Matrix3 rotation; |
||||||
|
if(length >= Math::TypeTraits<Float>::epsilon()) { |
||||||
|
rotation.up() = direction/length; |
||||||
|
rotation.right() = rotation.up().perpendicular(); |
||||||
|
CORRADE_INTERNAL_ASSERT(rotation.right().isNormalized()); |
||||||
|
} |
||||||
|
|
||||||
|
/* Scaling and translation */ |
||||||
|
return Matrix3::translation(0.5f*(a + b))*rotation*Matrix3::scaling({radius, length}); |
||||||
|
} |
||||||
|
|
||||||
|
template<> Matrix4 cylinderRendererTransformation<3>(const Vector3& a, const Vector3& b, const Float radius) { |
||||||
|
/* Vector from cylinder center to top hemisphere center */ |
||||||
|
const Vector3 direction = 0.5f*(b - a); |
||||||
|
const Float length = direction.length(); |
||||||
|
|
||||||
|
/* Capsule rotation and distance to caps after they are scaled to proper
|
||||||
|
radius (if nonzero cylinder length) */ |
||||||
|
Matrix4 rotation; |
||||||
|
if(length >= Math::TypeTraits<Float>::epsilon()) { |
||||||
|
const Vector3 directionNormalized = direction/length; |
||||||
|
const Float dot = Vector3::dot(directionNormalized, Vector3::zAxis()); |
||||||
|
|
||||||
|
/* Direction is parallel to Z axis, special rotation case */ |
||||||
|
if(Math::abs(dot) > 1.0f - Math::TypeTraits<Float>::epsilon()) { |
||||||
|
rotation.up() = dot*Vector3::zAxis(); |
||||||
|
rotation.right() = Vector3::xAxis(); |
||||||
|
rotation.backward() = -dot*Vector3::yAxis(); |
||||||
|
|
||||||
|
/* Common case */ |
||||||
|
} else { |
||||||
|
rotation.up() = directionNormalized; |
||||||
|
rotation.right() = Vector3::cross(rotation.up(), Vector3::zAxis()).normalized(); |
||||||
|
rotation.backward() = Vector3::cross(rotation.right(), rotation.up()); |
||||||
|
CORRADE_INTERNAL_ASSERT(rotation.up().isNormalized() && rotation.backward().isNormalized()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/* Scaling and translation */ |
||||||
|
return Matrix4::translation(0.5f*(a + b))*rotation*Matrix4::scaling({radius, length, radius}); |
||||||
|
} |
||||||
|
|
||||||
|
}}} |
||||||
|
|
||||||
|
#endif |
||||||
@ -0,0 +1,177 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <TestSuite/Tester.h> |
||||||
|
|
||||||
|
#include "DebugTools/Implementation/CapsuleRendererTransformation.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace DebugTools { namespace Test { |
||||||
|
|
||||||
|
class CapsuleRendererTest: public TestSuite::Tester { |
||||||
|
public: |
||||||
|
explicit CapsuleRendererTest(); |
||||||
|
|
||||||
|
void zeroLength2D(); |
||||||
|
void common2D(); |
||||||
|
|
||||||
|
void zeroLength3D(); |
||||||
|
void parallel3D(); |
||||||
|
void antiParallel3D(); |
||||||
|
void common3D(); |
||||||
|
}; |
||||||
|
|
||||||
|
CapsuleRendererTest::CapsuleRendererTest() { |
||||||
|
addTests({&CapsuleRendererTest::zeroLength2D, |
||||||
|
&CapsuleRendererTest::common2D, |
||||||
|
|
||||||
|
&CapsuleRendererTest::zeroLength3D, |
||||||
|
&CapsuleRendererTest::parallel3D, |
||||||
|
&CapsuleRendererTest::antiParallel3D, |
||||||
|
&CapsuleRendererTest::common3D}); |
||||||
|
} |
||||||
|
|
||||||
|
void CapsuleRendererTest::zeroLength2D() { |
||||||
|
const Vector2 a(0.5f, 3.0f); |
||||||
|
std::array<Matrix3, 3> transformation = Implementation::capsuleRendererTransformation<2>(a, a, 3.5f); |
||||||
|
|
||||||
|
const auto scaling = Math::Matrix<2, Float>::fromDiagonal(Vector2(3.5f)); |
||||||
|
CORRADE_COMPARE(transformation[0].rotationScaling(), scaling); |
||||||
|
CORRADE_COMPARE(transformation[1].rotationScaling(), (Math::Matrix<2, Float>::fromDiagonal({3.5f, 0.0f}))); |
||||||
|
CORRADE_COMPARE(transformation[2].rotationScaling(), scaling); |
||||||
|
|
||||||
|
CORRADE_COMPARE(transformation[0].translation(), a); |
||||||
|
CORRADE_COMPARE(transformation[1].translation(), a); |
||||||
|
CORRADE_COMPARE(transformation[2].translation(), a); |
||||||
|
} |
||||||
|
|
||||||
|
void CapsuleRendererTest::common2D() { |
||||||
|
const Vector2 a(0.5f, 3.0f); |
||||||
|
const Vector2 b(7.5f, -1.0f); |
||||||
|
std::array<Matrix3, 3> transformation = Implementation::capsuleRendererTransformation<2>(a, b, 3.5f); |
||||||
|
|
||||||
|
/* Vector from capsule center to top hemisphere center */ |
||||||
|
const Vector2 up(3.5f, -2.0f); |
||||||
|
CORRADE_COMPARE(transformation[0].up(), up.resized(3.5f)); |
||||||
|
CORRADE_COMPARE(transformation[1].up(), up); |
||||||
|
CORRADE_COMPARE(transformation[2].up(), up.resized(3.5f)); |
||||||
|
|
||||||
|
const auto right = Vector2(4.0f, 7.0f).resized(3.5f); |
||||||
|
CORRADE_COMPARE(transformation[0].right(), right); |
||||||
|
CORRADE_COMPARE(transformation[1].right(), right); |
||||||
|
CORRADE_COMPARE(transformation[2].right(), right); |
||||||
|
|
||||||
|
/* Orthogonality */ |
||||||
|
CORRADE_COMPARE(Vector2::dot(transformation[0].up(), transformation[0].right()), 0.0f); |
||||||
|
|
||||||
|
const Vector2 capDistance = up.resized(3.5f); |
||||||
|
CORRADE_COMPARE(transformation[0].translation(), a+capDistance); |
||||||
|
CORRADE_COMPARE(transformation[1].translation(), 0.5f*(a + b)); |
||||||
|
CORRADE_COMPARE(transformation[2].translation(), b-capDistance); |
||||||
|
} |
||||||
|
|
||||||
|
void CapsuleRendererTest::zeroLength3D() { |
||||||
|
const Vector3 a(0.5f, 3.0f, 7.0f); |
||||||
|
std::array<Matrix4, 3> transformation = Implementation::capsuleRendererTransformation<3>(a, a, 3.5f); |
||||||
|
|
||||||
|
const auto scaling = Math::Matrix<3, Float>::fromDiagonal(Vector3(3.5f)); |
||||||
|
CORRADE_COMPARE(transformation[0].rotationScaling(), scaling); |
||||||
|
CORRADE_COMPARE(transformation[1].rotationScaling(), (Math::Matrix<3, Float>::fromDiagonal({3.5f, 0.0f, 3.5f}))); |
||||||
|
CORRADE_COMPARE(transformation[2].rotationScaling(), scaling); |
||||||
|
|
||||||
|
CORRADE_COMPARE(transformation[0].translation(), a); |
||||||
|
CORRADE_COMPARE(transformation[1].translation(), a); |
||||||
|
CORRADE_COMPARE(transformation[2].translation(), a); |
||||||
|
} |
||||||
|
|
||||||
|
void CapsuleRendererTest::parallel3D() { |
||||||
|
const Vector3 a(0.5f, 3.0f, 7.0f); |
||||||
|
const Vector3 b(0.5f, 3.0f, 11.0f); |
||||||
|
std::array<Matrix4, 3> transformation = Implementation::capsuleRendererTransformation<3>(a, b, 3.5f); |
||||||
|
|
||||||
|
const auto rotation = Matrix4::rotationX(Deg(90.0f)); |
||||||
|
const auto scaling = (rotation*Matrix4::scaling(Vector3(3.5f))).rotationScaling(); |
||||||
|
CORRADE_COMPARE(transformation[0].rotationScaling(), scaling); |
||||||
|
CORRADE_COMPARE(transformation[1].rotationScaling(), |
||||||
|
(rotation*Matrix4::scaling({3.5f, 2.0f, 3.5f})).rotationScaling()); |
||||||
|
CORRADE_COMPARE(transformation[2].rotationScaling(), scaling); |
||||||
|
|
||||||
|
const auto capDistance = Vector3::zAxis(3.5f); |
||||||
|
CORRADE_COMPARE(transformation[0].translation(), a+capDistance); |
||||||
|
CORRADE_COMPARE(transformation[1].translation(), a+Vector3::zAxis(2.0f)); |
||||||
|
CORRADE_COMPARE(transformation[2].translation(), b-capDistance); |
||||||
|
} |
||||||
|
|
||||||
|
void CapsuleRendererTest::antiParallel3D() { |
||||||
|
const Vector3 a(0.5f, 3.0f, 7.0f); |
||||||
|
const Vector3 b(0.5f, 3.0f, 3.0f); |
||||||
|
std::array<Matrix4, 3> transformation = Implementation::capsuleRendererTransformation<3>(a, b, 3.5f); |
||||||
|
|
||||||
|
const auto rotation = Matrix4::rotationX(-Deg(90.0f)); |
||||||
|
const auto rotationScaling = (rotation*Matrix4::scaling(Vector3(3.5f))).rotationScaling(); |
||||||
|
CORRADE_COMPARE(transformation[0].rotationScaling(), rotationScaling); |
||||||
|
CORRADE_COMPARE(transformation[1].rotationScaling(), |
||||||
|
(rotation*Matrix4::scaling({3.5f, 2.0f, 3.5f})).rotationScaling()); |
||||||
|
CORRADE_COMPARE(transformation[2].rotationScaling(), rotationScaling); |
||||||
|
|
||||||
|
const auto capDistance = Vector3::zAxis(-3.5f); |
||||||
|
CORRADE_COMPARE(transformation[0].translation(), a+capDistance); |
||||||
|
CORRADE_COMPARE(transformation[1].translation(), a+Vector3::zAxis(-2.0f)); |
||||||
|
CORRADE_COMPARE(transformation[2].translation(), b-capDistance); |
||||||
|
} |
||||||
|
|
||||||
|
void CapsuleRendererTest::common3D() { |
||||||
|
const Vector3 a(0.5f, 3.0f, 7.0f); |
||||||
|
const Vector3 b(7.5f, -1.0f, 1.5f); |
||||||
|
std::array<Matrix4, 3> transformation = Implementation::capsuleRendererTransformation<3>(a, b, 3.5f); |
||||||
|
|
||||||
|
/* Vector from capsule center to top hemisphere center */ |
||||||
|
const Vector3 up(3.5f, -2.0f, -2.75f); |
||||||
|
CORRADE_COMPARE(transformation[0].up(), up.resized(3.5f)); |
||||||
|
CORRADE_COMPARE(transformation[1].up(), up); |
||||||
|
CORRADE_COMPARE(transformation[2].up(), up.resized(3.5f)); |
||||||
|
|
||||||
|
const auto right = Vector3(-2.0f, -3.5f, 0.0f).resized(3.5f); |
||||||
|
CORRADE_COMPARE(transformation[0].right(), right); |
||||||
|
CORRADE_COMPARE(transformation[1].right(), right); |
||||||
|
CORRADE_COMPARE(transformation[2].right(), right); |
||||||
|
|
||||||
|
const auto backward = Vector3(9.625f, -5.5f, 16.25f).resized(3.5f); |
||||||
|
CORRADE_COMPARE(transformation[0].backward(), backward); |
||||||
|
CORRADE_COMPARE(transformation[1].backward(), backward); |
||||||
|
CORRADE_COMPARE(transformation[2].backward(), backward); |
||||||
|
|
||||||
|
/* Orthogonality */ |
||||||
|
CORRADE_COMPARE(Vector3::dot(transformation[0].up(), transformation[0].right()), 0.0f); |
||||||
|
CORRADE_COMPARE(Vector3::dot(transformation[0].up(), transformation[0].backward()), 0.0f); |
||||||
|
CORRADE_COMPARE(Vector3::dot(transformation[0].right(), transformation[0].backward()), 0.0f); |
||||||
|
|
||||||
|
const Vector3 capDistance = up.resized(3.5f); |
||||||
|
CORRADE_COMPARE(transformation[0].translation(), a+capDistance); |
||||||
|
CORRADE_COMPARE(transformation[1].translation(), 0.5f*(a + b)); |
||||||
|
CORRADE_COMPARE(transformation[2].translation(), b-capDistance); |
||||||
|
} |
||||||
|
|
||||||
|
}}} |
||||||
|
|
||||||
|
CORRADE_TEST_MAIN(Magnum::DebugTools::Test::CapsuleRendererTest) |
||||||
@ -0,0 +1,125 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <TestSuite/Tester.h> |
||||||
|
|
||||||
|
#include "DebugTools/Implementation/CylinderRendererTransformation.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace DebugTools { namespace Test { |
||||||
|
|
||||||
|
class CylinderRendererTest: public TestSuite::Tester { |
||||||
|
public: |
||||||
|
explicit CylinderRendererTest(); |
||||||
|
|
||||||
|
void zeroLength2D(); |
||||||
|
void common2D(); |
||||||
|
|
||||||
|
void zeroLength3D(); |
||||||
|
void parallel3D(); |
||||||
|
void antiParallel3D(); |
||||||
|
void common3D(); |
||||||
|
}; |
||||||
|
|
||||||
|
CylinderRendererTest::CylinderRendererTest() { |
||||||
|
addTests({&CylinderRendererTest::zeroLength2D, |
||||||
|
&CylinderRendererTest::common2D, |
||||||
|
|
||||||
|
&CylinderRendererTest::zeroLength3D, |
||||||
|
&CylinderRendererTest::parallel3D, |
||||||
|
&CylinderRendererTest::antiParallel3D, |
||||||
|
&CylinderRendererTest::common3D}); |
||||||
|
} |
||||||
|
|
||||||
|
void CylinderRendererTest::zeroLength2D() { |
||||||
|
const Vector2 a(0.5f, 3.0f); |
||||||
|
const Matrix3 transformation = Implementation::cylinderRendererTransformation<2>(a, a, 3.5f); |
||||||
|
|
||||||
|
CORRADE_COMPARE(transformation.rotationScaling(), (Math::Matrix<2, Float>::fromDiagonal({3.5f, 0.0f}))); |
||||||
|
CORRADE_COMPARE(transformation.translation(), a); |
||||||
|
} |
||||||
|
|
||||||
|
void CylinderRendererTest::common2D() { |
||||||
|
const Vector2 a(0.5f, 3.0f); |
||||||
|
const Vector2 b(7.5f, -1.0f); |
||||||
|
const Matrix3 transformation = Implementation::cylinderRendererTransformation<2>(a, b, 3.5f); |
||||||
|
|
||||||
|
/* Rotation + scaling, test orthogonality */ |
||||||
|
CORRADE_COMPARE(transformation.up(), Vector2(3.5f, -2.0f)); |
||||||
|
CORRADE_COMPARE(transformation.right(), Vector2(4.0f, 7.0f).resized(3.5f)); |
||||||
|
CORRADE_COMPARE(Vector2::dot(transformation.up(), transformation.right()), 0.0f); |
||||||
|
|
||||||
|
CORRADE_COMPARE(transformation.translation(), 0.5f*(a + b)); |
||||||
|
} |
||||||
|
|
||||||
|
void CylinderRendererTest::zeroLength3D() { |
||||||
|
const Vector3 a(0.5f, 3.0f, 7.0f); |
||||||
|
const Matrix4 transformation = Implementation::cylinderRendererTransformation<3>(a, a, 3.5f); |
||||||
|
|
||||||
|
CORRADE_COMPARE(transformation.rotationScaling(), (Math::Matrix<3, Float>::fromDiagonal({3.5f, 0.0f, 3.5f}))); |
||||||
|
CORRADE_COMPARE(transformation.translation(), a); |
||||||
|
} |
||||||
|
|
||||||
|
void CylinderRendererTest::parallel3D() { |
||||||
|
const Vector3 a(0.5f, 3.0f, 7.0f); |
||||||
|
const Vector3 b(0.5f, 3.0f, 11.0f); |
||||||
|
const Matrix4 transformation = Implementation::cylinderRendererTransformation<3>(a, b, 3.5f); |
||||||
|
|
||||||
|
CORRADE_COMPARE(transformation.rotationScaling(), |
||||||
|
(Matrix4::rotationX(Deg(90.0f))*Matrix4::scaling({3.5f, 2.0f, 3.5f})).rotationScaling()); |
||||||
|
|
||||||
|
CORRADE_COMPARE(transformation.translation(), a+Vector3::zAxis(2.0f)); |
||||||
|
} |
||||||
|
|
||||||
|
void CylinderRendererTest::antiParallel3D() { |
||||||
|
const Vector3 a(0.5f, 3.0f, 7.0f); |
||||||
|
const Vector3 b(0.5f, 3.0f, 3.0f); |
||||||
|
const Matrix4 transformation = Implementation::cylinderRendererTransformation<3>(a, b, 3.5f); |
||||||
|
|
||||||
|
CORRADE_COMPARE(transformation.rotationScaling(), |
||||||
|
(Matrix4::rotationX(-Deg(90.0f))*Matrix4::scaling({3.5f, 2.0f, 3.5f})).rotationScaling()); |
||||||
|
|
||||||
|
CORRADE_COMPARE(transformation.translation(), a+Vector3::zAxis(-2.0f)); |
||||||
|
} |
||||||
|
|
||||||
|
void CylinderRendererTest::common3D() { |
||||||
|
const Vector3 a(0.5f, 3.0f, 7.0f); |
||||||
|
const Vector3 b(7.5f, -1.0f, 1.5f); |
||||||
|
const Matrix4 transformation = Implementation::cylinderRendererTransformation<3>(a, b, 3.5f); |
||||||
|
|
||||||
|
/* Rotation + scaling */ |
||||||
|
CORRADE_COMPARE(transformation.up(), Vector3(3.5f, -2.0f, -2.75f)); |
||||||
|
CORRADE_COMPARE(transformation.right(), Vector3(-2.0f, -3.5f, 0.0f).resized(3.5f)); |
||||||
|
CORRADE_COMPARE(transformation.backward(), Vector3(9.625f, -5.5f, 16.25f).resized(3.5f)); |
||||||
|
|
||||||
|
/* Orthogonality */ |
||||||
|
CORRADE_COMPARE(Vector3::dot(transformation.up(), transformation.right()), 0.0f); |
||||||
|
CORRADE_COMPARE(Vector3::dot(transformation.up(), transformation.backward()), 0.0f); |
||||||
|
CORRADE_COMPARE(Vector3::dot(transformation.right(), transformation.backward()), 0.0f); |
||||||
|
|
||||||
|
CORRADE_COMPARE(transformation.translation(), 0.5f*(a + b)); |
||||||
|
} |
||||||
|
|
||||||
|
}}} |
||||||
|
|
||||||
|
CORRADE_TEST_MAIN(Magnum::DebugTools::Test::CylinderRendererTest) |
||||||
@ -0,0 +1,43 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "MeshView.h" |
||||||
|
|
||||||
|
#include "Mesh.h" |
||||||
|
|
||||||
|
namespace Magnum { |
||||||
|
|
||||||
|
MeshView& MeshView::setIndexRange(Int first, Int count, UnsignedInt start, UnsignedInt end) { |
||||||
|
_indexOffset = first*_original->indexSize(); |
||||||
|
_indexCount = count; |
||||||
|
_indexStart = start; |
||||||
|
_indexEnd = end; |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
void MeshView::draw() { |
||||||
|
_original->drawInternal(_firstVertex, _vertexCount, _indexOffset, _indexCount, _indexStart, _indexEnd); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,139 @@ |
|||||||
|
#ifndef Magnum_MeshView_h |
||||||
|
#define Magnum_MeshView_h |
||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
/** @file
|
||||||
|
* @brief Class Magnum::MeshView |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "Magnum.h" |
||||||
|
#include "magnumVisibility.h" |
||||||
|
|
||||||
|
#ifndef DOXYGEN_GENERATING_OUTPUT |
||||||
|
typedef std::ptrdiff_t GLintptr; |
||||||
|
#endif |
||||||
|
|
||||||
|
namespace Magnum { |
||||||
|
|
||||||
|
/**
|
||||||
|
@brief %Mesh view |
||||||
|
|
||||||
|
Allows different interpretation of given @ref Mesh data via different vertex or |
||||||
|
index count and offset. It is then possible to reuse one mesh buffer |
||||||
|
configuration for different views. %Mesh primitive, index type, attribute |
||||||
|
bindings and attached buffers are reused from original mesh. |
||||||
|
|
||||||
|
The same rules as in Mesh apply, i.e. if the view has non-zero index count, it |
||||||
|
is treated as indexed mesh, otherwise it is treated as non-indexed mesh. If |
||||||
|
both index and vertex count is zero, the view is treated as empty and no draw |
||||||
|
commands are issued when calling draw(). |
||||||
|
|
||||||
|
You must ensure that the original mesh remains available for whole view |
||||||
|
lifetime. |
||||||
|
@todo Might cause issues when there are more data than just indices in index |
||||||
|
buffer (wrongly computed offset) |
||||||
|
*/ |
||||||
|
class MAGNUM_EXPORT MeshView { |
||||||
|
public: |
||||||
|
/**
|
||||||
|
* @brief Constructor |
||||||
|
* @param original Original, already configured mesh |
||||||
|
*/ |
||||||
|
explicit MeshView(Mesh& original); |
||||||
|
|
||||||
|
/** @brief Copy constructor */ |
||||||
|
MeshView(const MeshView& other) = default; |
||||||
|
|
||||||
|
/** @brief Movement is not allowed */ |
||||||
|
MeshView(MeshView&& other) = delete; |
||||||
|
|
||||||
|
/** @brief Copy assignment */ |
||||||
|
MeshView& operator=(const MeshView&) = default; |
||||||
|
|
||||||
|
/** @brief Movement is not allowed */ |
||||||
|
MeshView& operator=(MeshView&& other) = delete; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set vertex range |
||||||
|
* @param first First vertex |
||||||
|
* @param count Vertex count |
||||||
|
* @return Reference to self (for method chaining) |
||||||
|
* |
||||||
|
* Default is zero @p offset and zero @p count. If index range is |
||||||
|
* non-zero, vertex range is ignored, see main class documentation for |
||||||
|
* more information. |
||||||
|
*/ |
||||||
|
MeshView& setVertexRange(Int first, Int count) { |
||||||
|
_firstVertex = first; |
||||||
|
_vertexCount = count; |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set index range |
||||||
|
* @param first First index |
||||||
|
* @param count Index count |
||||||
|
* @param start Minimum array index contained in the buffer |
||||||
|
* @param end Maximum array index contained in the buffer |
||||||
|
* @return Reference to self (for method chaining) |
||||||
|
* |
||||||
|
* Specifying `0` for both @p start and @p end behaves the same as |
||||||
|
* @ref setIndexRange(Int, Int). |
||||||
|
*/ |
||||||
|
MeshView& setIndexRange(Int first, Int count, UnsignedInt start, UnsignedInt end); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set index range |
||||||
|
* @param first First index |
||||||
|
* @param count Index count |
||||||
|
* @return Reference to self (for method chaining) |
||||||
|
* |
||||||
|
* Prefer to use @ref setIndexRange(Int, Int, UnsignedInt, UnsignedInt) |
||||||
|
* for better performance. |
||||||
|
*/ |
||||||
|
MeshView& setIndexRange(Int first, Int count) { |
||||||
|
return setIndexRange(first, count, 0, 0); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Draw the mesh |
||||||
|
* |
||||||
|
* See @ref Mesh::draw() for more information. |
||||||
|
*/ |
||||||
|
void draw(); |
||||||
|
|
||||||
|
private: |
||||||
|
Mesh* _original; |
||||||
|
|
||||||
|
Int _firstVertex, _vertexCount, _indexCount; |
||||||
|
GLintptr _indexOffset; |
||||||
|
UnsignedInt _indexStart, _indexEnd; |
||||||
|
}; |
||||||
|
|
||||||
|
inline MeshView::MeshView(Mesh& original): _original(&original), _firstVertex(0), _vertexCount(0), _indexCount(0), _indexOffset(0), _indexStart(0), _indexEnd(0) {} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
#endif |
||||||
@ -0,0 +1,58 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "Cylinder.h" |
||||||
|
|
||||||
|
#include "Math/Functions.h" |
||||||
|
#include "Math/Matrix3.h" |
||||||
|
#include "Math/Matrix4.h" |
||||||
|
#include "Math/Geometry/Distance.h" |
||||||
|
#include "Magnum.h" |
||||||
|
#include "Shapes/Point.h" |
||||||
|
#include "Shapes/Sphere.h" |
||||||
|
|
||||||
|
using namespace Magnum::Math::Geometry; |
||||||
|
|
||||||
|
namespace Magnum { namespace Shapes { |
||||||
|
|
||||||
|
template<UnsignedInt dimensions> Cylinder<dimensions> Cylinder<dimensions>::transformed(const typename DimensionTraits<dimensions, Float>::MatrixType& matrix) const { |
||||||
|
return Cylinder<dimensions>(matrix.transformPoint(_a), matrix.transformPoint(_b), matrix.uniformScaling()*_radius); |
||||||
|
} |
||||||
|
|
||||||
|
template<UnsignedInt dimensions> bool Cylinder<dimensions>::operator%(const Point<dimensions>& other) const { |
||||||
|
return Distance::linePointSquared(_a, _b, other.position()) < |
||||||
|
Math::pow<2>(_radius); |
||||||
|
} |
||||||
|
|
||||||
|
template<UnsignedInt dimensions> bool Cylinder<dimensions>::operator%(const Sphere<dimensions>& other) const { |
||||||
|
return Distance::linePointSquared(_a, _b, other.position()) < |
||||||
|
Math::pow<2>(_radius+other.radius()); |
||||||
|
} |
||||||
|
|
||||||
|
#ifndef DOXYGEN_GENERATING_OUTPUT |
||||||
|
template class MAGNUM_SHAPES_EXPORT Cylinder<2>; |
||||||
|
template class MAGNUM_SHAPES_EXPORT Cylinder<3>; |
||||||
|
#endif |
||||||
|
|
||||||
|
}} |
||||||
@ -0,0 +1,117 @@ |
|||||||
|
#ifndef Magnum_Shapes_Cylinder_h |
||||||
|
#define Magnum_Shapes_Cylinder_h |
||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
/** @file
|
||||||
|
* @brief Class Magnum::Shapes::Cylinder, typedef Magnum::Shapes::Cylinder2D, Magnum::Shapes::Cylinder3D |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "Math/Vector3.h" |
||||||
|
#include "DimensionTraits.h" |
||||||
|
#include "Shapes/Shapes.h" |
||||||
|
#include "Shapes/magnumShapesVisibility.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace Shapes { |
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Infinite cylinder defined by line and radius |
||||||
|
|
||||||
|
Unlike other elements the cylinder expects uniform scaling. See @ref shapes for |
||||||
|
brief introduction. |
||||||
|
@see @ref Cylinder2D, @ref Cylinder3D, @ref Capsule |
||||||
|
@todo Store the radius as squared value to avoid sqrt/pow? Will complicate |
||||||
|
collision detection with sphere. |
||||||
|
*/ |
||||||
|
template<UnsignedInt dimensions> class MAGNUM_SHAPES_EXPORT Cylinder { |
||||||
|
public: |
||||||
|
enum: UnsignedInt { |
||||||
|
Dimensions = dimensions /**< Dimension count */ |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constructor |
||||||
|
* |
||||||
|
* Creates zero-sized cylinder at origin. |
||||||
|
*/ |
||||||
|
constexpr /*implicit*/ Cylinder(): _radius(0.0f) {} |
||||||
|
|
||||||
|
/** @brief Constructor */ |
||||||
|
constexpr /*implicit*/ Cylinder(const typename DimensionTraits<dimensions, Float>::VectorType& a, const typename DimensionTraits<dimensions, Float>::VectorType& b, Float radius): _a(a), _b(b), _radius(radius) {} |
||||||
|
|
||||||
|
/** @brief Transformed shape */ |
||||||
|
Cylinder<dimensions> transformed(const typename DimensionTraits<dimensions, Float>::MatrixType& matrix) const; |
||||||
|
|
||||||
|
/** @brief First point */ |
||||||
|
constexpr typename DimensionTraits<dimensions, Float>::VectorType a() const { |
||||||
|
return _a; |
||||||
|
} |
||||||
|
|
||||||
|
/** @brief Set first point */ |
||||||
|
void setA(const typename DimensionTraits<dimensions, Float>::VectorType& a) { |
||||||
|
_a = a; |
||||||
|
} |
||||||
|
|
||||||
|
/** @brief Second point */ |
||||||
|
constexpr typename DimensionTraits<dimensions, Float>::VectorType b() const { |
||||||
|
return _b; |
||||||
|
} |
||||||
|
|
||||||
|
/** @brief Set second point */ |
||||||
|
void setB(const typename DimensionTraits<dimensions, Float>::VectorType& b) { |
||||||
|
_b = b; |
||||||
|
} |
||||||
|
|
||||||
|
/** @brief Radius */ |
||||||
|
constexpr Float radius() const { return _radius; } |
||||||
|
|
||||||
|
/** @brief Set radius */ |
||||||
|
void setRadius(Float radius) { _radius = radius; } |
||||||
|
|
||||||
|
/** @brief Collision with point */ |
||||||
|
bool operator%(const Point<dimensions>& other) const; |
||||||
|
|
||||||
|
/** @brief Collision with sphere */ |
||||||
|
bool operator%(const Sphere<dimensions>& other) const; |
||||||
|
|
||||||
|
private: |
||||||
|
typename DimensionTraits<dimensions, Float>::VectorType _a, _b; |
||||||
|
Float _radius; |
||||||
|
}; |
||||||
|
|
||||||
|
/** @brief Infinite two-dimensional cylinder */ |
||||||
|
typedef Cylinder<2> Cylinder2D; |
||||||
|
|
||||||
|
/** @brief Infinite three-dimensional cylinder */ |
||||||
|
typedef Cylinder<3> Cylinder3D; |
||||||
|
|
||||||
|
/** @collisionoperator{Point,Cylinder} */ |
||||||
|
template<UnsignedInt dimensions> inline bool operator%(const Point<dimensions>& a, const Cylinder<dimensions>& b) { return b % a; } |
||||||
|
|
||||||
|
/** @collisionoperator{Sphere,Cylinder} */ |
||||||
|
template<UnsignedInt dimensions> inline bool operator%(const Sphere<dimensions>& a, const Cylinder<dimensions>& b) { return b % a; } |
||||||
|
|
||||||
|
}} |
||||||
|
|
||||||
|
#endif |
||||||
@ -0,0 +1,85 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "Math/Matrix3.h" |
||||||
|
#include "Math/Matrix4.h" |
||||||
|
#include "Magnum.h" |
||||||
|
#include "Shapes/Cylinder.h" |
||||||
|
#include "Shapes/Point.h" |
||||||
|
#include "Shapes/Sphere.h" |
||||||
|
|
||||||
|
#include "ShapeTestBase.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace Shapes { namespace Test { |
||||||
|
|
||||||
|
class CylinderTest: public TestSuite::Tester { |
||||||
|
public: |
||||||
|
CylinderTest(); |
||||||
|
|
||||||
|
void transformed(); |
||||||
|
void transformedAverageScaling(); |
||||||
|
void collisionPoint(); |
||||||
|
void collisionSphere(); |
||||||
|
}; |
||||||
|
|
||||||
|
CylinderTest::CylinderTest() { |
||||||
|
addTests({&CylinderTest::transformed, |
||||||
|
&CylinderTest::collisionPoint, |
||||||
|
&CylinderTest::collisionSphere}); |
||||||
|
} |
||||||
|
|
||||||
|
void CylinderTest::transformed() { |
||||||
|
const Shapes::Cylinder3D cylinder({1.0f, 2.0f, 3.0f}, {-1.0f, -2.0f, -3.0f}, 7.0f); |
||||||
|
|
||||||
|
const auto transformed = cylinder.transformed(Matrix4::scaling(Vector3(2.0f))*Matrix4::rotation(Deg(90.0f), Vector3::zAxis())); |
||||||
|
CORRADE_COMPARE(transformed.a(), Vector3(-4.0f, 2.0f, 6.0f)); |
||||||
|
CORRADE_COMPARE(transformed.b(), Vector3(4.0f, -2.0f, -6.0f)); |
||||||
|
CORRADE_COMPARE(transformed.radius(), 14.0f); |
||||||
|
} |
||||||
|
|
||||||
|
void CylinderTest::collisionPoint() { |
||||||
|
Shapes::Cylinder3D cylinder({-1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, 2.0f); |
||||||
|
Shapes::Point3D point({2.0f, 0.0f, 0.0f}); |
||||||
|
Shapes::Point3D point1({1.0f, 3.1f, 0.0f}); |
||||||
|
Shapes::Point3D point2({2.9f, -1.0f, 0.0f}); |
||||||
|
|
||||||
|
VERIFY_COLLIDES(cylinder, point); |
||||||
|
VERIFY_COLLIDES(cylinder, point1); |
||||||
|
VERIFY_NOT_COLLIDES(cylinder, point2); |
||||||
|
} |
||||||
|
|
||||||
|
void CylinderTest::collisionSphere() { |
||||||
|
Shapes::Cylinder3D cylinder({-1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, 2.0f); |
||||||
|
Shapes::Sphere3D sphere({3.0f, 0.0f, 0.0f}, 0.9f); |
||||||
|
Shapes::Sphere3D sphere1({1.0f, 4.1f, 0.0f}, 1.0f); |
||||||
|
Shapes::Sphere3D sphere2({3.5f, -1.0f, 0.0f}, 0.6f); |
||||||
|
|
||||||
|
VERIFY_COLLIDES(cylinder, sphere); |
||||||
|
VERIFY_COLLIDES(cylinder, sphere1); |
||||||
|
VERIFY_NOT_COLLIDES(cylinder, sphere2); |
||||||
|
} |
||||||
|
|
||||||
|
}}} |
||||||
|
|
||||||
|
CORRADE_TEST_MAIN(Magnum::Shapes::Test::CylinderTest) |
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue