diff --git a/src/AbstractFramebuffer.cpp b/src/AbstractFramebuffer.cpp index 6fd62aab8..7c353bcbd 100644 --- a/src/AbstractFramebuffer.cpp +++ b/src/AbstractFramebuffer.cpp @@ -62,7 +62,7 @@ void AbstractFramebuffer::bindInternal(Target target) { } else if(target == Target::ReadDraw) { if(state->readBinding == _id && state->drawBinding == _id) return; state->readBinding = state->drawBinding = _id; - } else CORRADE_INTERNAL_ASSERT(false); + } else CORRADE_ASSERT_UNREACHABLE(); glBindFramebuffer(static_cast(target), _id); } diff --git a/src/AbstractImage.cpp b/src/AbstractImage.cpp index c7bd56b2d..761f15dd8 100644 --- a/src/AbstractImage.cpp +++ b/src/AbstractImage.cpp @@ -129,10 +129,10 @@ std::size_t AbstractImage::pixelSize(Format format, Type type) { case Format::StencilIndex: #endif case Format::DepthStencil: - CORRADE_INTERNAL_ASSERT(false); + CORRADE_ASSERT_UNREACHABLE(); } - CORRADE_INTERNAL_ASSERT(false); + CORRADE_ASSERT_UNREACHABLE(); return 0; } diff --git a/src/AbstractShaderProgram.cpp b/src/AbstractShaderProgram.cpp index b353ca475..bd5c52273 100644 --- a/src/AbstractShaderProgram.cpp +++ b/src/AbstractShaderProgram.cpp @@ -27,7 +27,7 @@ #include #include -#include "Math/Matrix.h" +#include "Math/RectangularMatrix.h" #include "Shader.h" #include "Implementation/State.h" #include "Implementation/ShaderProgramState.h" @@ -37,22 +37,22 @@ namespace Magnum { -AbstractShaderProgram::Uniform1fImplementation AbstractShaderProgram::uniform1fImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform1fvImplementation AbstractShaderProgram::uniform1fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; AbstractShaderProgram::Uniform2fvImplementation AbstractShaderProgram::uniform2fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; AbstractShaderProgram::Uniform3fvImplementation AbstractShaderProgram::uniform3fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; AbstractShaderProgram::Uniform4fvImplementation AbstractShaderProgram::uniform4fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; -AbstractShaderProgram::Uniform1iImplementation AbstractShaderProgram::uniform1iImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform1ivImplementation AbstractShaderProgram::uniform1ivImplementation = &AbstractShaderProgram::uniformImplementationDefault; AbstractShaderProgram::Uniform2ivImplementation AbstractShaderProgram::uniform2ivImplementation = &AbstractShaderProgram::uniformImplementationDefault; AbstractShaderProgram::Uniform3ivImplementation AbstractShaderProgram::uniform3ivImplementation = &AbstractShaderProgram::uniformImplementationDefault; AbstractShaderProgram::Uniform4ivImplementation AbstractShaderProgram::uniform4ivImplementation = &AbstractShaderProgram::uniformImplementationDefault; #ifndef MAGNUM_TARGET_GLES2 -AbstractShaderProgram::Uniform1uiImplementation AbstractShaderProgram::uniform1uiImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform1uivImplementation AbstractShaderProgram::uniform1uivImplementation = &AbstractShaderProgram::uniformImplementationDefault; AbstractShaderProgram::Uniform2uivImplementation AbstractShaderProgram::uniform2uivImplementation = &AbstractShaderProgram::uniformImplementationDefault; AbstractShaderProgram::Uniform3uivImplementation AbstractShaderProgram::uniform3uivImplementation = &AbstractShaderProgram::uniformImplementationDefault; AbstractShaderProgram::Uniform4uivImplementation AbstractShaderProgram::uniform4uivImplementation = &AbstractShaderProgram::uniformImplementationDefault; #endif #ifndef MAGNUM_TARGET_GLES -AbstractShaderProgram::Uniform1dImplementation AbstractShaderProgram::uniform1dImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform1dvImplementation AbstractShaderProgram::uniform1dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; AbstractShaderProgram::Uniform2dvImplementation AbstractShaderProgram::uniform2dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; AbstractShaderProgram::Uniform3dvImplementation AbstractShaderProgram::uniform3dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; AbstractShaderProgram::Uniform4dvImplementation AbstractShaderProgram::uniform4dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; @@ -181,19 +181,19 @@ void AbstractShaderProgram::initializeContextBasedFunctionality(Context* context context->isExtensionSupported()) { Debug() << "AbstractShaderProgram: using" << (context->isExtensionSupported() ? Extensions::GL::ARB::separate_shader_objects::string() : Extensions::GL::EXT::direct_state_access::string()) << "features"; - uniform1fImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform1fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; uniform2fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; uniform3fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; uniform4fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; - uniform1iImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform1ivImplementation = &AbstractShaderProgram::uniformImplementationDSA; uniform2ivImplementation = &AbstractShaderProgram::uniformImplementationDSA; uniform3ivImplementation = &AbstractShaderProgram::uniformImplementationDSA; uniform4ivImplementation = &AbstractShaderProgram::uniformImplementationDSA; - uniform1uiImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform1uivImplementation = &AbstractShaderProgram::uniformImplementationDSA; uniform2uivImplementation = &AbstractShaderProgram::uniformImplementationDSA; uniform3uivImplementation = &AbstractShaderProgram::uniformImplementationDSA; uniform4uivImplementation = &AbstractShaderProgram::uniformImplementationDSA; - uniform1dImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform1dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; uniform2dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; uniform3dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; uniform4dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; @@ -222,359 +222,359 @@ void AbstractShaderProgram::initializeContextBasedFunctionality(Context* context #endif } -void AbstractShaderProgram::uniformImplementationDefault(GLint location, GLfloat value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const GLfloat* const values) { use(); - glUniform1f(location, value); + glUniform1fv(location, count, values); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, GLfloat value) { - glProgramUniform1f(_id, location, value); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const GLfloat* const values) { + glProgramUniform1fv(_id, location, count, values); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<2, GLfloat>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::Vector<2, GLfloat>* const values) { use(); - glUniform2fv(location, 1, value.data()); + glUniform2fv(location, count, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<2, GLfloat>& value) { - glProgramUniform2fv(_id, location, 1, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<2, GLfloat>* const values) { + glProgramUniform2fv(_id, location, count, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<3, GLfloat>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::Vector<3, GLfloat>* const values) { use(); - glUniform3fv(location, 1, value.data()); + glUniform3fv(location, count, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<3, GLfloat>& value) { - glProgramUniform3fv(_id, location, 1, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<3, GLfloat>* const values) { + glProgramUniform3fv(_id, location, count, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<4, GLfloat>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::Vector<4, GLfloat>* const values) { use(); - glUniform4fv(location, 1, value.data()); + glUniform4fv(location, count, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<4, GLfloat>& value) { - glProgramUniform4fv(_id, location, 1, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<4, GLfloat>* const values) { + glProgramUniform4fv(_id, location, count, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, GLint value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const GLint* const values) { use(); - glUniform1i(location, value); + glUniform1iv(location, count, values); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, GLint value) { - glProgramUniform1i(_id, location, value); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const GLint* const values) { + glProgramUniform1iv(_id, location, count, values); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<2, GLint>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::Vector<2, GLint>* const values) { use(); - glUniform2iv(location, 1, value.data()); + glUniform2iv(location, count, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<2, GLint>& value) { - glProgramUniform2iv(_id, location, 1, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<2, GLint>* const values) { + glProgramUniform2iv(_id, location, count, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<3, GLint>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::Vector<3, GLint>* const values) { use(); - glUniform3iv(location, 1, value.data()); + glUniform3iv(location, count, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<3, GLint>& value) { - glProgramUniform3iv(_id, location, 1, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<3, GLint>* const values) { + glProgramUniform3iv(_id, location, count, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<4, GLint>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::Vector<4, GLint>* const values) { use(); - glUniform4iv(location, 1, value.data()); + glUniform4iv(location, count, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<4, GLint>& value) { - glProgramUniform4iv(_id, location, 1, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<4, GLint>* const values) { + glProgramUniform4iv(_id, location, count, values[0].data()); } #endif #ifndef MAGNUM_TARGET_GLES2 -void AbstractShaderProgram::uniformImplementationDefault(GLint location, GLuint value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const GLuint* const values) { use(); - glUniform1ui(location, value); + glUniform1uiv(location, count, values); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, GLuint value) { - glProgramUniform1ui(_id, location, value); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const GLuint* const values) { + glProgramUniform1uiv(_id, location, count, values); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<2, GLuint>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::Vector<2, GLuint>* const values) { use(); - glUniform2uiv(location, 1, value.data()); + glUniform2uiv(location, count, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<2, GLuint>& value) { - glProgramUniform2uiv(_id, location, 1, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<2, GLuint>* const values) { + glProgramUniform2uiv(_id, location, count, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<3, GLuint>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::Vector<3, GLuint>* const values) { use(); - glUniform3uiv(location, 1, value.data()); + glUniform3uiv(location, count, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<3, GLuint>& value) { - glProgramUniform3uiv(_id, location, 1, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<3, GLuint>* const values) { + glProgramUniform3uiv(_id, location, count, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<4, GLuint>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::Vector<4, GLuint>* const values) { use(); - glUniform4uiv(location, 1, value.data()); + glUniform4uiv(location, count, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<4, GLuint>& value) { - glProgramUniform4uiv(_id, location, 1, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<4, GLuint>* const values) { + glProgramUniform4uiv(_id, location, count, values[0].data()); } #endif #endif #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDefault(GLint location, GLdouble value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const GLdouble* const values) { use(); - glUniform1d(location, value); + glUniform1dv(location, count, values); } -void AbstractShaderProgram::uniformImplementationDSA(GLint location, GLdouble value) { - glProgramUniform1d(_id, location, value); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const GLdouble* const values) { + glProgramUniform1dv(_id, location, count, values); } -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<2, GLdouble>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::Vector<2, GLdouble>* const values) { use(); - glUniform2dv(location, 1, value.data()); + glUniform2dv(location, count, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<2, GLdouble>& value) { - glProgramUniform2dv(_id, location, 1, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<2, GLdouble>* const values) { + glProgramUniform2dv(_id, location, count, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<3, GLdouble>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::Vector<3, GLdouble>* const values) { use(); - glUniform3dv(location, 1, value.data()); + glUniform3dv(location, count, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<3, GLdouble>& value) { - glProgramUniform3dv(_id, location, 1, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<3, GLdouble>* const values) { + glProgramUniform3dv(_id, location, count, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<4, GLdouble>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::Vector<4, GLdouble>* const values) { use(); - glUniform4dv(location, 1, value.data()); + glUniform4dv(location, count, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<4, GLdouble>& value) { - glProgramUniform4dv(_id, location, 1, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<4, GLdouble>* const values) { + glProgramUniform4dv(_id, location, count, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Matrix<2, GLfloat>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 2, GLfloat>* const values) { use(); - glUniformMatrix2fv(location, 1, GL_FALSE, value.data()); + glUniformMatrix2fv(location, count, GL_FALSE, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Matrix<2, GLfloat>& value) { - glProgramUniformMatrix2fv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 2, GLfloat>* const values) { + glProgramUniformMatrix2fv(_id, location, count, GL_FALSE, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Matrix<3, GLfloat>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 3, GLfloat>* const values) { use(); - glUniformMatrix3fv(location, 1, GL_FALSE, value.data()); + glUniformMatrix3fv(location, count, GL_FALSE, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Matrix<3, GLfloat>& value) { - glProgramUniformMatrix3fv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 3, GLfloat>* const values) { + glProgramUniformMatrix3fv(_id, location, count, GL_FALSE, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Matrix<4, GLfloat>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 4, GLfloat>* const values) { use(); - glUniformMatrix4fv(location, 1, GL_FALSE, value.data()); + glUniformMatrix4fv(location, count, GL_FALSE, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Matrix<4, GLfloat>& value) { - glProgramUniformMatrix4fv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 4, GLfloat>* const values) { + glProgramUniformMatrix4fv(_id, location, count, GL_FALSE, values[0].data()); } #endif #ifndef MAGNUM_TARGET_GLES2 -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 3, GLfloat>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 3, GLfloat>* const values) { use(); - glUniformMatrix2x3fv(location, 1, GL_FALSE, value.data()); + glUniformMatrix2x3fv(location, count, GL_FALSE, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 3, GLfloat>& value) { - glProgramUniformMatrix2x3fv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 3, GLfloat>* const values) { + glProgramUniformMatrix2x3fv(_id, location, count, GL_FALSE, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 2, GLfloat>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 2, GLfloat>* const values) { use(); - glUniformMatrix3x2fv(location, 1, GL_FALSE, value.data()); + glUniformMatrix3x2fv(location, count, GL_FALSE, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 2, GLfloat>& value) { - glProgramUniformMatrix3x2fv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 2, GLfloat>* const values) { + glProgramUniformMatrix3x2fv(_id, location, count, GL_FALSE, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 4, GLfloat>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 4, GLfloat>* const values) { use(); - glUniformMatrix2x4fv(location, 1, GL_FALSE, value.data()); + glUniformMatrix2x4fv(location, count, GL_FALSE, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 4, GLfloat>& value) { - glProgramUniformMatrix2x4fv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 4, GLfloat>* const values) { + glProgramUniformMatrix2x4fv(_id, location, count, GL_FALSE, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 2, GLfloat>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 2, GLfloat>* const values) { use(); - glUniformMatrix4x2fv(location, 1, GL_FALSE, value.data()); + glUniformMatrix4x2fv(location, count, GL_FALSE, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 2, GLfloat>& value) { - glProgramUniformMatrix4x2fv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 2, GLfloat>* const values) { + glProgramUniformMatrix4x2fv(_id, location, count, GL_FALSE, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 4, GLfloat>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 4, GLfloat>* const values) { use(); - glUniformMatrix3x4fv(location, 1, GL_FALSE, value.data()); + glUniformMatrix3x4fv(location, count, GL_FALSE, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 4, GLfloat>& value) { - glProgramUniformMatrix3x4fv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 4, GLfloat>* const values) { + glProgramUniformMatrix3x4fv(_id, location, count, GL_FALSE, values[0].data()); } #endif -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 3, GLfloat>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 3, GLfloat>* const values) { use(); - glUniformMatrix4x3fv(location, 1, GL_FALSE, value.data()); + glUniformMatrix4x3fv(location, count, GL_FALSE, values[0].data()); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 3, GLfloat>& value) { - glProgramUniformMatrix4x3fv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 3, GLfloat>* const values) { + glProgramUniformMatrix4x3fv(_id, location, count, GL_FALSE, values[0].data()); } #endif #endif #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Matrix<2, GLdouble>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 2, GLdouble>* const values) { use(); - glUniformMatrix2dv(location, 1, GL_FALSE, value.data()); + glUniformMatrix2dv(location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Matrix<2, GLdouble>& value) { - glProgramUniformMatrix2dv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 2, GLdouble>* const values) { + glProgramUniformMatrix2dv(_id, location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Matrix<3, GLdouble>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 3, GLdouble>* const values) { use(); - glUniformMatrix3dv(location, 1, GL_FALSE, value.data()); + glUniformMatrix3dv(location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Matrix<3, GLdouble>& value) { - glProgramUniformMatrix3dv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 3, GLdouble>* const values) { + glProgramUniformMatrix3dv(_id, location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Matrix<4, GLdouble>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 4, GLdouble>* const values) { use(); - glUniformMatrix4dv(location, 1, GL_FALSE, value.data()); + glUniformMatrix4dv(location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Matrix<4, GLdouble>& value) { - glProgramUniformMatrix4dv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 4, GLdouble>* const values) { + glProgramUniformMatrix4dv(_id, location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 3, GLdouble>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 3, GLdouble>* const values) { use(); - glUniformMatrix2x3dv(location, 1, GL_FALSE, value.data()); + glUniformMatrix2x3dv(location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 3, GLdouble>& value) { - glProgramUniformMatrix2x3dv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 3, GLdouble>* const values) { + glProgramUniformMatrix2x3dv(_id, location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 2, GLdouble>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 2, GLdouble>* const values) { use(); - glUniformMatrix3x2dv(location, 1, GL_FALSE, value.data()); + glUniformMatrix3x2dv(location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 2, GLdouble>& value) { - glProgramUniformMatrix3x2dv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 2, GLdouble>* const values) { + glProgramUniformMatrix3x2dv(_id, location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 4, GLdouble>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 4, GLdouble>* const values) { use(); - glUniformMatrix2x4dv(location, 1, GL_FALSE, value.data()); + glUniformMatrix2x4dv(location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 4, GLdouble>& value) { - glProgramUniformMatrix2x4dv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 4, GLdouble>* const values) { + glProgramUniformMatrix2x4dv(_id, location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 2, GLdouble>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 2, GLdouble>* const values) { use(); - glUniformMatrix4x2dv(location, 1, GL_FALSE, value.data()); + glUniformMatrix4x2dv(location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 2, GLdouble>& value) { - glProgramUniformMatrix4x2dv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 2, GLdouble>* const values) { + glProgramUniformMatrix4x2dv(_id, location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 4, GLdouble>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 4, GLdouble>* const values) { use(); - glUniformMatrix3x4dv(location, 1, GL_FALSE, value.data()); + glUniformMatrix3x4dv(location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 4, GLdouble>& value) { - glProgramUniformMatrix3x4dv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 4, GLdouble>* const values) { + glProgramUniformMatrix3x4dv(_id, location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 3, GLdouble>& value) { +void AbstractShaderProgram::uniformImplementationDefault(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 3, GLdouble>* const values) { use(); - glUniformMatrix4x3dv(location, 1, GL_FALSE, value.data()); + glUniformMatrix4x3dv(location, count, GL_FALSE, values[0].data()); } -void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 3, GLdouble>& value) { - glProgramUniformMatrix4x3dv(_id, location, 1, GL_FALSE, value.data()); +void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 3, GLdouble>* const values) { + glProgramUniformMatrix4x3dv(_id, location, count, GL_FALSE, values[0].data()); } #endif @@ -600,7 +600,7 @@ std::size_t FloatAttribute::size(GLint components, DataType dataType) { #endif } - CORRADE_INTERNAL_ASSERT(false); + CORRADE_ASSERT_UNREACHABLE(); return 0; } @@ -618,7 +618,7 @@ std::size_t IntAttribute::size(GLint components, DataType dataType) { return 4*components; } - CORRADE_INTERNAL_ASSERT(false); + CORRADE_ASSERT_UNREACHABLE(); return 0; } #endif @@ -630,7 +630,7 @@ std::size_t DoubleAttribute::size(GLint components, DataType dataType) { return 8*components; } - CORRADE_INTERNAL_ASSERT(false); + CORRADE_ASSERT_UNREACHABLE(); return 0; } #endif @@ -665,7 +665,7 @@ std::size_t Attribute>::size(GLint components, DataType d #endif } - CORRADE_INTERNAL_ASSERT(false); + CORRADE_ASSERT_UNREACHABLE(); return 0; } diff --git a/src/AbstractShaderProgram.h b/src/AbstractShaderProgram.h index 38b4f4866..f4c51e81f 100644 --- a/src/AbstractShaderProgram.h +++ b/src/AbstractShaderProgram.h @@ -279,8 +279,6 @@ setUniform() documentation for more information. To achieve least state changes, set all uniforms in one run -- method chaining comes in handy. - -@todo Uniform arrays support */ class MAGNUM_EXPORT AbstractShaderProgram { friend class Context; @@ -678,275 +676,312 @@ class MAGNUM_EXPORT AbstractShaderProgram { /** * @brief Set uniform value - * @param location Uniform location (see uniformLocation()) + * @param location Uniform location * @param value Value * + * Convenience alternative for setting one value, see + * setUniform(Int, UnsignedInt, const Float*) for more information. + */ + #ifdef DOXYGEN_GENERATING_OUTPUT + template inline void setUniform(Int location, const T& value); + #else + inline void setUniform(Int location, Float value) { + setUniform(location, 1, &value); + } + inline void setUniform(Int location, Int value) { + setUniform(location, 1, &value); + } + #ifndef MAGNUM_TARGET_GLES2 + inline void setUniform(Int location, UnsignedInt value) { + setUniform(location, 1, &value); + } + #endif + #ifndef MAGNUM_TARGET_GLES + inline void setUniform(Int location, Double value) { + setUniform(location, 1, &value); + } + #endif + template inline void setUniform(Int location, const Math::Vector& value) { + setUniform(location, 1, &value); + } + template inline void setUniform(Int location, const Math::RectangularMatrix& value) { + setUniform(location, 1, &value); + } + #endif + + /** + * @brief Set uniform values + * @param location Uniform location + * @param count Value count + * @param values Values + * * If neither @extension{ARB,separate_shader_objects} nor * @extension{EXT,direct_state_access} is available, the shader is * marked for use before the operation. - * @see @fn_gl{UseProgram}, @fn_gl{Uniform} or `glProgramUniform()` - * from @extension{ARB,separate_shader_objects}/@extension{EXT,direct_state_access}. + * @see setUniform(Int, const T&), @fn_gl{UseProgram}, @fn_gl{Uniform} + * or `glProgramUniform()` from + * @extension{ARB,separate_shader_objects}/@extension{EXT,direct_state_access}. */ - inline void setUniform(Int location, Float value) { - (this->*uniform1fImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Float* values) { + (this->*uniform1fvImplementation)(location, count, values); } - /** @copydoc setUniform(Int, Float) */ - inline void setUniform(Int location, const Math::Vector<2, Float>& value) { - (this->*uniform2fvImplementation)(location, value); + /** @copydoc setUniform(Int, UnsignedInt, const Float*) */ + inline void setUniform(Int location, UnsignedInt count, const Math::Vector<2, Float>* values) { + (this->*uniform2fvImplementation)(location, count, values); } - /** @copydoc setUniform(Int, Float) */ - inline void setUniform(Int location, const Math::Vector<3, Float>& value) { - (this->*uniform3fvImplementation)(location, value); + /** @copydoc setUniform(Int, UnsignedInt, const Float*) */ + inline void setUniform(Int location, UnsignedInt count, const Math::Vector<3, Float>* values) { + (this->*uniform3fvImplementation)(location, count, values); } - /** @copydoc setUniform(Int, Float) */ - inline void setUniform(Int location, const Math::Vector<4, Float>& value) { - (this->*uniform4fvImplementation)(location, value); + /** @copydoc setUniform(Int, UnsignedInt, const Float*) */ + inline void setUniform(Int location, UnsignedInt count, const Math::Vector<4, Float>* values) { + (this->*uniform4fvImplementation)(location, count, values); } - /** @copydoc setUniform(Int, Float) */ - inline void setUniform(Int location, Int value) { - (this->*uniform1iImplementation)(location, value); + /** @copydoc setUniform(Int, UnsignedInt, const Float*) */ + inline void setUniform(Int location, UnsignedInt count, const Int* values) { + (this->*uniform1ivImplementation)(location, count, values); } - /** @copydoc setUniform(Int, Float) */ - inline void setUniform(Int location, const Math::Vector<2, Int>& value) { - (this->*uniform2ivImplementation)(location, value); + /** @copydoc setUniform(Int, UnsignedInt, const Float*) */ + inline void setUniform(Int location, UnsignedInt count, const Math::Vector<2, Int>* values) { + (this->*uniform2ivImplementation)(location, count, values); } - /** @copydoc setUniform(Int, Float) */ - inline void setUniform(Int location, const Math::Vector<3, Int>& value) { - (this->*uniform3ivImplementation)(location, value); + /** @copydoc setUniform(Int, UnsignedInt, const Float*) */ + inline void setUniform(Int location, UnsignedInt count, const Math::Vector<3, Int>* values) { + (this->*uniform3ivImplementation)(location, count, values); } - /** @copydoc setUniform(Int, Float) */ - inline void setUniform(Int location, const Math::Vector<4, Int>& value) { - (this->*uniform4ivImplementation)(location, value); + /** @copydoc setUniform(Int, UnsignedInt, const Float*) */ + inline void setUniform(Int location, UnsignedInt count, const Math::Vector<4, Int>* values) { + (this->*uniform4ivImplementation)(location, count, values); } #ifndef MAGNUM_TARGET_GLES2 /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl30 %Extension @extension{EXT,gpu_shader4} * @requires_gles30 Only signed integers are available in OpenGL ES 2.0. */ - inline void setUniform(Int location, UnsignedInt value) { - (this->*uniform1uiImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const UnsignedInt* values) { + (this->*uniform1uivImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl30 %Extension @extension{EXT,gpu_shader4} * @requires_gles30 Only signed integers are available in OpenGL ES 2.0. */ - inline void setUniform(Int location, const Math::Vector<2, UnsignedInt>& value) { - (this->*uniform2uivImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::Vector<2, UnsignedInt>* values) { + (this->*uniform2uivImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl30 %Extension @extension{EXT,gpu_shader4} * @requires_gles30 Only signed integers are available in OpenGL ES 2.0. */ - inline void setUniform(Int location, const Math::Vector<3, UnsignedInt>& value) { - (this->*uniform3uivImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::Vector<3, UnsignedInt>* values) { + (this->*uniform3uivImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl30 %Extension @extension{EXT,gpu_shader4} * @requires_gles30 Only signed integers are available in OpenGL ES 2.0. */ - inline void setUniform(Int location, const Math::Vector<4, UnsignedInt>& value) { - (this->*uniform4uivImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::Vector<4, UnsignedInt>* values) { + (this->*uniform4uivImplementation)(location, count, values); } #endif #ifndef MAGNUM_TARGET_GLES /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl Only floats are available in OpenGL ES. */ - inline void setUniform(Int location, Double value) { - (this->*uniform1dImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Double* values) { + (this->*uniform1dvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl Only floats are available in OpenGL ES. */ - inline void setUniform(Int location, const Math::Vector<2, Double>& value) { - (this->*uniform2dvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::Vector<2, Double>* values) { + (this->*uniform2dvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl Only floats are available in OpenGL ES. */ - inline void setUniform(Int location, const Math::Vector<3, Double>& value) { - (this->*uniform3dvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::Vector<3, Double>* values) { + (this->*uniform3dvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl Only floats are available in OpenGL ES. */ - inline void setUniform(Int location, const Math::Vector<4, Double>& value) { - (this->*uniform4dvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::Vector<4, Double>* values) { + (this->*uniform4dvImplementation)(location, count, values); } #endif - /** @copydoc setUniform(Int, Float) */ - inline void setUniform(Int location, const Math::Matrix<2, Float>& value) { - (this->*uniformMatrix2fvImplementation)(location, value); + /** @copydoc setUniform(Int, UnsignedInt, const Float*) */ + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 2, Float>* values) { + (this->*uniformMatrix2fvImplementation)(location, count, values); } - /** @copydoc setUniform(Int, Float) */ - inline void setUniform(Int location, const Math::Matrix<3, Float>& value) { - (this->*uniformMatrix3fvImplementation)(location, value); + /** @copydoc setUniform(Int, UnsignedInt, const Float*) */ + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 3, Float>* values) { + (this->*uniformMatrix3fvImplementation)(location, count, values); } - /** @copydoc setUniform(Int, Float) */ - inline void setUniform(Int location, const Math::Matrix<4, Float>& value) { - (this->*uniformMatrix4fvImplementation)(location, value); + /** @copydoc setUniform(Int, UnsignedInt, const Float*) */ + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 4, Float>* values) { + (this->*uniformMatrix4fvImplementation)(location, count, values); } #ifndef MAGNUM_TARGET_GLES2 /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gles30 Only square matrices are available in OpenGL ES 2.0. */ - inline void setUniform(Int location, const Math::RectangularMatrix<2, 3, Float>& value) { - (this->*uniformMatrix2x3fvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 3, Float>* values) { + (this->*uniformMatrix2x3fvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gles30 Only square matrices are available in OpenGL ES 2.0. */ - inline void setUniform(Int location, const Math::RectangularMatrix<3, 2, Float>& value) { - (this->*uniformMatrix3x2fvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 2, Float>* values) { + (this->*uniformMatrix3x2fvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gles30 Only square matrices are available in OpenGL ES 2.0. */ - inline void setUniform(Int location, const Math::RectangularMatrix<2, 4, Float>& value) { - (this->*uniformMatrix2x4fvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 4, Float>* values) { + (this->*uniformMatrix2x4fvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gles30 Only square matrices are available in OpenGL ES 2.0. */ - inline void setUniform(Int location, const Math::RectangularMatrix<4, 2, Float>& value) { - (this->*uniformMatrix4x2fvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 2, Float>* values) { + (this->*uniformMatrix4x2fvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gles30 Only square matrices are available in OpenGL ES 2.0. */ - inline void setUniform(Int location, const Math::RectangularMatrix<3, 4, Float>& value) { - (this->*uniformMatrix3x4fvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 4, Float>* values) { + (this->*uniformMatrix3x4fvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gles30 Only square matrices are available in OpenGL ES 2.0. */ - inline void setUniform(Int location, const Math::RectangularMatrix<4, 3, Float>& value) { - (this->*uniformMatrix4x3fvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 3, Float>* values) { + (this->*uniformMatrix4x3fvImplementation)(location, count, values); } #endif #ifndef MAGNUM_TARGET_GLES /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl Only floats are available in OpenGL ES. */ - inline void setUniform(Int location, const Math::Matrix<2, Double>& value) { - (this->*uniformMatrix2dvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 2, Double>* values) { + (this->*uniformMatrix2dvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl Only floats are available in OpenGL ES. */ - inline void setUniform(Int location, const Math::Matrix<3, Double>& value) { - (this->*uniformMatrix3dvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 3, Double>* values) { + (this->*uniformMatrix3dvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl Only floats are available in OpenGL ES. */ - inline void setUniform(Int location, const Math::Matrix<4, Double>& value) { - (this->*uniformMatrix4dvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 4, Double>* values) { + (this->*uniformMatrix4dvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl Only floats are available in OpenGL ES. */ - inline void setUniform(Int location, const Math::RectangularMatrix<2, 3, Double>& value) { - (this->*uniformMatrix2x3dvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 3, Double>* values) { + (this->*uniformMatrix2x3dvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl Only floats are available in OpenGL ES. */ - inline void setUniform(Int location, const Math::RectangularMatrix<3, 2, Double>& value) { - (this->*uniformMatrix3x2dvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 2, Double>* values) { + (this->*uniformMatrix3x2dvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl Only floats are available in OpenGL ES. */ - inline void setUniform(Int location, const Math::RectangularMatrix<2, 4, Double>& value) { - (this->*uniformMatrix2x4dvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 4, Double>* values) { + (this->*uniformMatrix2x4dvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl Only floats are available in OpenGL ES. */ - inline void setUniform(Int location, const Math::RectangularMatrix<4, 2, Double>& value) { - (this->*uniformMatrix4x2dvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 2, Double>* values) { + (this->*uniformMatrix4x2dvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl Only floats are available in OpenGL ES. */ - inline void setUniform(Int location, const Math::RectangularMatrix<3, 4, Double>& value) { - (this->*uniformMatrix3x4dvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 4, Double>* values) { + (this->*uniformMatrix3x4dvImplementation)(location, count, values); } /** - * @copydoc setUniform(Int, Float) + * @copydoc setUniform(Int, UnsignedInt, const Float*) * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl Only floats are available in OpenGL ES. */ - inline void setUniform(Int location, const Math::RectangularMatrix<4, 3, Double>& value) { - (this->*uniformMatrix4x3dvImplementation)(location, value); + inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 3, Double>* values) { + (this->*uniformMatrix4x3dvImplementation)(location, count, values); } #endif @@ -959,144 +994,144 @@ class MAGNUM_EXPORT AbstractShaderProgram { static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context* context); - typedef void(AbstractShaderProgram::*Uniform1fImplementation)(GLint, GLfloat); - typedef void(AbstractShaderProgram::*Uniform2fvImplementation)(GLint, const Math::Vector<2, GLfloat>&); - typedef void(AbstractShaderProgram::*Uniform3fvImplementation)(GLint, const Math::Vector<3, GLfloat>&); - typedef void(AbstractShaderProgram::*Uniform4fvImplementation)(GLint, const Math::Vector<4, GLfloat>&); - typedef void(AbstractShaderProgram::*Uniform1iImplementation)(GLint, GLint); - typedef void(AbstractShaderProgram::*Uniform2ivImplementation)(GLint, const Math::Vector<2, GLint>&); - typedef void(AbstractShaderProgram::*Uniform3ivImplementation)(GLint, const Math::Vector<3, GLint>&); - typedef void(AbstractShaderProgram::*Uniform4ivImplementation)(GLint, const Math::Vector<4, GLint>&); + typedef void(AbstractShaderProgram::*Uniform1fvImplementation)(GLint, GLsizei, const GLfloat*); + typedef void(AbstractShaderProgram::*Uniform2fvImplementation)(GLint, GLsizei, const Math::Vector<2, GLfloat>*); + typedef void(AbstractShaderProgram::*Uniform3fvImplementation)(GLint, GLsizei, const Math::Vector<3, GLfloat>*); + typedef void(AbstractShaderProgram::*Uniform4fvImplementation)(GLint, GLsizei, const Math::Vector<4, GLfloat>*); + typedef void(AbstractShaderProgram::*Uniform1ivImplementation)(GLint, GLsizei, const GLint*); + typedef void(AbstractShaderProgram::*Uniform2ivImplementation)(GLint, GLsizei, const Math::Vector<2, GLint>*); + typedef void(AbstractShaderProgram::*Uniform3ivImplementation)(GLint, GLsizei, const Math::Vector<3, GLint>*); + typedef void(AbstractShaderProgram::*Uniform4ivImplementation)(GLint, GLsizei, const Math::Vector<4, GLint>*); #ifndef MAGNUM_TARGET_GLES2 - typedef void(AbstractShaderProgram::*Uniform1uiImplementation)(GLint, GLuint); - typedef void(AbstractShaderProgram::*Uniform2uivImplementation)(GLint, const Math::Vector<2, GLuint>&); - typedef void(AbstractShaderProgram::*Uniform3uivImplementation)(GLint, const Math::Vector<3, GLuint>&); - typedef void(AbstractShaderProgram::*Uniform4uivImplementation)(GLint, const Math::Vector<4, GLuint>&); + typedef void(AbstractShaderProgram::*Uniform1uivImplementation)(GLint, GLsizei, const GLuint*); + typedef void(AbstractShaderProgram::*Uniform2uivImplementation)(GLint, GLsizei, const Math::Vector<2, GLuint>*); + typedef void(AbstractShaderProgram::*Uniform3uivImplementation)(GLint, GLsizei, const Math::Vector<3, GLuint>*); + typedef void(AbstractShaderProgram::*Uniform4uivImplementation)(GLint, GLsizei, const Math::Vector<4, GLuint>*); #endif #ifndef MAGNUM_TARGET_GLES - typedef void(AbstractShaderProgram::*Uniform1dImplementation)(GLint, GLdouble); - typedef void(AbstractShaderProgram::*Uniform2dvImplementation)(GLint, const Math::Vector<2, GLdouble>&); - typedef void(AbstractShaderProgram::*Uniform3dvImplementation)(GLint, const Math::Vector<3, GLdouble>&); - typedef void(AbstractShaderProgram::*Uniform4dvImplementation)(GLint, const Math::Vector<4, GLdouble>&); + typedef void(AbstractShaderProgram::*Uniform1dvImplementation)(GLint, GLsizei, const GLdouble*); + typedef void(AbstractShaderProgram::*Uniform2dvImplementation)(GLint, GLsizei, const Math::Vector<2, GLdouble>*); + typedef void(AbstractShaderProgram::*Uniform3dvImplementation)(GLint, GLsizei, const Math::Vector<3, GLdouble>*); + typedef void(AbstractShaderProgram::*Uniform4dvImplementation)(GLint, GLsizei, const Math::Vector<4, GLdouble>*); #endif - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLfloat value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<2, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<3, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<4, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLint value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<2, GLint>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<3, GLint>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<4, GLint>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const GLfloat* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::Vector<2, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::Vector<3, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::Vector<4, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const GLint* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::Vector<2, GLint>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::Vector<3, GLint>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::Vector<4, GLint>* values); #ifndef MAGNUM_TARGET_GLES2 - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLuint value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<2, GLuint>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<3, GLuint>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<4, GLuint>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const GLuint* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::Vector<2, GLuint>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::Vector<3, GLuint>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::Vector<4, GLuint>* values); #endif #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLdouble value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<2, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<3, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<4, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLfloat value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<2, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<3, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<4, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLint value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<2, GLint>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<3, GLint>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<4, GLint>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLuint value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<2, GLuint>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<3, GLuint>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<4, GLuint>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLdouble value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<2, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<3, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<4, GLdouble>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const GLdouble* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::Vector<2, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::Vector<3, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::Vector<4, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const GLfloat* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<2, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<3, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<4, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const GLint* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<2, GLint>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<3, GLint>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<4, GLint>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const GLuint* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<2, GLuint>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<3, GLuint>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<4, GLuint>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const GLdouble* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<2, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<3, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<4, GLdouble>* values); #endif - static Uniform1fImplementation uniform1fImplementation; + static Uniform1fvImplementation uniform1fvImplementation; static Uniform2fvImplementation uniform2fvImplementation; static Uniform3fvImplementation uniform3fvImplementation; static Uniform4fvImplementation uniform4fvImplementation; - static Uniform1iImplementation uniform1iImplementation; + static Uniform1ivImplementation uniform1ivImplementation; static Uniform2ivImplementation uniform2ivImplementation; static Uniform3ivImplementation uniform3ivImplementation; static Uniform4ivImplementation uniform4ivImplementation; #ifndef MAGNUM_TARGET_GLES2 - static Uniform1uiImplementation uniform1uiImplementation; + static Uniform1uivImplementation uniform1uivImplementation; static Uniform2uivImplementation uniform2uivImplementation; static Uniform3uivImplementation uniform3uivImplementation; static Uniform4uivImplementation uniform4uivImplementation; #endif #ifndef MAGNUM_TARGET_GLES - static Uniform1dImplementation uniform1dImplementation; + static Uniform1dvImplementation uniform1dvImplementation; static Uniform2dvImplementation uniform2dvImplementation; static Uniform3dvImplementation uniform3dvImplementation; static Uniform4dvImplementation uniform4dvImplementation; #endif - typedef void(AbstractShaderProgram::*UniformMatrix2fvImplementation)(GLint, const Math::Matrix<2, GLfloat>&); - typedef void(AbstractShaderProgram::*UniformMatrix3fvImplementation)(GLint, const Math::Matrix<3, GLfloat>&); - typedef void(AbstractShaderProgram::*UniformMatrix4fvImplementation)(GLint, const Math::Matrix<4, GLfloat>&); + typedef void(AbstractShaderProgram::*UniformMatrix2fvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<2, 2, GLfloat>*); + typedef void(AbstractShaderProgram::*UniformMatrix3fvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<3, 3, GLfloat>*); + typedef void(AbstractShaderProgram::*UniformMatrix4fvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<4, 4, GLfloat>*); #ifndef MAGNUM_TARGET_GLES2 - typedef void(AbstractShaderProgram::*UniformMatrix2x3fvImplementation)(GLint, const Math::RectangularMatrix<2, 3, GLfloat>&); - typedef void(AbstractShaderProgram::*UniformMatrix3x2fvImplementation)(GLint, const Math::RectangularMatrix<3, 2, GLfloat>&); - typedef void(AbstractShaderProgram::*UniformMatrix2x4fvImplementation)(GLint, const Math::RectangularMatrix<2, 4, GLfloat>&); - typedef void(AbstractShaderProgram::*UniformMatrix4x2fvImplementation)(GLint, const Math::RectangularMatrix<4, 2, GLfloat>&); - typedef void(AbstractShaderProgram::*UniformMatrix3x4fvImplementation)(GLint, const Math::RectangularMatrix<3, 4, GLfloat>&); - typedef void(AbstractShaderProgram::*UniformMatrix4x3fvImplementation)(GLint, const Math::RectangularMatrix<4, 3, GLfloat>&); + typedef void(AbstractShaderProgram::*UniformMatrix2x3fvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<2, 3, GLfloat>*); + typedef void(AbstractShaderProgram::*UniformMatrix3x2fvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<3, 2, GLfloat>*); + typedef void(AbstractShaderProgram::*UniformMatrix2x4fvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<2, 4, GLfloat>*); + typedef void(AbstractShaderProgram::*UniformMatrix4x2fvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<4, 2, GLfloat>*); + typedef void(AbstractShaderProgram::*UniformMatrix3x4fvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<3, 4, GLfloat>*); + typedef void(AbstractShaderProgram::*UniformMatrix4x3fvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<4, 3, GLfloat>*); #endif #ifndef MAGNUM_TARGET_GLES - typedef void(AbstractShaderProgram::*UniformMatrix2dvImplementation)(GLint, const Math::Matrix<2, GLdouble>&); - typedef void(AbstractShaderProgram::*UniformMatrix3dvImplementation)(GLint, const Math::Matrix<3, GLdouble>&); - typedef void(AbstractShaderProgram::*UniformMatrix4dvImplementation)(GLint, const Math::Matrix<4, GLdouble>&); - typedef void(AbstractShaderProgram::*UniformMatrix2x3dvImplementation)(GLint, const Math::RectangularMatrix<2, 3, GLdouble>&); - typedef void(AbstractShaderProgram::*UniformMatrix3x2dvImplementation)(GLint, const Math::RectangularMatrix<3, 2, GLdouble>&); - typedef void(AbstractShaderProgram::*UniformMatrix2x4dvImplementation)(GLint, const Math::RectangularMatrix<2, 4, GLdouble>&); - typedef void(AbstractShaderProgram::*UniformMatrix4x2dvImplementation)(GLint, const Math::RectangularMatrix<4, 2, GLdouble>&); - typedef void(AbstractShaderProgram::*UniformMatrix3x4dvImplementation)(GLint, const Math::RectangularMatrix<3, 4, GLdouble>&); - typedef void(AbstractShaderProgram::*UniformMatrix4x3dvImplementation)(GLint, const Math::RectangularMatrix<4, 3, GLdouble>&); + typedef void(AbstractShaderProgram::*UniformMatrix2dvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<2, 2, GLdouble>*); + typedef void(AbstractShaderProgram::*UniformMatrix3dvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<3, 3, GLdouble>*); + typedef void(AbstractShaderProgram::*UniformMatrix4dvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<4, 4, GLdouble>*); + typedef void(AbstractShaderProgram::*UniformMatrix2x3dvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<2, 3, GLdouble>*); + typedef void(AbstractShaderProgram::*UniformMatrix3x2dvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<3, 2, GLdouble>*); + typedef void(AbstractShaderProgram::*UniformMatrix2x4dvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<2, 4, GLdouble>*); + typedef void(AbstractShaderProgram::*UniformMatrix4x2dvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<4, 2, GLdouble>*); + typedef void(AbstractShaderProgram::*UniformMatrix3x4dvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<3, 4, GLdouble>*); + typedef void(AbstractShaderProgram::*UniformMatrix4x3dvImplementation)(GLint, GLsizei, const Math::RectangularMatrix<4, 3, GLdouble>*); #endif - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Matrix<2, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Matrix<3, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Matrix<4, GLfloat>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<2, 2, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<3, 3, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<4, 4, GLfloat>* values); #ifndef MAGNUM_TARGET_GLES2 - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 3, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 2, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 4, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 2, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 4, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 3, GLfloat>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<2, 3, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<3, 2, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<2, 4, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<4, 2, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<3, 4, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<4, 3, GLfloat>* values); #endif #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Matrix<2, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Matrix<3, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Matrix<4, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 3, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 2, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 4, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 2, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 4, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 3, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Matrix<2, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Matrix<3, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Matrix<4, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 3, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 2, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 4, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 2, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 4, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 3, GLfloat>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Matrix<2, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Matrix<3, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Matrix<4, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 3, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 2, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 4, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 2, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 4, GLdouble>& value); - void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 3, GLdouble>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<2, 2, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<3, 3, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<4, 4, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<2, 3, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<3, 2, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<2, 4, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<4, 2, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<3, 4, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<4, 3, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<2, 2, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<3, 3, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<4, 4, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<2, 3, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<3, 2, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<2, 4, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<4, 2, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<3, 4, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<4, 3, GLfloat>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<2, 2, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<3, 3, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<4, 4, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<2, 3, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<3, 2, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<2, 4, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<4, 2, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<3, 4, GLdouble>* values); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<4, 3, GLdouble>* values); #endif static UniformMatrix2fvImplementation uniformMatrix2fvImplementation; static UniformMatrix3fvImplementation uniformMatrix3fvImplementation; diff --git a/src/Color.h b/src/Color.h index fadae7dd0..6625e4c0c 100644 --- a/src/Color.h +++ b/src/Color.h @@ -63,7 +63,7 @@ template inline typename std::enable_if::valu case 3: return {p, q, value}; case 4: return {t, p, value}; case 5: return {value, p, q}; - default: CORRADE_INTERNAL_ASSERT(false); + default: CORRADE_ASSERT_UNREACHABLE(); } } template inline typename std::enable_if::value, Color3>::type fromHSV(typename Color3::HSV hsv) { diff --git a/src/DebugTools/ForceRenderer.h b/src/DebugTools/ForceRenderer.h index 79e521ab4..7af657909 100644 --- a/src/DebugTools/ForceRenderer.h +++ b/src/DebugTools/ForceRenderer.h @@ -44,7 +44,7 @@ See ForceRenderer documentation for more information. */ class ForceRendererOptions { public: - inline constexpr ForceRendererOptions(): _size(1.0f) {} + inline constexpr ForceRendererOptions(): _color(1.0f), _size(1.0f) {} /** @brief Color of rendered arrow */ inline constexpr Color4<> color() const { return _color; } @@ -53,7 +53,7 @@ class ForceRendererOptions { * @brief Set color of rendered arrow * @return Pointer to self (for method chaining) * - * Default is black. + * Default is 100% opaque white. */ inline ForceRendererOptions* setColor(const Color4<>& color) { _color = color; diff --git a/src/DebugTools/Implementation/AbstractBoxRenderer.cpp b/src/DebugTools/Implementation/AbstractBoxRenderer.cpp index 011997e4f..60fb738a8 100644 --- a/src/DebugTools/Implementation/AbstractBoxRenderer.cpp +++ b/src/DebugTools/Implementation/AbstractBoxRenderer.cpp @@ -32,11 +32,11 @@ namespace Magnum { namespace DebugTools { namespace Implementation { AbstractBoxRenderer<2>::AbstractBoxRenderer(): AbstractShapeRenderer<2>("box2d", "box2d-vertices", {}) { - if(!mesh) this->createResources(Primitives::Square::wireframe()); + if(!wireframeMesh) this->createResources(Primitives::Square::wireframe()); } AbstractBoxRenderer<3>::AbstractBoxRenderer(): AbstractShapeRenderer<3>("box3d", "box3d-vertices", "box3d-indices") { - if(!mesh) this->createResources(Primitives::Cube::wireframe()); + if(!wireframeMesh) this->createResources(Primitives::Cube::wireframe()); } template class AbstractBoxRenderer<2>; diff --git a/src/DebugTools/Implementation/AbstractShapeRenderer.cpp b/src/DebugTools/Implementation/AbstractShapeRenderer.cpp index 06f9b30cd..b976cb576 100644 --- a/src/DebugTools/Implementation/AbstractShapeRenderer.cpp +++ b/src/DebugTools/Implementation/AbstractShapeRenderer.cpp @@ -90,19 +90,19 @@ template<> void create<3>(Trade::MeshData3D& data, Resource& meshResource, } template AbstractShapeRenderer::AbstractShapeRenderer(ResourceKey meshKey, ResourceKey vertexBufferKey, ResourceKey indexBufferKey) { - shader = ResourceManager::instance()->get>(shaderKey()); - mesh = ResourceManager::instance()->get(meshKey); + wireframeShader = ResourceManager::instance()->get>(shaderKey()); + wireframeMesh = ResourceManager::instance()->get(meshKey); vertexBuffer = ResourceManager::instance()->get(vertexBufferKey); indexBuffer = ResourceManager::instance()->get(indexBufferKey); - if(!shader) ResourceManager::instance()->set(shaderKey(), + if(!wireframeShader) ResourceManager::instance()->set(shaderKey(), new Shaders::FlatShader, ResourceDataState::Final, ResourcePolicy::Resident); } template AbstractShapeRenderer::~AbstractShapeRenderer() {} template void AbstractShapeRenderer::createResources(typename MeshData::Type data) { - create(data, this->mesh, this->vertexBuffer, this->indexBuffer); + create(data, this->wireframeMesh, this->vertexBuffer, this->indexBuffer); } template class AbstractShapeRenderer<2>; diff --git a/src/DebugTools/Implementation/AbstractShapeRenderer.h b/src/DebugTools/Implementation/AbstractShapeRenderer.h index 16f7f6606..25105f6c4 100644 --- a/src/DebugTools/Implementation/AbstractShapeRenderer.h +++ b/src/DebugTools/Implementation/AbstractShapeRenderer.h @@ -49,8 +49,8 @@ template class AbstractShapeRenderer { /* Call only if the mesh resource isn't already present */ void createResources(typename MeshData::Type data); - Resource> shader; - Resource mesh; + Resource> wireframeShader; + Resource wireframeMesh; private: Resource indexBuffer, vertexBuffer; diff --git a/src/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp b/src/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp index 9ef7904d5..4072650b5 100644 --- a/src/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp +++ b/src/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp @@ -34,12 +34,12 @@ namespace Magnum { namespace DebugTools { namespace Implementation { template AxisAlignedBoxRenderer::AxisAlignedBoxRenderer(Physics::AxisAlignedBox& axisAlignedBox): axisAlignedBox(axisAlignedBox) {} template void AxisAlignedBoxRenderer::draw(Resource& options, const typename DimensionTraits::MatrixType& projectionMatrix) { - this->shader->setTransformationProjectionMatrix(projectionMatrix* + this->wireframeShader->setTransformationProjectionMatrix(projectionMatrix* DimensionTraits::MatrixType::translation((axisAlignedBox.transformedMin()+axisAlignedBox.transformedMax())/2)* DimensionTraits::MatrixType::scaling(axisAlignedBox.transformedMax()-axisAlignedBox.transformedMin())) ->setColor(options->color()) ->use(); - this->mesh->draw(); + this->wireframeMesh->draw(); } template class AxisAlignedBoxRenderer<2>; diff --git a/src/DebugTools/Implementation/BoxRenderer.cpp b/src/DebugTools/Implementation/BoxRenderer.cpp index d9a34c62d..4e0bcb9fd 100644 --- a/src/DebugTools/Implementation/BoxRenderer.cpp +++ b/src/DebugTools/Implementation/BoxRenderer.cpp @@ -34,10 +34,10 @@ namespace Magnum { namespace DebugTools { namespace Implementation { template BoxRenderer::BoxRenderer(Physics::Box& box): box(box) {} template void BoxRenderer::draw(Resource& options, const typename DimensionTraits::MatrixType& projectionMatrix) { - this->shader->setTransformationProjectionMatrix(projectionMatrix*box.transformedTransformation()) + this->wireframeShader->setTransformationProjectionMatrix(projectionMatrix*box.transformedTransformation()) ->setColor(options->color()) ->use(); - this->mesh->draw(); + this->wireframeMesh->draw(); } template class BoxRenderer<2>; diff --git a/src/DebugTools/Implementation/LineSegmentRenderer.cpp b/src/DebugTools/Implementation/LineSegmentRenderer.cpp index c9a0240c8..900b96055 100644 --- a/src/DebugTools/Implementation/LineSegmentRenderer.cpp +++ b/src/DebugTools/Implementation/LineSegmentRenderer.cpp @@ -51,15 +51,15 @@ namespace { } template LineSegmentRenderer::LineSegmentRenderer(Physics::Line& line): AbstractShapeRenderer(meshKey(), vertexBufferKey(), {}), line(line) { - if(!this->mesh) this->createResources(meshData()); + if(!this->wireframeMesh) this->createResources(meshData()); } template void LineSegmentRenderer::draw(Resource& options, const typename DimensionTraits::MatrixType& projectionMatrix) { - this->shader->setTransformationProjectionMatrix(projectionMatrix* + this->wireframeShader->setTransformationProjectionMatrix(projectionMatrix* Implementation::lineSegmentRendererTransformation(line.transformedA(), line.transformedB())) ->setColor(options->color()) ->use(); - this->mesh->draw(); + this->wireframeMesh->draw(); } template class LineSegmentRenderer<2>; diff --git a/src/DebugTools/Implementation/PointRenderer.cpp b/src/DebugTools/Implementation/PointRenderer.cpp index c414813f2..31283541a 100644 --- a/src/DebugTools/Implementation/PointRenderer.cpp +++ b/src/DebugTools/Implementation/PointRenderer.cpp @@ -49,17 +49,17 @@ namespace { } template PointRenderer::PointRenderer(Physics::Point& point): AbstractShapeRenderer(meshKey(), vertexBufferKey(), {}), point(point) { - if(!this->mesh) this->createResources(meshData()); + if(!this->wireframeMesh) this->createResources(meshData()); } template void PointRenderer::draw(Resource& options, const typename DimensionTraits::MatrixType& projectionMatrix) { /* Half scale, because the point is 2x2(x2) */ - this->shader->setTransformationProjectionMatrix(projectionMatrix* + this->wireframeShader->setTransformationProjectionMatrix(projectionMatrix* DimensionTraits::MatrixType::translation(point.transformedPosition())* DimensionTraits::MatrixType::scaling(typename DimensionTraits::VectorType(options->pointSize()/2))) ->setColor(options->color()) ->use(); - this->mesh->draw(); + this->wireframeMesh->draw(); } template class PointRenderer<2>; diff --git a/src/DebugTools/Implementation/SphereRenderer.cpp b/src/DebugTools/Implementation/SphereRenderer.cpp index 60b27c880..be6f8d2f5 100644 --- a/src/DebugTools/Implementation/SphereRenderer.cpp +++ b/src/DebugTools/Implementation/SphereRenderer.cpp @@ -34,18 +34,18 @@ namespace Magnum { namespace DebugTools { namespace Implementation { AbstractSphereRenderer<2>::AbstractSphereRenderer(): AbstractShapeRenderer<2>("sphere2d", "sphere2d-vertices", {}) { - if(!mesh) this->createResources(Primitives::Circle::wireframe(40)); + if(!wireframeMesh) createResources(Primitives::Circle::wireframe(40)); } template SphereRenderer::SphereRenderer(Physics::Sphere& sphere): sphere(sphere) {} template void SphereRenderer::draw(Resource& options, const typename DimensionTraits::MatrixType& projectionMatrix) { - this->shader->setTransformationProjectionMatrix(projectionMatrix* + this->wireframeShader->setTransformationProjectionMatrix(projectionMatrix* DimensionTraits::MatrixType::translation(sphere.transformedPosition())* DimensionTraits::MatrixType::scaling(typename DimensionTraits::VectorType(sphere.transformedRadius()))) ->setColor(options->color()) ->use(); - this->mesh->draw(); + this->wireframeMesh->draw(); } template class SphereRenderer<2>; diff --git a/src/DebugTools/ShapeRenderer.h b/src/DebugTools/ShapeRenderer.h index e1af8bf93..35c062915 100644 --- a/src/DebugTools/ShapeRenderer.h +++ b/src/DebugTools/ShapeRenderer.h @@ -57,7 +57,31 @@ See ShapeRenderer documentation for more information. */ class ShapeRendererOptions { public: - inline constexpr ShapeRendererOptions(): _pointSize(0.25f) {} + /** + * @brief Shape rendering mode + * + * @see setRenderMode() + */ + enum class RenderMode: UnsignedByte { + Wireframe, + Solid + }; + + inline constexpr ShapeRendererOptions(): _color(1.0f), _pointSize(0.25f), _renderMode(RenderMode::Wireframe) {} + + /** @brief Shape rendering mode */ + inline constexpr RenderMode renderMode() const { return _renderMode; } + + /** + * @brief Set shape rendering mode + * @return Pointer to self (for method chaining) + * + * Default is @ref RenderMode "RenderMode::Wireframe". + */ + inline ShapeRendererOptions* setRenderMode(RenderMode mode) { + _renderMode = mode; + return this; + } /** @brief Color of rendered shape */ inline constexpr Color4<> color() const { return _color; } @@ -66,7 +90,7 @@ class ShapeRendererOptions { * @brief Set color of rendered shape * @return Pointer to self (for method chaining) * - * Default is black. + * Default is 100% opaque white. */ inline ShapeRendererOptions* setColor(const Color4<>& color) { _color = color; @@ -91,6 +115,7 @@ class ShapeRendererOptions { private: Color4<> _color; Float _pointSize; + RenderMode _renderMode; }; /** diff --git a/src/DebugTools/magnumDebugToolsVisibility.h b/src/DebugTools/magnumDebugToolsVisibility.h index 46eda28fd..d08f88d14 100644 --- a/src/DebugTools/magnumDebugToolsVisibility.h +++ b/src/DebugTools/magnumDebugToolsVisibility.h @@ -24,14 +24,12 @@ DEALINGS IN THE SOFTWARE. */ -#ifdef _WIN32 - #ifdef MagnumDebugTools_EXPORTS - #define MAGNUM_DEBUGTOOLS_EXPORT __declspec(dllexport) - #else - #define MAGNUM_DEBUGTOOLS_EXPORT __declspec(dllimport) - #endif +#include + +#ifdef MagnumDebugTools_EXPORTS + #define MAGNUM_DEBUGTOOLS_EXPORT CORRADE_VISIBILITY_EXPORT #else - #define MAGNUM_DEBUGTOOLS_EXPORT __attribute__ ((visibility ("default"))) + #define MAGNUM_DEBUGTOOLS_EXPORT CORRADE_VISIBILITY_IMPORT #endif #endif diff --git a/src/Implementation/BufferState.cpp b/src/Implementation/BufferState.cpp index 15ecc9a9e..e844f8991 100644 --- a/src/Implementation/BufferState.cpp +++ b/src/Implementation/BufferState.cpp @@ -71,7 +71,7 @@ std::size_t BufferState::indexForTarget(Buffer::Target target) { #endif } - CORRADE_INTERNAL_ASSERT(false); + CORRADE_ASSERT_UNREACHABLE(); } }} diff --git a/src/Implementation/FramebufferState.h b/src/Implementation/FramebufferState.h index 4d213425c..df7464cff 100644 --- a/src/Implementation/FramebufferState.h +++ b/src/Implementation/FramebufferState.h @@ -30,7 +30,7 @@ namespace Magnum { namespace Implementation { struct FramebufferState { - inline FramebufferState(): readBinding(0), drawBinding(0), renderbufferBinding(0) {} + inline constexpr FramebufferState(): readBinding(0), drawBinding(0), renderbufferBinding(0) {} GLuint readBinding, drawBinding, renderbufferBinding; Rectanglei viewport; diff --git a/src/Implementation/MeshState.h b/src/Implementation/MeshState.h index b2a18d756..b12b1c5ae 100644 --- a/src/Implementation/MeshState.h +++ b/src/Implementation/MeshState.h @@ -29,7 +29,7 @@ namespace Magnum { namespace Implementation { struct MeshState { - inline MeshState(): currentVAO(0) {} + inline constexpr MeshState(): currentVAO(0) {} GLuint currentVAO; }; diff --git a/src/Math/Algorithms/Test/SvdTest.cpp b/src/Math/Algorithms/Test/SvdTest.cpp index 3397f92f3..c46448fc4 100644 --- a/src/Math/Algorithms/Test/SvdTest.cpp +++ b/src/Math/Algorithms/Test/SvdTest.cpp @@ -107,14 +107,14 @@ void SvdTest::testFloat() { /* Test composition (single precision is not enough, test for similarity) */ Matrix8f u2(u[0], u[1], u[2], u[3], u[4], Vector8f(), Vector8f(), Vector8f()); Matrix5x8f w2 = Matrix5x8f::fromDiagonal(w); - CORRADE_VERIFY((u2*w2*v.transposed()-af).maxAbs() < 1.0e-5f); + CORRADE_VERIFY(Math::abs((u2*w2*v.transposed()-af).toVector()).max() < 1.0e-5f); /* Test that V is unitary */ CORRADE_COMPARE(v*v.transposed(), Matrix5f(Matrix5f::Identity)); CORRADE_COMPARE(v.transposed()*v, Matrix5f(Matrix5f::Identity)); /* Test W (single precision is not enough, test for similarity) */ - CORRADE_VERIFY((w-expectedf).maxAbs() < 1.0e-5f); + CORRADE_VERIFY(Math::abs(w-expectedf).max() < 1.0e-5f); } }}}} diff --git a/src/Math/Functions.h b/src/Math/Functions.h index b2625be6f..06477f181 100644 --- a/src/Math/Functions.h +++ b/src/Math/Functions.h @@ -126,7 +126,7 @@ perform the operations component-wise. /** @brief Minimum -@see min(), clamp() +@see min(), clamp(), Vector::min() */ #ifdef DOXYGEN_GENERATING_OUTPUT template inline T min(T a, T b); @@ -145,7 +145,7 @@ template inline Vector min(const Vector inline T max(const T& a, const T& b); @@ -197,7 +197,11 @@ template Vector abs(const Vector& a } #endif -/** @brief Square root */ +/** +@brief Square root + +@see sqrtInverted(), Vector::length() +*/ #ifdef DOXYGEN_GENERATING_OUTPUT template inline T sqrt(const T& a); #else @@ -212,6 +216,25 @@ template Vector sqrt(const Vector& } #endif +/** +@brief Inverse square root + +@see sqrt(), Vector::lengthInverted() +*/ +#ifdef DOXYGEN_GENERATING_OUTPUT +template inline T sqrtInverted(const T& a); +#else +template inline typename std::enable_if::value, T>::type sqrtInverted(T a) { + return T(1)/std::sqrt(a); +} +template Vector sqrtInverted(const Vector& a) { + Vector out; + for(std::size_t i = 0; i != size; ++i) + out[i] = T(1)/std::sqrt(a[i]); + return out; +} +#endif + /** @brief Clamp value @@ -257,6 +280,22 @@ template inline Vector lerp(const V } #endif +/** +@brief Fused multiply-add + +Computes and returns @f$ ab + c @f$. +*/ +#ifdef DOXYGEN_GENERATING_OUTPUT +template inline T fma(const T& a, const T& b, const T& c); +#else +template inline typename std::enable_if::value, T>::type fma(T a, T b, T c) { + return std::fma(a, b, c); +} +template inline Vector fma(const Vector& a, const Vector& b, const Vector& c) { + return a*b + c; +} +#endif + /** @brief Normalize integral value diff --git a/src/Math/Geometry/Intersection.h b/src/Math/Geometry/Intersection.h index 9d3bff5c7..35adfe578 100644 --- a/src/Math/Geometry/Intersection.h +++ b/src/Math/Geometry/Intersection.h @@ -37,38 +37,91 @@ class Intersection { public: Intersection() = delete; + /** + * @brief %Intersection of two line segments in 2D + * @param p Starting point of first line segment + * @param r Direction of first line segment + * @param q Starting point of second line segment + * @param s Direction of second line segment + * @return %Intersection point positions `t`, `u` on both lines, NaN if + * the lines are collinear or infinity if they are parallel. + * %Intersection point can be then computed with `p + t*r` or + * `q + u*s`. If `t` is in range @f$ [ 0 ; 1 ] @f$, the + * intersection is inside the line segment defined by `p` and + * `p + r`, if `u` is in range @f$ [ 0 ; 1 ] @f$, the intersection + * is inside the line segment defined by `q` and `q + s`. + * + * The two lines intersect if **t** and **u** exist such that: @f[ + * \boldsymbol p + t \boldsymbol r = \boldsymbol q + u \boldsymbol s + * @f] + * Crossing both sides with **s**, distributing the cross product and + * eliminating @f$ \boldsymbol s \times \boldsymbol s = 0 @f$, then + * solving for **t** and similarly for **u**: @f[ + * \begin{array}{rcl} + * (\boldsymbol p + t \boldsymbol r) \times s & = & (\boldsymbol q + u \boldsymbol s) \times s \\ + * t (\boldsymbol r \times s) & = & (\boldsymbol q - \boldsymbol p) \times s \\ + * t & = & \cfrac{(\boldsymbol q - \boldsymbol p) \times s}{\boldsymbol r \times \boldsymbol s} \\ + * u & = & \cfrac{(\boldsymbol q - \boldsymbol p) \times r}{\boldsymbol r \times \boldsymbol s} + * \end{array} + * @f] + * + * See also lineSegmentLine() which computes only **t**, which is + * useful if you don't need to test that the intersection lies inside + * line segment defined by `q` and `q + s`. + */ + template static std::pair lineSegmentLineSegment(const Vector2& p, const Vector2& r, const Vector2& q, const Vector2& s) { + const Vector2 qp = q - p; + const T rs = Vector2::cross(r, s); + return {Vector2::cross(qp, s)/rs, + Vector2::cross(qp, r)/rs}; + } + + /** + * @brief %Intersection of line segment and line in 2D + * @param p Starting point of first line segment + * @param r Direction of first line segment + * @param q Starting point of second line + * @param s Direction of second line + * @return %Intersection point position `t` on first line, NaN if the + * lines are collinear or infinity if they are parallel. + * %Intersection point can be then with `p + t*r`. If returned + * value is in range @f$ [ 0 ; 1 ] @f$, the intersection is inside + * the line segment defined by `p` and `p + r`. + * + * Unlike lineSegmentLineSegment() computes only **t**. + */ + template static T lineSegmentLine(const Vector2& p, const Vector2& r, const Vector2& q, const Vector2& s) { + return Vector2::cross(q - p, s)/Vector2::cross(r, s); + } + /** * @brief %Intersection of a plane and line * @param planePosition Plane position * @param planeNormal Plane normal - * @param a Starting point of the line - * @param b Ending point of the line - * @return %Intersection point position, NaN if the line lies on the - * plane or infinity if the intersection doesn't exist. %Intersection - * point can be computed from the position with `a+intersection(...)*b`. - * If returned value is in range @f$ [ 0 ; 1 ] @f$, the intersection - * is inside the line segment defined by `a` and `b`. + * @param p Starting point of the line + * @param r Direction of the line + * @return %Intersection point position `t` on the line, NaN if the + * line lies on the plane or infinity if the intersection doesn't + * exist. %Intersection point can be then computed from with + * `p + t*r`. If returned value is in range @f$ [ 0 ; 1 ] @f$, the + * intersection is inside the line segment defined by `p` and `r`. * * First the parameter *f* of parametric equation of the plane * is computed from plane normal **n** and plane position: @f[ * \begin{pmatrix} n_0 \\ n_1 \\ n_2 \end{pmatrix} \cdot * \begin{pmatrix} x \\ y \\ z \end{pmatrix} - f = 0 * @f] - * Using plane normal **n**, parameter *f* and points **a** and **b**, - * value of *t* is computed and returned. @f[ + * Using plane normal **n**, parameter *f* and line defined by **p** + * and **r**, value of *t* is computed and returned. @f[ * \begin{array}{rcl} - * \Delta \boldsymbol b & = & \boldsymbol b - \boldsymbol a \\ - * f & = & \boldsymbol n \cdot (\boldsymbol a + \Delta \boldsymbol b \cdot t) \\ - * \Rightarrow t & = & \cfrac{f - \boldsymbol n \cdot \boldsymbol a}{\boldsymbol n \cdot \Delta \boldsymbol b} + * f & = & \boldsymbol n \cdot (\boldsymbol p + t \boldsymbol r) \\ + * \Rightarrow t & = & \cfrac{f - \boldsymbol n \cdot \boldsymbol p}{\boldsymbol n \cdot \boldsymbol r} * \end{array} * @f] */ - template static T planeLine(const Vector3& planePosition, const Vector3& planeNormal, const Vector3& a, const Vector3& b) { - /* Compute f from normal and plane position */ - T f = Vector3::dot(planePosition, planeNormal); - - /* Compute t */ - return (f-Vector3::dot(planeNormal, a))/Vector3::dot(planeNormal, b-a); + template static T planeLine(const Vector3& planePosition, const Vector3& planeNormal, const Vector3& p, const Vector3& r) { + const T f = Vector3::dot(planePosition, planeNormal); + return (f-Vector3::dot(planeNormal, p))/Vector3::dot(planeNormal, r); } }; diff --git a/src/Math/Geometry/Test/CMakeLists.txt b/src/Math/Geometry/Test/CMakeLists.txt index e60e23aa3..21fcaedb2 100644 --- a/src/Math/Geometry/Test/CMakeLists.txt +++ b/src/Math/Geometry/Test/CMakeLists.txt @@ -23,5 +23,5 @@ # corrade_add_test(MathGeometryDistanceTest DistanceTest.cpp) -corrade_add_test(MathGeometryIntersectionTest IntersectionTest.cpp) +corrade_add_test(MathGeometryIntersectionTest IntersectionTest.cpp LIBRARIES MagnumMathTestLib) corrade_add_test(MathGeometryRectangleTest RectangleTest.cpp LIBRARIES MagnumMathTestLib) diff --git a/src/Math/Geometry/Test/IntersectionTest.cpp b/src/Math/Geometry/Test/IntersectionTest.cpp index c70f48747..db23f96f8 100644 --- a/src/Math/Geometry/Test/IntersectionTest.cpp +++ b/src/Math/Geometry/Test/IntersectionTest.cpp @@ -22,8 +22,8 @@ DEALINGS IN THE SOFTWARE. */ -#include #include +#include #include "Math/Geometry/Intersection.h" @@ -34,33 +34,68 @@ class IntersectionTest: public Corrade::TestSuite::Tester { IntersectionTest(); void planeLine(); + void lineLine(); }; +typedef Math::Vector2 Vector2; typedef Math::Vector3 Vector3; IntersectionTest::IntersectionTest() { - addTests({&IntersectionTest::planeLine}); + addTests({&IntersectionTest::planeLine, + &IntersectionTest::lineLine}); } void IntersectionTest::planeLine() { - Vector3 planePosition(-1.0f, 1.0f, 0.5f); - Vector3 planeNormal(0.0f, 0.0f, 1.0f); + const Vector3 planePosition(-1.0f, 1.0f, 0.5f); + const Vector3 planeNormal(0.0f, 0.0f, 1.0f); /* Inside line segment */ - CORRADE_COMPARE((Intersection::planeLine(planePosition, planeNormal, - Vector3(0.0f, 0.0f, -1.0f), Vector3(0.0f, 0.0f, 1.0f))), 0.75f); + CORRADE_COMPARE(Intersection::planeLine(planePosition, planeNormal, + {0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, 2.0f}), 0.75f); /* Outside line segment */ - CORRADE_COMPARE((Intersection::planeLine(planePosition, planeNormal, - Vector3(0.0f, 0.0f, 1.0f), Vector3(0.0f, 0.0f, 2.0f))), -0.5f); + CORRADE_COMPARE(Intersection::planeLine(planePosition, planeNormal, + {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 1.0f}), -0.5f); /* Line lies on the plane */ CORRADE_COMPARE(Intersection::planeLine(planePosition, planeNormal, - Vector3(1.0f, 0.5f, 0.5f), Vector3(0.0f, 1.0f, 0.5f)), std::numeric_limits::quiet_NaN()); + {1.0f, 0.5f, 0.5f}, {-1.0f, 0.5f, 0.0f}), std::numeric_limits::quiet_NaN()); + + /* Line is parallel to the plane */ + CORRADE_COMPARE(Intersection::planeLine(planePosition, planeNormal, + {1.0f, 0.0f, 1.0f}, {-1.0f, 0.0f, 0.0f}), -std::numeric_limits::infinity()); +} - /* Line is parallell to the plane */ - CORRADE_COMPARE((Intersection::planeLine(planePosition, planeNormal, - Vector3(1.0f, 0.0f, 1.0f), Vector3(0.0f, 0.0f, 1.0f))), -std::numeric_limits::infinity()); +void IntersectionTest::lineLine() { + const Vector2 p(-1.0f, -1.0f); + const Vector2 r(1.0, 2.0f); + + /* Inside both line segments */ + CORRADE_COMPARE(Intersection::lineSegmentLineSegment(p, r, + {0.0f, 0.0f}, {-1.0f, 0.0f}), std::make_pair(0.5f, 0.5f)); + CORRADE_COMPARE(Intersection::lineSegmentLine(p, r, + {0.0f, 0.0f}, {-1.0f, 0.0f}), 0.5); + + /* Outside both line segments */ + CORRADE_COMPARE(Intersection::lineSegmentLineSegment(p, r, + {0.0f, -2.0f}, {-1.0f, 0.0f}), std::make_pair(-0.5f, 1.5f)); + CORRADE_COMPARE(Intersection::lineSegmentLine(p, r, + {0.0f, -2.0f}, {-1.0f, 0.0f}), -0.5f); + + /* Collinear lines */ + const auto tu = Intersection::lineSegmentLineSegment(p, r, + {0.0f, 1.0f}, {-1.0f, -2.0f}); + CORRADE_COMPARE(tu.first, -std::numeric_limits::quiet_NaN()); + CORRADE_COMPARE(tu.second, -std::numeric_limits::quiet_NaN()); + CORRADE_COMPARE(Intersection::lineSegmentLine(p, r, + {0.0f, 1.0f}, {-1.0f, -2.0f}), -std::numeric_limits::quiet_NaN()); + + /* Parallel lines */ + CORRADE_COMPARE(Intersection::lineSegmentLineSegment(p, r, + {0.0f, 0.0f}, {1.0f, 2.0f}), std::make_pair(std::numeric_limits::infinity(), + std::numeric_limits::infinity())); + CORRADE_COMPARE(Intersection::lineSegmentLine(p, r, + {0.0f, 0.0f}, {1.0f, 2.0f}), std::numeric_limits::infinity()); } }}}} diff --git a/src/Math/Math.h b/src/Math/Math.h index 081d7acdf..0e11a8b5e 100644 --- a/src/Math/Math.h +++ b/src/Math/Math.h @@ -32,6 +32,8 @@ namespace Magnum { namespace Math { +/** @todo Denormals to zero */ + /** @todoc Remove `ifndef` when Doxygen is sane again */ #ifndef DOXYGEN_GENERATING_OUTPUT /* Class Constants used only statically */ diff --git a/src/Math/RectangularMatrix.h b/src/Math/RectangularMatrix.h index b9ab6b7a2..a2d4f944f 100644 --- a/src/Math/RectangularMatrix.h +++ b/src/Math/RectangularMatrix.h @@ -96,6 +96,17 @@ template class RectangularMatrix { return out; } + /** + * @brief Construct matrix from vector + * + * Rolls the vector into matrix, i.e. first `rows` elements of the + * vector will make first column of resulting matrix. + * @see toVector() + */ + inline static RectangularMatrix fromVector(const Vector& vector) { + return *reinterpret_cast*>(vector.data()); + } + /** @brief Construct zero-filled matrix */ inline constexpr /*implicit*/ RectangularMatrix() {} @@ -386,64 +397,17 @@ template class RectangularMatrix { return out; } - /** @brief Sum of values in the matrix */ - T sum() const { - T out(_data[0].sum()); - - for(std::size_t i = 1; i != cols; ++i) - out += _data[i].sum(); - - return out; - } - - /** @brief Product of values in the matrix */ - T product() const { - T out(_data[0].product()); - - for(std::size_t i = 1; i != cols; ++i) - out *= _data[i].product(); - - return out; - } - - /** @brief Minimal value in the matrix */ - T min() const { - T out(_data[0].min()); - - for(std::size_t i = 1; i != cols; ++i) - out = std::min(out, _data[i].min()); - - return out; - } - - /** @brief Minimal absolute value in the matrix */ - T minAbs() const { - T out(_data[0].minAbs()); - - for(std::size_t i = 1; i != cols; ++i) - out = std::min(out, _data[i].minAbs()); - - return out; - } - - /** @brief Maximal value in the matrix */ - T max() const { - T out(_data[0].max()); - - for(std::size_t i = 1; i != cols; ++i) - out = std::max(out, _data[i].max()); - - return out; - } - - /** @brief Maximal absolute value in the matrix */ - T maxAbs() const { - T out(_data[0].maxAbs()); - - for(std::size_t i = 1; i != cols; ++i) - out = std::max(out, _data[i].maxAbs()); - - return out; + /** + * @brief Convert matrix to vector + * + * Returns the matrix unrolled into one large vector, i.e. first column + * of the matrix will make first `rows` elements of resulting vector. + * Useful for performing vector operations with the matrix (e.g. + * summing the elements etc.). + * @see fromVector() + */ + inline Vector toVector() const { + return *reinterpret_cast*>(data()); } private: diff --git a/src/Math/Test/FunctionsTest.cpp b/src/Math/Test/FunctionsTest.cpp index 93c09d86b..25e519f92 100644 --- a/src/Math/Test/FunctionsTest.cpp +++ b/src/Math/Test/FunctionsTest.cpp @@ -38,8 +38,10 @@ class FunctionsTest: public Corrade::TestSuite::Tester { void sign(); void abs(); void sqrt(); + void sqrtInverted(); void clamp(); void lerp(); + void fma(); void normalizeUnsigned(); void normalizeSigned(); void denormalizeUnsigned(); @@ -70,8 +72,10 @@ FunctionsTest::FunctionsTest() { &FunctionsTest::sign, &FunctionsTest::abs, &FunctionsTest::sqrt, + &FunctionsTest::sqrtInverted, &FunctionsTest::clamp, &FunctionsTest::lerp, + &FunctionsTest::fma, &FunctionsTest::normalizeUnsigned, &FunctionsTest::normalizeSigned, &FunctionsTest::denormalizeUnsigned, @@ -116,6 +120,11 @@ void FunctionsTest::sqrt() { CORRADE_COMPARE(Math::sqrt(Vector3i(256, 1, 0)), Vector3i(16, 1, 0)); } +void FunctionsTest::sqrtInverted() { + CORRADE_COMPARE(Math::sqrtInverted(16.0f), 0.25f); + CORRADE_COMPARE(Math::sqrtInverted(Vector3(1.0f, 4.0f, 16.0f)), Vector3(1.0f, 0.5f, 0.25f)); +} + void FunctionsTest::clamp() { CORRADE_COMPARE(Math::clamp(0.5f, -1.0f, 5.0f), 0.5f); CORRADE_COMPARE(Math::clamp(-1.6f, -1.0f, 5.0f), -1.0f); @@ -141,6 +150,14 @@ void FunctionsTest::lerp() { CORRADE_COMPARE(Math::lerp(c, d, 0.25f), Vector3ub(4, 96, 56)); } +void FunctionsTest::fma() { + CORRADE_COMPARE(Math::fma(2.0f, 3.0f, 0.75f), 6.75f); + CORRADE_COMPARE(Math::fma(Vector3( 2.0f, 1.5f, 0.5f), + Vector3( 3.0f, 2.0f, -1.0f), + Vector3(0.75f, 0.25f, 0.1f)), + Vector3(6.75f, 3.25f, -0.4f)); +} + void FunctionsTest::normalizeUnsigned() { CORRADE_COMPARE((Math::normalize(0)), 0.0f); CORRADE_COMPARE((Math::normalize(255)), 1.0f); diff --git a/src/Math/Test/RectangularMatrixTest.cpp b/src/Math/Test/RectangularMatrixTest.cpp index 9ce624889..ab25a608c 100644 --- a/src/Math/Test/RectangularMatrixTest.cpp +++ b/src/Math/Test/RectangularMatrixTest.cpp @@ -54,12 +54,7 @@ class RectangularMatrixTest: public Corrade::TestSuite::Tester { void transposed(); void diagonal(); - void sum(); - void product(); - void min(); - void minAbs(); - void max(); - void maxAbs(); + void vector(); void debug(); void configuration(); @@ -95,12 +90,7 @@ RectangularMatrixTest::RectangularMatrixTest() { &RectangularMatrixTest::transposed, &RectangularMatrixTest::diagonal, - &RectangularMatrixTest::sum, - &RectangularMatrixTest::product, - &RectangularMatrixTest::min, - &RectangularMatrixTest::minAbs, - &RectangularMatrixTest::max, - &RectangularMatrixTest::maxAbs, + &RectangularMatrixTest::vector, &RectangularMatrixTest::debug, &RectangularMatrixTest::configuration}); @@ -338,50 +328,20 @@ void RectangularMatrixTest::diagonal() { CORRADE_COMPARE(b.diagonal(), diagonal); } -void RectangularMatrixTest::sum() { - Matrix2 matrix(Vector2(1.0f, 2.0f), - Vector2(3.0f, 4.0f)); - CORRADE_COMPARE(matrix.sum(), 10.0f); -} - -void RectangularMatrixTest::product() { - Matrix2 matrix(Vector2(1.0f, 2.0f), - Vector2(3.0f, 4.0f)); - CORRADE_COMPARE(matrix.product(), 24.0f); -} - -void RectangularMatrixTest::min() { - /* Check also that initial value isn't initialized to 0 */ - Matrix2 matrix(Vector2(-2.0f, 1.0f), - Vector2(3.0f, 4.0f)); - CORRADE_COMPARE(matrix.min(), -2.0f); -} +void RectangularMatrixTest::vector() { + typedef Vector<3, Int> Vector3i; + typedef RectangularMatrix<4, 3, Int> Matrix4x3i; + typedef Vector<12, Int> Vector12i; -void RectangularMatrixTest::minAbs() { - /* Check that initial value is absolute and also all others */ - Matrix2 a(Vector2(-2.0f, 1.0f), - Vector2(3.0f, 4.0f)); - Matrix2 b(Vector2(3.0f, 4.0f), - Vector2(-2.0f, 1.0f)); - CORRADE_COMPARE(a.minAbs(), 1.0f); - CORRADE_COMPARE(a.minAbs(), 1.0f); -} + Matrix4x3i a(Vector3i(0, 1, 2), + Vector3i(3, 4, 5), + Vector3i(6, 7, 8), + Vector3i(9, 10, 11)); -void RectangularMatrixTest::max() { - /* Check also that initial value isn't initialized to 0 */ - Matrix2 matrix(Vector2(-2.0f, -1.0f), - Vector2(-3.0f, -4.0f)); - CORRADE_COMPARE(matrix.max(), -1.0f); -} + Vector12i b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); -void RectangularMatrixTest::maxAbs() { - /* Check that initial value is absolute and also all others */ - Matrix2 a(Vector2(2.0f, 1.0f), - Vector2(3.0f, -4.0f)); - Matrix2 b(Vector2(3.0f, -4.0f), - Vector2(2.0f, 1.0f)); - CORRADE_COMPARE(a.maxAbs(), 4.0f); - CORRADE_COMPARE(b.maxAbs(), 4.0f); + CORRADE_COMPARE(a.toVector(), b); + CORRADE_COMPARE(Matrix4x3i::fromVector(b), a); } void RectangularMatrixTest::debug() { diff --git a/src/Math/Test/VectorTest.cpp b/src/Math/Test/VectorTest.cpp index 839450e8b..4fa7e93ae 100644 --- a/src/Math/Test/VectorTest.cpp +++ b/src/Math/Test/VectorTest.cpp @@ -78,14 +78,13 @@ class VectorTest: public Corrade::TestSuite::Tester { void dot(); void dotSelf(); void length(); + void lengthInverted(); void normalized(); void sum(); void product(); void min(); - void minAbs(); void max(); - void maxAbs(); void projected(); void projectedOntoNormalized(); @@ -125,14 +124,13 @@ VectorTest::VectorTest() { &VectorTest::dot, &VectorTest::dotSelf, &VectorTest::length, + &VectorTest::lengthInverted, &VectorTest::normalized, &VectorTest::sum, &VectorTest::product, &VectorTest::min, - &VectorTest::minAbs, &VectorTest::max, - &VectorTest::maxAbs, &VectorTest::projected, &VectorTest::projectedOntoNormalized, @@ -319,6 +317,10 @@ void VectorTest::length() { CORRADE_COMPARE(Vector4(1.0f, 2.0f, 3.0f, 4.0f).length(), 5.4772256f); } +void VectorTest::lengthInverted() { + CORRADE_COMPARE(Vector4(1.0f, 2.0f, 3.0f, 4.0f).lengthInverted(), 0.182574f); +} + void VectorTest::normalized() { CORRADE_COMPARE(Vector4(1.0f, 1.0f, 1.0f, 1.0f).normalized(), Vector4(0.5f, 0.5f, 0.5f, 0.5f)); } @@ -336,23 +338,11 @@ void VectorTest::min() { CORRADE_COMPARE(Vector3(1.0f, -2.0f, 3.0f).min(), -2.0f); } -void VectorTest::minAbs() { - /* Check that initial value is absolute and also all others */ - CORRADE_COMPARE(Vector3(-2.0f, 1.0f, 3.0f).minAbs(), 1.0f); - CORRADE_COMPARE(Vector3(1.0f, -2.0f, 3.0f).minAbs(), 1.0f); -} - void VectorTest::max() { /* Check also that initial value isn't initialized to 0 */ CORRADE_COMPARE(Vector3(-1.0f, -2.0f, -3.0f).max(), -1.0f); } -void VectorTest::maxAbs() { - /* Check that initial value is absolute and also all others */ - CORRADE_COMPARE(Vector3(-5.0f, 1.0f, 3.0f).maxAbs(), 5.0f); - CORRADE_COMPARE(Vector3(1.0f, -5.0f, 3.0f).maxAbs(), 5.0f); -} - void VectorTest::projected() { Vector3 line(1.0f, -1.0f, 0.5f); Vector3 projected = Vector3(1.0f, 2.0f, 3.0f).projected(line); diff --git a/src/Math/Vector.h b/src/Math/Vector.h index fa25328d6..2796af1cd 100644 --- a/src/Math/Vector.h +++ b/src/Math/Vector.h @@ -308,7 +308,7 @@ template class Vector { /** * @brief Add vector * - * @see operator+=() + * @see operator+=(), sum() */ inline Vector operator+(const Vector& other) const { return Vector(*this) += other; @@ -416,7 +416,7 @@ template class Vector { /** * @brief Multiply vector component-wise * - * @see operator*=(const Vector&) + * @see operator*=(const Vector&), product() */ template inline Vector operator*(const Vector& other) const { return Vector(*this) *= other; @@ -465,20 +465,32 @@ template class Vector { * values. @f[ * |\boldsymbol a| = \sqrt{\boldsymbol a \cdot \boldsymbol a} * @f] - * @see isNormalized() + * @see lengthInverted(), Math::sqrt(), normalized() * @todo something like std::hypot() for possibly better precision? */ inline T length() const { return std::sqrt(dot()); } + /** + * @brief Inverse vector length + * + * @f[ + * \frac{1}{|\boldsymbol a|} = \frac{1}{\sqrt{\boldsymbol a \cdot \boldsymbol a}} + * @f] + * @see length(), Math::sqrtInverted(), normalized() + */ + inline T lengthInverted() const { + return T(1)/length(); + } + /** * @brief Normalized vector (of unit length) * * @see isNormalized() */ inline Vector normalized() const { - return *this/length(); + return *this*lengthInverted(); } /** @@ -487,7 +499,7 @@ template class Vector { * Returns vector projected onto @p line. @f[ * \boldsymbol a_1 = \frac{\boldsymbol a \cdot \boldsymbol b}{\boldsymbol b \cdot \boldsymbol b} \boldsymbol b * @f] - * @see projectedOntoNormalized() + * @see dot(), projectedOntoNormalized() */ inline Vector projected(const Vector& line) const { return line*dot(*this, line)/line.dot(); @@ -501,13 +513,18 @@ template class Vector { * \boldsymbol a_1 = \frac{\boldsymbol a \cdot \boldsymbol b}{\boldsymbol b \cdot \boldsymbol b} \boldsymbol b = * (\boldsymbol a \cdot \boldsymbol b) \boldsymbol b * @f] + * @see dot() */ inline Vector projectedOntoNormalized(const Vector& line) const { CORRADE_ASSERT(line.isNormalized(), "Math::Vector::projectedOntoNormalized(): line must be normalized", (Vector(std::numeric_limits::quiet_NaN()))); return line*dot(*this, line); } - /** @brief Sum of values in the vector */ + /** + * @brief Sum of values in the vector + * + * @see operator+() + */ T sum() const { T out(_data[0]); @@ -517,7 +534,11 @@ template class Vector { return out; } - /** @brief Product of values in the vector */ + /** + * @brief Product of values in the vector + * + * @see operator*(const Vector&) + */ T product() const { T out(_data[0]); @@ -527,7 +548,11 @@ template class Vector { return out; } - /** @brief Minimal value in the vector */ + /** + * @brief Minimal value in the vector + * + * @see Math::min() + */ T min() const { T out(_data[0]); @@ -537,17 +562,11 @@ template class Vector { return out; } - /** @brief Minimal absolute value in the vector */ - T minAbs() const { - T out(std::abs(_data[0])); - - for(std::size_t i = 1; i != size; ++i) - out = std::min(out, std::abs(_data[i])); - - return out; - } - - /** @brief Maximal value in the vector */ + /** + * @brief Maximal value in the vector + * + * @see Math::max() + */ T max() const { T out(_data[0]); @@ -557,16 +576,6 @@ template class Vector { return out; } - /** @brief Maximal absolute value in the vector */ - T maxAbs() const { - T out(std::abs(_data[0])); - - for(std::size_t i = 1; i != size; ++i) - out = std::max(out, std::abs(_data[i])); - - return out; - } - private: /* Implementation for Vector::Vector(const Vector&) */ template inline constexpr explicit Vector(Implementation::Sequence, const Vector& vector): _data{T(vector._data[sequence])...} {} diff --git a/src/Math/Vector2.h b/src/Math/Vector2.h index 3a3e549f4..a503b0dfa 100644 --- a/src/Math/Vector2.h +++ b/src/Math/Vector2.h @@ -83,15 +83,16 @@ template class Vector2: public Vector<2, T> { /** * @brief 2D cross product * - * 2D version of cross product, equivalent to calling Vector3::cross() - * with Z coordinate set to `0` and extracting only Z coordinate from - * the result (X and Y coordinates are always zero). - * @f[ - * \boldsymbol a \times \boldsymbol b = a_xb_y - a_yb_x + * 2D version of cross product, also called perp-dot product, + * equivalent to calling Vector3::cross() with Z coordinate set to `0` + * and extracting only Z coordinate from the result (X and Y + * coordinates are always zero). @f[ + * \boldsymbol a \times \boldsymbol b = \boldsymbol a_\perp \cdot \boldsymbol b = a_xb_y - a_yb_x * @f] + * @see perpendicular(), dot(const Vector&, const Vector&) */ inline static T cross(const Vector2& a, const Vector2& b) { - return a.x()*b.y() - a.y()*b.x(); + return Vector<2, T>::dot(a.perpendicular(), b); } /** @copydoc Vector::Vector() */ @@ -133,7 +134,7 @@ template class Vector2: public Vector<2, T> { * Returns vector rotated 90° counterclockwise. @f[ * \boldsymbol v_\perp = \begin{pmatrix} -v_y \\ v_x \end{pmatrix} * @f] - * @see dot(const Vector&, const Vector&), operator-() const + * @see cross(), dot(const Vector&, const Vector&), operator-() const */ inline Vector2 perpendicular() const { return {-y(), x()}; } diff --git a/src/Mesh.cpp b/src/Mesh.cpp index 85cd97caa..19c8cee0e 100644 --- a/src/Mesh.cpp +++ b/src/Mesh.cpp @@ -55,7 +55,7 @@ std::size_t Mesh::indexSize(IndexType type) { case IndexType::UnsignedInt: return 4; } - CORRADE_INTERNAL_ASSERT(false); + CORRADE_ASSERT_UNREACHABLE(); } Mesh::Mesh(Primitive primitive): _primitive(primitive), _vertexCount(0), _indexCount(0) diff --git a/src/MeshTools/magnumMeshToolsVisibility.h b/src/MeshTools/magnumMeshToolsVisibility.h index 2c4934962..f7d8a63c4 100644 --- a/src/MeshTools/magnumMeshToolsVisibility.h +++ b/src/MeshTools/magnumMeshToolsVisibility.h @@ -24,14 +24,12 @@ DEALINGS IN THE SOFTWARE. */ -#ifdef _WIN32 - #if defined(MagnumMeshTools_EXPORTS) || defined(MagnumMeshToolsObjects_EXPORTS) - #define MAGNUM_MESHTOOLS_EXPORT __declspec(dllexport) - #else - #define MAGNUM_MESHTOOLS_EXPORT __declspec(dllimport) - #endif +#include + +#if defined(MagnumMeshTools_EXPORTS) || defined(MagnumMeshToolsObjects_EXPORTS) + #define MAGNUM_MESHTOOLS_EXPORT CORRADE_VISIBILITY_EXPORT #else - #define MAGNUM_MESHTOOLS_EXPORT __attribute__ ((visibility ("default"))) + #define MAGNUM_MESHTOOLS_EXPORT CORRADE_VISIBILITY_IMPORT #endif #endif diff --git a/src/Physics/AxisAlignedBox.h b/src/Physics/AxisAlignedBox.h index d987c8674..1a0a1e6d7 100644 --- a/src/Physics/AxisAlignedBox.h +++ b/src/Physics/AxisAlignedBox.h @@ -46,6 +46,13 @@ radius. */ template class MAGNUM_PHYSICS_EXPORT AxisAlignedBox: public AbstractShape { public: + /** + * @brief Default constructor + * + * Creates zero sized box positioned at origin. + */ + inline explicit AxisAlignedBox() {} + /** @brief Constructor */ inline explicit AxisAlignedBox(const typename DimensionTraits::VectorType& min, const typename DimensionTraits::VectorType& max): _min(min), _max(max), _transformedMin(min), _transformedMax(max) {} diff --git a/src/Physics/Box.h b/src/Physics/Box.h index e0b79de96..cf7276187 100644 --- a/src/Physics/Box.h +++ b/src/Physics/Box.h @@ -47,6 +47,13 @@ radius. */ template class MAGNUM_PHYSICS_EXPORT Box: public AbstractShape { public: + /** + * @brief Default constructor + * + * Creates zero-sized box positioned at origin. + */ + inline explicit Box(): _transformation(DimensionTraits::MatrixType::Zero), _transformedTransformation(DimensionTraits::MatrixType::Zero) {} + /** @brief Constructor */ inline explicit Box(const typename DimensionTraits::MatrixType& transformation): _transformation(transformation), _transformedTransformation(transformation) {} diff --git a/src/Physics/Capsule.h b/src/Physics/Capsule.h index bdb9975d7..b40a33b4f 100644 --- a/src/Physics/Capsule.h +++ b/src/Physics/Capsule.h @@ -46,6 +46,13 @@ applying transformation, the scale factor is averaged from all axes. */ template class MAGNUM_PHYSICS_EXPORT Capsule: public AbstractShape { public: + /** + * @brief Constructor + * + * Creates zero-sized capsule at origin. + */ + inline explicit Capsule(): _radius(0.0f), _transformedRadius(0.0f) {} + /** @brief Constructor */ inline explicit Capsule(const typename DimensionTraits::VectorType& a, const typename DimensionTraits::VectorType& b, Float radius): _a(a), _transformedA(a), _b(b), _transformedB(b), _radius(radius), _transformedRadius(radius) {} @@ -64,7 +71,7 @@ template class MAGNUM_PHYSICS_EXPORT Capsule: public Abs /** @brief End point */ inline typename DimensionTraits::VectorType b() const { - return _a; + return _b; } /** @brief Set start point */ diff --git a/src/Physics/Line.h b/src/Physics/Line.h index 0c9abb333..49e835c3c 100644 --- a/src/Physics/Line.h +++ b/src/Physics/Line.h @@ -43,6 +43,13 @@ namespace Magnum { namespace Physics { */ template class MAGNUM_PHYSICS_EXPORT Line: public AbstractShape { public: + /** + * @brief Default constructor + * + * Creates line with both points at origin. + */ + inline explicit Line() {} + /** @brief Constructor */ inline explicit Line(const typename DimensionTraits::VectorType& a, const typename DimensionTraits::VectorType& b): _a(a), _transformedA(a), _b(b), _transformedB(b) {} @@ -59,7 +66,7 @@ template class MAGNUM_PHYSICS_EXPORT Line: public Abstra /** @brief Second point */ inline typename DimensionTraits::VectorType b() const { - return _a; + return _b; } /** @brief Set first point */ diff --git a/src/Physics/LineSegment.h b/src/Physics/LineSegment.h index ab1684480..666764734 100644 --- a/src/Physics/LineSegment.h +++ b/src/Physics/LineSegment.h @@ -39,6 +39,13 @@ namespace Magnum { namespace Physics { */ template class LineSegment: public Line { public: + /** + * @brief Default constructor + * + * Creates line segment with both points at origin. + */ + inline explicit LineSegment() {} + /** @brief Constructor */ inline explicit LineSegment(const typename DimensionTraits::VectorType& a, const typename DimensionTraits::VectorType& b): Line(a, b) {} diff --git a/src/Physics/Plane.cpp b/src/Physics/Plane.cpp index 8c3ae2b50..047e22773 100644 --- a/src/Physics/Plane.cpp +++ b/src/Physics/Plane.cpp @@ -49,12 +49,12 @@ bool Plane::collides(const AbstractShape<3>* other) const { } bool Plane::operator%(const Line3D& other) const { - Float t = Intersection::planeLine(transformedPosition(), transformedNormal(), other.transformedA(), other.transformedB()); + Float t = Intersection::planeLine(transformedPosition(), transformedNormal(), other.transformedA(), other.transformedB()-other.transformedA()); return t != t || (t != std::numeric_limits::infinity() && t != -std::numeric_limits::infinity()); } bool Plane::operator%(const LineSegment3D& other) const { - Float t = Intersection::planeLine(transformedPosition(), transformedNormal(), other.transformedA(), other.transformedB()); + Float t = Intersection::planeLine(transformedPosition(), transformedNormal(), other.transformedA(), other.transformedB()-other.transformedA()); return t > 0.0f && t < 1.0f; } diff --git a/src/Physics/Plane.h b/src/Physics/Plane.h index 7dbf76e22..fbb576eb6 100644 --- a/src/Physics/Plane.h +++ b/src/Physics/Plane.h @@ -39,6 +39,13 @@ namespace Magnum { namespace Physics { /** @brief Infinite plane, defined by position and normal (3D only) */ class MAGNUM_PHYSICS_EXPORT Plane: public AbstractShape<3> { public: + /** + * @brief Default constructor + * + * Creates plane with zero-sized normal at origin. + */ + inline explicit Plane() {} + /** @brief Constructor */ inline explicit Plane(const Vector3& position, const Vector3& normal): _position(position), _transformedPosition(position), _normal(normal), _transformedNormal(normal) {} diff --git a/src/Physics/Point.h b/src/Physics/Point.h index 2ab8f362e..606ad0b51 100644 --- a/src/Physics/Point.h +++ b/src/Physics/Point.h @@ -42,6 +42,13 @@ namespace Magnum { namespace Physics { */ template class MAGNUM_PHYSICS_EXPORT Point: public AbstractShape { public: + /** + * @brief Default constructor + * + * Creates point at origin. + */ + inline explicit Point() {} + /** @brief Constructor */ inline explicit Point(const typename DimensionTraits::VectorType& position): _position(position), _transformedPosition(position) {} diff --git a/src/Physics/Sphere.h b/src/Physics/Sphere.h index c1324c550..6f83d2ddb 100644 --- a/src/Physics/Sphere.h +++ b/src/Physics/Sphere.h @@ -46,6 +46,13 @@ applying transformation, the scale factor is averaged from all axes. */ template class MAGNUM_PHYSICS_EXPORT Sphere: public AbstractShape { public: + /** + * @brief Default constructor + * + * Creates zero-sized sphere at origin. + */ + inline explicit Sphere(): _radius(0.0f), _transformedRadius(0.0f) {} + /** @brief Constructor */ inline explicit Sphere(const typename DimensionTraits::VectorType& position, Float radius): _position(position), _transformedPosition(position), _radius(radius), _transformedRadius(radius) {} diff --git a/src/Physics/Test/CapsuleTest.cpp b/src/Physics/Test/CapsuleTest.cpp index 8f1bc43d3..9e69302fe 100644 --- a/src/Physics/Test/CapsuleTest.cpp +++ b/src/Physics/Test/CapsuleTest.cpp @@ -41,7 +41,8 @@ class CapsuleTest: public Corrade::TestSuite::Tester, ShapeTestBase { CapsuleTest::CapsuleTest() { addTests({&CapsuleTest::applyTransformation, - &CapsuleTest::collisionPoint}); + &CapsuleTest::collisionPoint, + &CapsuleTest::collisionSphere}); } void CapsuleTest::applyTransformation() { @@ -50,7 +51,8 @@ void CapsuleTest::applyTransformation() { capsule.applyTransformationMatrix(Matrix4::rotation(Deg(90.0f), Vector3::zAxis())); CORRADE_COMPARE(capsule.transformedA(), Vector3(-2.0f, 1.0f, 3.0f)); CORRADE_COMPARE(capsule.transformedB(), Vector3(2.0f, -1.0f, -3.0f)); - CORRADE_COMPARE(capsule.radius(), 7.0f); + CORRADE_COMPARE(capsule.transformedRadius(), 7.0f); +} /* Apply average scaling to radius */ capsule.applyTransformationMatrix(Matrix4::scaling({Constants::sqrt3(), -Constants::sqrt2(), 2.0f})); diff --git a/src/Physics/magnumPhysicsVisibility.h b/src/Physics/magnumPhysicsVisibility.h index 07d22128b..6ee2b89c0 100644 --- a/src/Physics/magnumPhysicsVisibility.h +++ b/src/Physics/magnumPhysicsVisibility.h @@ -24,14 +24,12 @@ DEALINGS IN THE SOFTWARE. */ -#ifdef _WIN32 - #ifdef MagnumPhysics_EXPORTS - #define MAGNUM_PHYSICS_EXPORT __declspec(dllexport) - #else - #define MAGNUM_PHYSICS_EXPORT __declspec(dllimport) - #endif +#include + +#ifdef MagnumPhysics_EXPORTS + #define MAGNUM_PHYSICS_EXPORT CORRADE_VISIBILITY_EXPORT #else - #define MAGNUM_PHYSICS_EXPORT __attribute__ ((visibility ("default"))) + #define MAGNUM_PHYSICS_EXPORT CORRADE_VISIBILITY_IMPORT #endif #endif diff --git a/src/Platform/AbstractXApplication.h b/src/Platform/AbstractXApplication.h index 3afdd40c2..4913d03bb 100644 --- a/src/Platform/AbstractXApplication.h +++ b/src/Platform/AbstractXApplication.h @@ -56,7 +56,10 @@ Supports keyboard and mouse handling. See @ref platform for brief introduction. class AbstractXApplication { public: /** @brief Application arguments */ - typedef std::pair Arguments; + struct Arguments { + int& argc; /**< @brief Argument count */ + char** argv; /**< @brief Argument values */ + }; class Configuration; class InputEvent; diff --git a/src/Platform/GlutApplication.cpp b/src/Platform/GlutApplication.cpp index 705264312..65ea0566c 100644 --- a/src/Platform/GlutApplication.cpp +++ b/src/Platform/GlutApplication.cpp @@ -32,12 +32,12 @@ namespace Magnum { namespace Platform { GlutApplication* GlutApplication::instance = nullptr; GlutApplication::GlutApplication(const Arguments& arguments): c(nullptr) { - initialize(arguments.first, arguments.second); + initialize(arguments.argc, arguments.argv); createContext(new Configuration); } GlutApplication::GlutApplication(const Arguments& arguments, Configuration* configuration): c(nullptr) { - initialize(arguments.first, arguments.second); + initialize(arguments.argc, arguments.argv); if(configuration) createContext(configuration); } diff --git a/src/Platform/GlutApplication.h b/src/Platform/GlutApplication.h index 4987ccf60..0f0ab185a 100644 --- a/src/Platform/GlutApplication.h +++ b/src/Platform/GlutApplication.h @@ -68,7 +68,10 @@ to simplify porting. class GlutApplication { public: /** @brief Application arguments */ - typedef std::pair Arguments; + struct Arguments { + int& argc; /**< @brief Argument count */ + char** argv; /**< @brief Argument values */ + }; class Configuration; class InputEvent; diff --git a/src/Platform/Sdl2Application.cpp b/src/Platform/Sdl2Application.cpp index d5e5b3855..2470d6639 100644 --- a/src/Platform/Sdl2Application.cpp +++ b/src/Platform/Sdl2Application.cpp @@ -93,10 +93,8 @@ bool Sdl2Application::tryCreateContext(Configuration* configuration) { if(!(window = SDL_CreateWindow(configuration->title().c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, configuration->size().x(), configuration->size().y(), - SDL_WINDOW_OPENGL|flags))) { - Error() << "Platform::Sdl2Application::tryCreateContext(): cannot create window"; - std::exit(2); - } + SDL_WINDOW_OPENGL|flags))) + return false; if(!(context = SDL_GL_CreateContext(window))) { SDL_DestroyWindow(window); diff --git a/src/Platform/Sdl2Application.h b/src/Platform/Sdl2Application.h index 5ed06ed7a..10733d3cb 100644 --- a/src/Platform/Sdl2Application.h +++ b/src/Platform/Sdl2Application.h @@ -69,7 +69,10 @@ to simplify porting. class Sdl2Application { public: /** @brief Application arguments */ - typedef std::pair Arguments; + struct Arguments { + int& argc; /**< @brief Argument count */ + char** argv; /**< @brief Argument values */ + }; class Configuration; class InputEvent; diff --git a/src/Platform/WindowlessGlxApplication.cpp b/src/Platform/WindowlessGlxApplication.cpp index 2d7c017b8..0108bc2ca 100644 --- a/src/Platform/WindowlessGlxApplication.cpp +++ b/src/Platform/WindowlessGlxApplication.cpp @@ -33,11 +33,11 @@ namespace Magnum { namespace Platform { -WindowlessGlxApplication::WindowlessGlxApplication(const Arguments&) { +WindowlessGlxApplication::WindowlessGlxApplication(const Arguments&): c(nullptr) { createContext(new Configuration); } -WindowlessGlxApplication::WindowlessGlxApplication(const Arguments&, Configuration* configuration) { +WindowlessGlxApplication::WindowlessGlxApplication(const Arguments&, Configuration* configuration): c(nullptr) { if(configuration) createContext(configuration); } @@ -104,6 +104,8 @@ void WindowlessGlxApplication::createContext(Configuration* configuration) { } WindowlessGlxApplication::~WindowlessGlxApplication() { + delete c; + glXMakeCurrent(display, None, nullptr); glXDestroyContext(display, context); } diff --git a/src/Platform/WindowlessGlxApplication.h b/src/Platform/WindowlessGlxApplication.h index b7c8d940a..c38cfb5a6 100644 --- a/src/Platform/WindowlessGlxApplication.h +++ b/src/Platform/WindowlessGlxApplication.h @@ -66,7 +66,10 @@ If no other application header is included this class is also aliased to class WindowlessGlxApplication { public: /** @brief Application arguments */ - typedef std::pair Arguments; + struct Arguments { + int& argc; /**< @brief Argument count */ + char** argv; /**< @brief Argument values */ + }; class Configuration; diff --git a/src/Primitives/CMakeLists.txt b/src/Primitives/CMakeLists.txt index 9675469aa..01224000d 100644 --- a/src/Primitives/CMakeLists.txt +++ b/src/Primitives/CMakeLists.txt @@ -32,7 +32,9 @@ set(MagnumPrimitives_SRCS Line.cpp Plane.cpp Square.cpp - UVSphere.cpp) + UVSphere.cpp + + Implementation/Spheroid.cpp) set(MagnumPrimitives_HEADERS Capsule.h diff --git a/src/Primitives/Capsule.cpp b/src/Primitives/Capsule.cpp index e35ecb34f..1447e2e16 100644 --- a/src/Primitives/Capsule.cpp +++ b/src/Primitives/Capsule.cpp @@ -24,147 +24,43 @@ #include "Capsule.h" -#include "Math/Functions.h" -#include "Math/Vector3.h" +#include "Math/Angle.h" +#include "Primitives/Implementation/Spheroid.h" namespace Magnum { namespace Primitives { -Capsule::Capsule(UnsignedInt hemisphereRings, UnsignedInt cylinderRings, UnsignedInt segments, Float length, TextureCoords textureCoords): MeshData3D(Mesh::Primitive::Triangles, new std::vector, {new std::vector()}, {new std::vector()}, textureCoords == TextureCoords::Generate ? std::vector*>{new std::vector()} : std::vector*>()), segments(segments), textureCoords(textureCoords) { - CORRADE_ASSERT(hemisphereRings >= 1 && cylinderRings >= 1 && segments >= 3, "Capsule must have at least one hemisphere ring, one cylinder ring and three segments", ); +Trade::MeshData3D Capsule::solid(UnsignedInt hemisphereRings, UnsignedInt cylinderRings, UnsignedInt segments, Float length, TextureCoords textureCoords) { + CORRADE_ASSERT(hemisphereRings >= 1 && cylinderRings >= 1 && segments >= 3, "Capsule must have at least one hemisphere ring, one cylinder ring and three segments", Trade::MeshData3D(Mesh::Primitive::Triangles, nullptr, {}, {}, {})); + + Implementation::Spheroid capsule(segments, textureCoords == TextureCoords::Generate ? + Implementation::Spheroid::TextureCoords::Generate : + Implementation::Spheroid::TextureCoords::DontGenerate); Float height = 2.0f+length; Float hemisphereTextureCoordsVIncrement = 1.0f/(hemisphereRings*height); Rad hemisphereRingAngleIncrement(Constants::pi()/(2*hemisphereRings)); /* Bottom cap vertex */ - capVertex(-height/2, -1.0f, 0.0f); + capsule.capVertex(-height/2, -1.0f, 0.0f); /* Rings of bottom hemisphere */ - hemisphereVertexRings(hemisphereRings-1, -length/2, -Rad(Constants::pi())/2+hemisphereRingAngleIncrement, hemisphereRingAngleIncrement, hemisphereTextureCoordsVIncrement, hemisphereTextureCoordsVIncrement); + capsule.hemisphereVertexRings(hemisphereRings-1, -length/2, -Rad(Constants::pi())/2+hemisphereRingAngleIncrement, hemisphereRingAngleIncrement, hemisphereTextureCoordsVIncrement, hemisphereTextureCoordsVIncrement); /* Rings of cylinder */ - cylinderVertexRings(cylinderRings+1, -length/2, length/cylinderRings, 1.0f/height, length/(cylinderRings*height)); + capsule.cylinderVertexRings(cylinderRings+1, -length/2, length/cylinderRings, 1.0f/height, length/(cylinderRings*height)); /* Rings of top hemisphere */ - hemisphereVertexRings(hemisphereRings-1, length/2, hemisphereRingAngleIncrement, hemisphereRingAngleIncrement, (1.0f + length)/height+hemisphereTextureCoordsVIncrement, hemisphereTextureCoordsVIncrement); + capsule.hemisphereVertexRings(hemisphereRings-1, length/2, hemisphereRingAngleIncrement, hemisphereRingAngleIncrement, (1.0f + length)/height+hemisphereTextureCoordsVIncrement, hemisphereTextureCoordsVIncrement); /* Top cap vertex */ - capVertex(height/2, 1.0f, 1.0f); + capsule.capVertex(height/2, 1.0f, 1.0f); /* Faces */ - bottomFaceRing(); - faceRings(hemisphereRings*2-2+cylinderRings); - topFaceRing(); -} - -Capsule::Capsule(UnsignedInt segments, TextureCoords textureCoords): MeshData3D(Mesh::Primitive::Triangles, new std::vector, {new std::vector()}, {new std::vector()}, textureCoords == TextureCoords::Generate ? std::vector*>{new std::vector()} : std::vector*>()), segments(segments), textureCoords(textureCoords) {} - -void Capsule::capVertex(Float y, Float normalY, Float textureCoordsV) { - positions(0)->push_back({0.0f, y, 0.0f}); - normals(0)->push_back({0.0f, normalY, 0.0f}); - - if(textureCoords == TextureCoords::Generate) - textureCoords2D(0)->push_back({0.5, textureCoordsV}); -} - -void Capsule::hemisphereVertexRings(UnsignedInt count, Float centerY, Rad startRingAngle, Rad ringAngleIncrement, Float startTextureCoordsV, Float textureCoordsVIncrement) { - Rad segmentAngleIncrement(2*Constants::pi()/segments); - Float x, y, z; - for(UnsignedInt i = 0; i != count; ++i) { - Rad ringAngle = startRingAngle + i*ringAngleIncrement; - x = z = Math::cos(ringAngle); - y = Math::sin(ringAngle); - - for(UnsignedInt j = 0; j != segments; ++j) { - Rad segmentAngle = j*segmentAngleIncrement; - positions(0)->push_back({x*Math::sin(segmentAngle), centerY+y, z*Math::cos(segmentAngle)}); - normals(0)->push_back({x*Math::sin(segmentAngle), y, z*Math::cos(segmentAngle)}); - - if(textureCoords == TextureCoords::Generate) - textureCoords2D(0)->push_back({j*1.0f/segments, startTextureCoordsV + i*textureCoordsVIncrement}); - } - - /* Duplicate first segment in the ring for additional vertex for texture coordinate */ - if(textureCoords == TextureCoords::Generate) { - positions(0)->push_back((*positions(0))[positions(0)->size()-segments]); - normals(0)->push_back((*normals(0))[normals(0)->size()-segments]); - textureCoords2D(0)->push_back({1.0f, startTextureCoordsV + i*textureCoordsVIncrement}); - } - } -} - -void Capsule::cylinderVertexRings(UnsignedInt count, Float startY, Float yIncrement, Float startTextureCoordsV, Float textureCoordsVIncrement) { - Rad segmentAngleIncrement(2*Constants::pi()/segments); - for(UnsignedInt i = 0; i != count; ++i) { - for(UnsignedInt j = 0; j != segments; ++j) { - Rad segmentAngle = j*segmentAngleIncrement; - positions(0)->push_back({Math::sin(segmentAngle), startY, Math::cos(segmentAngle)}); - normals(0)->push_back({Math::sin(segmentAngle), 0.0f, Math::cos(segmentAngle)}); - - if(textureCoords == TextureCoords::Generate) - textureCoords2D(0)->push_back({j*1.0f/segments, startTextureCoordsV + i*textureCoordsVIncrement}); - } - - /* Duplicate first segment in the ring for additional vertex for texture coordinate */ - if(textureCoords == TextureCoords::Generate) { - positions(0)->push_back((*positions(0))[positions(0)->size()-segments]); - normals(0)->push_back((*normals(0))[normals(0)->size()-segments]); - textureCoords2D(0)->push_back({1.0f, startTextureCoordsV + i*textureCoordsVIncrement}); - } - - startY += yIncrement; - } -} - -void Capsule::bottomFaceRing() { - for(UnsignedInt j = 0; j != segments; ++j) { - /* Bottom vertex */ - indices()->push_back(0); - - /* Top right vertex */ - indices()->push_back((j != segments-1 || textureCoords == TextureCoords::Generate) ? - j+2 : 1); - - /* Top left vertex */ - indices()->push_back(j+1); - } -} - -void Capsule::faceRings(UnsignedInt count, UnsignedInt offset) { - UnsignedInt vertexSegments = segments + (textureCoords == TextureCoords::Generate ? 1 : 0); - - for(UnsignedInt i = 0; i != count; ++i) { - for(UnsignedInt j = 0; j != segments; ++j) { - UnsignedInt bottomLeft = i*vertexSegments+j+offset; - UnsignedInt bottomRight = ((j != segments-1 || textureCoords == TextureCoords::Generate) ? - i*vertexSegments+j+1+offset : i*segments+offset); - UnsignedInt topLeft = bottomLeft+vertexSegments; - UnsignedInt topRight = bottomRight+vertexSegments; - - indices()->push_back(bottomLeft); - indices()->push_back(bottomRight); - indices()->push_back(topRight); - indices()->push_back(bottomLeft); - indices()->push_back(topRight); - indices()->push_back(topLeft); - } - } -} - -void Capsule::topFaceRing() { - UnsignedInt vertexSegments = segments + (textureCoords == TextureCoords::Generate ? 1 : 0); - - for(UnsignedInt j = 0; j != segments; ++j) { - /* Bottom left vertex */ - indices()->push_back(normals(0)->size()-vertexSegments+j-1); - - /* Bottom right vertex */ - indices()->push_back((j != segments-1 || textureCoords == TextureCoords::Generate) ? - normals(0)->size()-vertexSegments+j : normals(0)->size()-segments-1); + capsule.bottomFaceRing(); + capsule.faceRings(hemisphereRings*2-2+cylinderRings); + capsule.topFaceRing(); - /* Top vertex */ - indices()->push_back(normals(0)->size()-1); - } + return std::move(capsule); } }} diff --git a/src/Primitives/Capsule.h b/src/Primitives/Capsule.h index 00111ae74..fbefe1c30 100644 --- a/src/Primitives/Capsule.h +++ b/src/Primitives/Capsule.h @@ -28,56 +28,40 @@ * @brief Class Magnum::Primitives::Capsule */ -#include "Trade/MeshData3D.h" - #include "Primitives/magnumPrimitivesVisibility.h" +#include "Trade/Trade.h" namespace Magnum { namespace Primitives { /** @brief 3D capsule primitive -%Cylinder along Y axis with hemispheres instead of caps. Indexed @ref Mesh::Primitive "Triangles" -with normals and optional 2D texture coordinates. +%Cylinder of radius `1` along Y axis with hemispheres instead of caps. */ -class Capsule: public Trade::MeshData3D { - friend class UVSphere; - friend class Cylinder; - +class MAGNUM_PRIMITIVES_EXPORT Capsule { public: /** @brief Whether to generate texture coordinates */ - enum class TextureCoords { + enum class TextureCoords: UnsignedByte { Generate, /**< Generate texture coordinates */ DontGenerate /**< Don't generate texture coordinates */ }; /** - * @brief Constructor + * @brief Solid capsule * @param hemisphereRings Number of (face) rings for each hemisphere. * Must be larger or equal to 1. * @param cylinderRings Number of (face) rings for cylinder. Must be * larger or equal to 1. - * @param segments Number of (face) segments. Must be larger or equal to 3. + * @param segments Number of (face) segments. Must be larger or + * equal to 3. * @param length Length of the capsule, excluding hemispheres. * @param textureCoords Whether to generate texture coordinates. * - * If texture coordinates are generated, vertices of one segment are - * duplicated for texture wrapping. + * Indexed @ref Mesh::Primitive "Triangles" with normals and optional + * 2D texture coordinates. If texture coordinates are generated, + * vertices of one segment are duplicated for texture wrapping. */ - explicit MAGNUM_PRIMITIVES_EXPORT Capsule(UnsignedInt hemisphereRings, UnsignedInt cylinderRings, UnsignedInt segments, Float length, TextureCoords textureCoords = TextureCoords::DontGenerate); - - private: - Capsule(UnsignedInt segments, TextureCoords textureCoords); - - void capVertex(Float y, Float normalY, Float textureCoordsV); - void hemisphereVertexRings(UnsignedInt count, Float centerY, Rad startRingAngle, Rad ringAngleIncrement, Float startTextureCoordsV, Float textureCoordsVIncrement); - void cylinderVertexRings(UnsignedInt count, Float startY, Float yIncrement, Float startTextureCoordsV, Float textureCoordsVIncrement); - void bottomFaceRing(); - void faceRings(UnsignedInt count, UnsignedInt offset = 1); - void topFaceRing(); - - UnsignedInt segments; - TextureCoords textureCoords; + static Trade::MeshData3D solid(UnsignedInt hemisphereRings, UnsignedInt cylinderRings, UnsignedInt segments, Float length, TextureCoords textureCoords = TextureCoords::DontGenerate); }; }} diff --git a/src/Primitives/Circle.h b/src/Primitives/Circle.h index a27876e31..b97c1e7b2 100644 --- a/src/Primitives/Circle.h +++ b/src/Primitives/Circle.h @@ -37,7 +37,7 @@ namespace Magnum { namespace Primitives { /** @brief 2D circle primitive -Circle with radius 1. +Circle with radius `1`. */ class MAGNUM_PRIMITIVES_EXPORT Circle { public: diff --git a/src/Primitives/Cylinder.cpp b/src/Primitives/Cylinder.cpp index 691e5402b..13c043b3a 100644 --- a/src/Primitives/Cylinder.cpp +++ b/src/Primitives/Cylinder.cpp @@ -24,56 +24,40 @@ #include "Cylinder.h" -#include "Math/Functions.h" #include "Math/Vector3.h" +#include "Primitives/Implementation/Spheroid.h" namespace Magnum { namespace Primitives { -Cylinder::Cylinder(UnsignedInt rings, UnsignedInt segments, Float length, Flags flags): Capsule(segments, flags & Flag::GenerateTextureCoords ? TextureCoords::Generate : TextureCoords::DontGenerate) { - CORRADE_ASSERT(rings >= 1 && segments >= 3, "Cylinder must have at least one ring and three segments", ); +Trade::MeshData3D Cylinder::solid(UnsignedInt rings, UnsignedInt segments, Float length, Cylinder::Flags flags) { + CORRADE_ASSERT(rings >= 1 && segments >= 3, "Primitives::Cylinder::solid(): cylinder must have at least one ring and three segments", Trade::MeshData3D(Mesh::Primitive::Triangles, nullptr, {}, {}, {})); + + Implementation::Spheroid cylinder(segments, flags & Flag::GenerateTextureCoords ? Implementation::Spheroid::TextureCoords::Generate : Implementation::Spheroid::TextureCoords::DontGenerate); Float y = length*0.5f; Float textureCoordsV = flags & Flag::CapEnds ? 1.0f/(length+2.0f) : 0.0f; /* Bottom cap */ if(flags & Flag::CapEnds) { - capVertex(-y, -1.0f, 0.0f); - capVertexRing(-y, textureCoordsV, Vector3::yAxis(-1.0f)); + cylinder.capVertex(-y, -1.0f, 0.0f); + cylinder.capVertexRing(-y, textureCoordsV, Vector3::yAxis(-1.0f)); } /* Vertex rings */ - cylinderVertexRings(rings+1, -y, length/rings, textureCoordsV, length/(rings*(flags & Flag::CapEnds ? length + 2.0f : length))); + cylinder.cylinderVertexRings(rings+1, -y, length/rings, textureCoordsV, length/(rings*(flags & Flag::CapEnds ? length + 2.0f : length))); /* Top cap */ if(flags & Flag::CapEnds) { - capVertexRing(y, 1.0f - textureCoordsV, Vector3::yAxis(1.0f)); - capVertex(y, 1.0f, 1.0f); + cylinder.capVertexRing(y, 1.0f - textureCoordsV, Vector3::yAxis(1.0f)); + cylinder.capVertex(y, 1.0f, 1.0f); } /* Faces */ - if(flags & Flag::CapEnds) bottomFaceRing(); - faceRings(rings, flags & Flag::CapEnds ? 1 : 0); - if(flags & Flag::CapEnds) topFaceRing(); -} - -void Cylinder::capVertexRing(Float y, Float textureCoordsV, const Vector3& normal) { - Rad segmentAngleIncrement(2*Constants::pi()/segments); - - for(UnsignedInt i = 0; i != segments; ++i) { - Rad segmentAngle = i*segmentAngleIncrement; - positions(0)->push_back({Math::sin(segmentAngle), y, Math::cos(segmentAngle)}); - normals(0)->push_back(normal); + if(flags & Flag::CapEnds) cylinder.bottomFaceRing(); + cylinder.faceRings(rings, flags & Flag::CapEnds ? 1 : 0); + if(flags & Flag::CapEnds) cylinder.topFaceRing(); - if(textureCoords == TextureCoords::Generate) - textureCoords2D(0)->push_back({i*1.0f/segments, textureCoordsV}); - } - - /* Duplicate first segment in the ring for additional vertex for texture coordinate */ - if(textureCoords == TextureCoords::Generate) { - positions(0)->push_back((*positions(0))[positions(0)->size()-segments]); - normals(0)->push_back(normal); - textureCoords2D(0)->push_back({1.0f, textureCoordsV}); - } + return std::move(cylinder); } }} diff --git a/src/Primitives/Cylinder.h b/src/Primitives/Cylinder.h index eac16de9d..ed38da5ae 100644 --- a/src/Primitives/Cylinder.h +++ b/src/Primitives/Cylinder.h @@ -30,19 +30,17 @@ #include -#include "Primitives/Capsule.h" - #include "Primitives/magnumPrimitivesVisibility.h" +#include "Trade/Trade.h" namespace Magnum { namespace Primitives { /** @brief 3D cylinder primitive -Indexed @ref Mesh::Primitive "Triangles" with normals, optional 2D texture -coordinates and optional capped ends. +%Cylinder along Y axis of radius `1`. */ -class Cylinder: public Capsule { +class MAGNUM_PRIMITIVES_EXPORT Cylinder { public: /** * @brief %Flags @@ -58,7 +56,7 @@ class Cylinder: public Capsule { typedef Corrade::Containers::EnumSet Flags; /** - * @brief Constructor + * @brief Solid cylinder * @param rings Number of (face) rings. Must be larger or * equal to 1. * @param segments Number of (face) segments. Must be larger or @@ -66,13 +64,12 @@ class Cylinder: public Capsule { * @param length Cylinder length * @param flags Flags * - * If texture coordinates are generated, vertices of one segment are - * duplicated for texture wrapping. + * Indexed @ref Mesh::Primitive "Triangles" with normals, optional 2D + * texture coordinates and optional capped ends. If texture coordinates + * are generated, vertices of one segment are duplicated for texture + * wrapping. */ - explicit MAGNUM_PRIMITIVES_EXPORT Cylinder(UnsignedInt rings, UnsignedInt segments, Float length, Flags flags = Flags()); - - private: - void capVertexRing(Float y, Float textureCoordsV, const Vector3& normal); + static Trade::MeshData3D solid(UnsignedInt rings, UnsignedInt segments, Float length, Flags flags = Flags()); }; CORRADE_ENUMSET_OPERATORS(Cylinder::Flags) diff --git a/src/Primitives/Implementation/Spheroid.cpp b/src/Primitives/Implementation/Spheroid.cpp new file mode 100644 index 000000000..288279160 --- /dev/null +++ b/src/Primitives/Implementation/Spheroid.cpp @@ -0,0 +1,162 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + 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 "Spheroid.h" + +#include "Math/Functions.h" +#include "Math/Vector3.h" + +namespace Magnum { namespace Primitives { namespace Implementation { + +Spheroid::Spheroid(UnsignedInt segments, TextureCoords textureCoords): MeshData3D(Mesh::Primitive::Triangles, new std::vector, {new std::vector()}, {new std::vector()}, textureCoords == TextureCoords::Generate ? std::vector*>{new std::vector()} : std::vector*>()), segments(segments), textureCoords(textureCoords) {} + +void Spheroid::capVertex(Float y, Float normalY, Float textureCoordsV) { + positions(0)->push_back({0.0f, y, 0.0f}); + normals(0)->push_back({0.0f, normalY, 0.0f}); + + if(textureCoords == TextureCoords::Generate) + textureCoords2D(0)->push_back({0.5, textureCoordsV}); +} + +void Spheroid::hemisphereVertexRings(UnsignedInt count, Float centerY, Rad startRingAngle, Rad ringAngleIncrement, Float startTextureCoordsV, Float textureCoordsVIncrement) { + Rad segmentAngleIncrement(2*Constants::pi()/segments); + Float x, y, z; + for(UnsignedInt i = 0; i != count; ++i) { + Rad ringAngle = startRingAngle + i*ringAngleIncrement; + x = z = Math::cos(ringAngle); + y = Math::sin(ringAngle); + + for(UnsignedInt j = 0; j != segments; ++j) { + Rad segmentAngle = j*segmentAngleIncrement; + positions(0)->push_back({x*Math::sin(segmentAngle), centerY+y, z*Math::cos(segmentAngle)}); + normals(0)->push_back({x*Math::sin(segmentAngle), y, z*Math::cos(segmentAngle)}); + + if(textureCoords == TextureCoords::Generate) + textureCoords2D(0)->push_back({j*1.0f/segments, startTextureCoordsV + i*textureCoordsVIncrement}); + } + + /* Duplicate first segment in the ring for additional vertex for texture coordinate */ + if(textureCoords == TextureCoords::Generate) { + positions(0)->push_back((*positions(0))[positions(0)->size()-segments]); + normals(0)->push_back((*normals(0))[normals(0)->size()-segments]); + textureCoords2D(0)->push_back({1.0f, startTextureCoordsV + i*textureCoordsVIncrement}); + } + } +} + +void Spheroid::cylinderVertexRings(UnsignedInt count, Float startY, Float yIncrement, Float startTextureCoordsV, Float textureCoordsVIncrement) { + Rad segmentAngleIncrement(2*Constants::pi()/segments); + for(UnsignedInt i = 0; i != count; ++i) { + for(UnsignedInt j = 0; j != segments; ++j) { + Rad segmentAngle = j*segmentAngleIncrement; + positions(0)->push_back({Math::sin(segmentAngle), startY, Math::cos(segmentAngle)}); + normals(0)->push_back({Math::sin(segmentAngle), 0.0f, Math::cos(segmentAngle)}); + + if(textureCoords == TextureCoords::Generate) + textureCoords2D(0)->push_back({j*1.0f/segments, startTextureCoordsV + i*textureCoordsVIncrement}); + } + + /* Duplicate first segment in the ring for additional vertex for texture coordinate */ + if(textureCoords == TextureCoords::Generate) { + positions(0)->push_back((*positions(0))[positions(0)->size()-segments]); + normals(0)->push_back((*normals(0))[normals(0)->size()-segments]); + textureCoords2D(0)->push_back({1.0f, startTextureCoordsV + i*textureCoordsVIncrement}); + } + + startY += yIncrement; + } +} + +void Spheroid::bottomFaceRing() { + for(UnsignedInt j = 0; j != segments; ++j) { + /* Bottom vertex */ + indices()->push_back(0); + + /* Top right vertex */ + indices()->push_back((j != segments-1 || textureCoords == TextureCoords::Generate) ? + j+2 : 1); + + /* Top left vertex */ + indices()->push_back(j+1); + } +} + +void Spheroid::faceRings(UnsignedInt count, UnsignedInt offset) { + UnsignedInt vertexSegments = segments + (textureCoords == TextureCoords::Generate ? 1 : 0); + + for(UnsignedInt i = 0; i != count; ++i) { + for(UnsignedInt j = 0; j != segments; ++j) { + UnsignedInt bottomLeft = i*vertexSegments+j+offset; + UnsignedInt bottomRight = ((j != segments-1 || textureCoords == TextureCoords::Generate) ? + i*vertexSegments+j+1+offset : i*segments+offset); + UnsignedInt topLeft = bottomLeft+vertexSegments; + UnsignedInt topRight = bottomRight+vertexSegments; + + indices()->push_back(bottomLeft); + indices()->push_back(bottomRight); + indices()->push_back(topRight); + indices()->push_back(bottomLeft); + indices()->push_back(topRight); + indices()->push_back(topLeft); + } + } +} + +void Spheroid::topFaceRing() { + UnsignedInt vertexSegments = segments + (textureCoords == TextureCoords::Generate ? 1 : 0); + + for(UnsignedInt j = 0; j != segments; ++j) { + /* Bottom left vertex */ + indices()->push_back(normals(0)->size()-vertexSegments+j-1); + + /* Bottom right vertex */ + indices()->push_back((j != segments-1 || textureCoords == TextureCoords::Generate) ? + normals(0)->size()-vertexSegments+j : normals(0)->size()-segments-1); + + /* Top vertex */ + indices()->push_back(normals(0)->size()-1); + } +} + +void Spheroid::capVertexRing(Float y, Float textureCoordsV, const Vector3& normal) { + Rad segmentAngleIncrement(2*Constants::pi()/segments); + + for(UnsignedInt i = 0; i != segments; ++i) { + Rad segmentAngle = i*segmentAngleIncrement; + positions(0)->push_back({Math::sin(segmentAngle), y, Math::cos(segmentAngle)}); + normals(0)->push_back(normal); + + if(textureCoords == TextureCoords::Generate) + textureCoords2D(0)->push_back({i*1.0f/segments, textureCoordsV}); + } + + /* Duplicate first segment in the ring for additional vertex for texture coordinate */ + if(textureCoords == TextureCoords::Generate) { + positions(0)->push_back((*positions(0))[positions(0)->size()-segments]); + normals(0)->push_back(normal); + textureCoords2D(0)->push_back({1.0f, textureCoordsV}); + } +} + +}}} diff --git a/src/Primitives/Implementation/Spheroid.h b/src/Primitives/Implementation/Spheroid.h new file mode 100644 index 000000000..9a3f89203 --- /dev/null +++ b/src/Primitives/Implementation/Spheroid.h @@ -0,0 +1,54 @@ +#ifndef Magnum_Primitives_Spheroid_h +#define Magnum_Primitives_Spheroid_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + 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 "Trade/MeshData3D.h" + +namespace Magnum { namespace Primitives { namespace Implementation { + +class Spheroid: public Trade::MeshData3D { + public: + enum class TextureCoords: UnsignedByte { + DontGenerate, + Generate + }; + + Spheroid(UnsignedInt segments, TextureCoords textureCoords); + + void capVertex(Float y, Float normalY, Float textureCoordsV); + void hemisphereVertexRings(UnsignedInt count, Float centerY, Rad startRingAngle, Rad ringAngleIncrement, Float startTextureCoordsV, Float textureCoordsVIncrement); + void cylinderVertexRings(UnsignedInt count, Float startY, Float yIncrement, Float startTextureCoordsV, Float textureCoordsVIncrement); + void bottomFaceRing(); + void faceRings(UnsignedInt count, UnsignedInt offset = 1); + void topFaceRing(); + void capVertexRing(Float y, Float textureCoordsV, const Vector3& normal); + + UnsignedInt segments; + TextureCoords textureCoords; +}; + +}}} + +#endif diff --git a/src/Primitives/Test/CapsuleTest.cpp b/src/Primitives/Test/CapsuleTest.cpp index 3d74a2680..56b5bc569 100644 --- a/src/Primitives/Test/CapsuleTest.cpp +++ b/src/Primitives/Test/CapsuleTest.cpp @@ -29,6 +29,7 @@ #include #include "Math/Vector3.h" +#include "Trade/MeshData3D.h" #include "Primitives/Capsule.h" using Corrade::TestSuite::Compare::Container; @@ -49,7 +50,7 @@ CapsuleTest::CapsuleTest() { } void CapsuleTest::withoutTextureCoords() { - Capsule capsule(2, 2, 3, 1.0f); + Trade::MeshData3D capsule = Capsule::solid(2, 2, 3, 1.0f); CORRADE_COMPARE_AS(*capsule.positions(0), (std::vector{ {0.0f, -1.5f, 0.0f}, @@ -114,7 +115,7 @@ void CapsuleTest::withoutTextureCoords() { } void CapsuleTest::withTextureCoords() { - Capsule capsule(2, 2, 3, 1.0f, Capsule::TextureCoords::Generate); + Trade::MeshData3D capsule = Capsule::solid(2, 2, 3, 1.0f, Capsule::TextureCoords::Generate); CORRADE_COMPARE_AS(*capsule.positions(0), (std::vector{ {0.0f, -1.5f, 0.0f}, diff --git a/src/Primitives/Test/CylinderTest.cpp b/src/Primitives/Test/CylinderTest.cpp index 938162fab..ef861c206 100644 --- a/src/Primitives/Test/CylinderTest.cpp +++ b/src/Primitives/Test/CylinderTest.cpp @@ -27,6 +27,7 @@ #include "Math/Vector3.h" #include "Primitives/Cylinder.h" +#include "Trade/MeshData3D.h" using Corrade::TestSuite::Compare::Container; @@ -46,7 +47,7 @@ CylinderTest::CylinderTest() { } void CylinderTest::withoutAnything() { - Cylinder cylinder(2, 3, 3.0f); + Trade::MeshData3D cylinder = Cylinder::solid(2, 3, 3.0f); CORRADE_COMPARE_AS(*cylinder.positions(0), (std::vector{ {0.0f, -1.5f, 1.0f}, @@ -83,7 +84,7 @@ void CylinderTest::withoutAnything() { } void CylinderTest::withTextureCoordsAndCaps() { - Cylinder cylinder(2, 3, 3.0f, Cylinder::Flag::GenerateTextureCoords|Cylinder::Flag::CapEnds); + Trade::MeshData3D cylinder = Cylinder::solid(2, 3, 3.0f, Cylinder::Flag::GenerateTextureCoords|Cylinder::Flag::CapEnds); CORRADE_COMPARE_AS(*cylinder.positions(0), (std::vector{ {0.0f, -1.5f, 0.0f}, diff --git a/src/Primitives/Test/UVSphereTest.cpp b/src/Primitives/Test/UVSphereTest.cpp index beaa6b46f..93cb2ff1f 100644 --- a/src/Primitives/Test/UVSphereTest.cpp +++ b/src/Primitives/Test/UVSphereTest.cpp @@ -27,6 +27,7 @@ #include "Math/Vector3.h" #include "Primitives/UVSphere.h" +#include "Trade/MeshData3D.h" using Corrade::TestSuite::Compare::Container; @@ -46,7 +47,7 @@ UVSphereTest::UVSphereTest() { } void UVSphereTest::withoutTextureCoords() { - UVSphere sphere(3, 3); + Trade::MeshData3D sphere = UVSphere::solid(3, 3); CORRADE_COMPARE_AS(*sphere.positions(0), (std::vector{ {0.0f, -1.0f, 0.0f}, @@ -84,7 +85,7 @@ void UVSphereTest::withoutTextureCoords() { } void UVSphereTest::withTextureCoords() { - UVSphere sphere(3, 3, UVSphere::TextureCoords::Generate); + Trade::MeshData3D sphere = UVSphere::solid(3, 3, UVSphere::TextureCoords::Generate); CORRADE_COMPARE_AS(*sphere.positions(0), (std::vector{ {0.0f, -1.0f, 0.0f}, diff --git a/src/Primitives/UVSphere.cpp b/src/Primitives/UVSphere.cpp index b6cde4ca3..5ec1d72c5 100644 --- a/src/Primitives/UVSphere.cpp +++ b/src/Primitives/UVSphere.cpp @@ -25,28 +25,35 @@ #include "UVSphere.h" #include "Math/Angle.h" +#include "Implementation/Spheroid.h" namespace Magnum { namespace Primitives { -UVSphere::UVSphere(UnsignedInt rings, UnsignedInt segments, TextureCoords textureCoords): Capsule(segments, textureCoords) { - CORRADE_ASSERT(rings >= 2 && segments >= 3, "UVSphere must have at least two rings and three segments", ); +Trade::MeshData3D UVSphere::solid(UnsignedInt rings, UnsignedInt segments, TextureCoords textureCoords) { + CORRADE_ASSERT(rings >= 2 && segments >= 3, "UVSphere must have at least two rings and three segments", Trade::MeshData3D(Mesh::Primitive::Triangles, nullptr, {}, {}, {})); + + Implementation::Spheroid sphere(segments, textureCoords == TextureCoords::Generate ? + Implementation::Spheroid::TextureCoords::Generate : + Implementation::Spheroid::TextureCoords::DontGenerate); Float textureCoordsVIncrement = 1.0f/rings; Rad ringAngleIncrement(Constants::pi()/rings); /* Bottom cap vertex */ - capVertex(-1.0f, -1.0f, 0.0f); + sphere.capVertex(-1.0f, -1.0f, 0.0f); /* Vertex rings */ - hemisphereVertexRings(rings-1, 0.0f, -Rad(Constants::pi())/2+ringAngleIncrement, ringAngleIncrement, textureCoordsVIncrement, textureCoordsVIncrement); + sphere.hemisphereVertexRings(rings-1, 0.0f, -Rad(Constants::pi())/2+ringAngleIncrement, ringAngleIncrement, textureCoordsVIncrement, textureCoordsVIncrement); /* Top cap vertex */ - capVertex(1.0f, 1.0f, 1.0f); + sphere.capVertex(1.0f, 1.0f, 1.0f); /* Faces */ - bottomFaceRing(); - faceRings(rings-2); - topFaceRing(); + sphere.bottomFaceRing(); + sphere.faceRings(rings-2); + sphere.topFaceRing(); + + return std::move(sphere); } }} diff --git a/src/Primitives/UVSphere.h b/src/Primitives/UVSphere.h index 8b6266c45..7cfb75b94 100644 --- a/src/Primitives/UVSphere.h +++ b/src/Primitives/UVSphere.h @@ -28,30 +28,37 @@ * @brief Class Magnum::Primitives::UVSphere */ -#include "Primitives/Capsule.h" - #include "Primitives/magnumPrimitivesVisibility.h" +#include "Trade/Trade.h" namespace Magnum { namespace Primitives { /** @brief 3D UV sphere primitive -Indexed @ref Mesh::Primitive "Triangles" with normals and optional 2D texture -coordinates. +Sphere with radius `1`. */ -class UVSphere: public Capsule { +class MAGNUM_PRIMITIVES_EXPORT UVSphere { public: + /** @brief Whether to generate texture coordinates */ + enum class TextureCoords: UnsignedByte { + Generate, /**< Generate texture coordinates */ + DontGenerate /**< Don't generate texture coordinates */ + }; + /** - * @brief Constructor - * @param rings Number of (face) rings. Must be larger or equal to 2. - * @param segments Number of (face) segments. Must be larger or equal to 3. + * @brief Solid UV sphere + * @param rings Number of (face) rings. Must be larger or equal + * to 2. + * @param segments Number of (face) segments. Must be larger or + * equal to 3. * @param textureCoords Whether to generate texture coordinates. * - * If texture coordinates are generated, vertices of one segment are - * duplicated for texture wrapping. + * Indexed @ref Mesh::Primitive "Triangles" with normals and optional + * 2D texture coordinates. If texture coordinates are generated, + * vertices of one segment are duplicated for texture wrapping. */ - explicit MAGNUM_PRIMITIVES_EXPORT UVSphere(UnsignedInt rings, UnsignedInt segments, TextureCoords textureCoords = TextureCoords::DontGenerate); + static Trade::MeshData3D solid(UnsignedInt rings, UnsignedInt segments, TextureCoords textureCoords = TextureCoords::DontGenerate); }; }} diff --git a/src/Primitives/magnumPrimitivesVisibility.h b/src/Primitives/magnumPrimitivesVisibility.h index 13a5c93cb..0acf6cf82 100644 --- a/src/Primitives/magnumPrimitivesVisibility.h +++ b/src/Primitives/magnumPrimitivesVisibility.h @@ -24,14 +24,12 @@ DEALINGS IN THE SOFTWARE. */ -#ifdef _WIN32 - #ifdef MagnumPrimitives_EXPORTS - #define MAGNUM_PRIMITIVES_EXPORT __declspec(dllexport) - #else - #define MAGNUM_PRIMITIVES_EXPORT __declspec(dllimport) - #endif +#include + +#ifdef MagnumPrimitives_EXPORTS + #define MAGNUM_PRIMITIVES_EXPORT CORRADE_VISIBILITY_EXPORT #else - #define MAGNUM_PRIMITIVES_EXPORT __attribute__ ((visibility ("default"))) + #define MAGNUM_PRIMITIVES_EXPORT CORRADE_VISIBILITY_IMPORT #endif #endif diff --git a/src/SceneGraph/Object.hpp b/src/SceneGraph/Object.hpp index 7282b2d5f..59516ab9b 100644 --- a/src/SceneGraph/Object.hpp +++ b/src/SceneGraph/Object.hpp @@ -142,7 +142,9 @@ template void Object::setClean() { /* Compose transformation and clean object */ absoluteTransformation = Transformation::compose(absoluteTransformation, o->transformation()); + CORRADE_INTERNAL_ASSERT(o->isDirty()); o->setClean(absoluteTransformation); + CORRADE_ASSERT(!o->isDirty(), "SceneGraph::Object::setClean(): original implementation was not called", ); } } @@ -344,8 +346,11 @@ template void Object::setClean(std::vector std::vector transformations(scene->transformations(objects)); /* Go through all objects and clean them */ - for(std::size_t i = 0; i != objects.size(); ++i) + for(std::size_t i = 0; i != objects.size(); ++i) { + CORRADE_INTERNAL_ASSERT(objects[i]->isDirty()); objects[i]->setClean(transformations[i]); + CORRADE_ASSERT(!objects[i]->isDirty(), "SceneGraph::Object::setClean(): original implementation was not called", ); + } } template void Object::setClean(const typename Transformation::DataType& absoluteTransformation) { diff --git a/src/SceneGraph/magnumSceneGraphVisibility.h b/src/SceneGraph/magnumSceneGraphVisibility.h index b4b023eef..366634198 100644 --- a/src/SceneGraph/magnumSceneGraphVisibility.h +++ b/src/SceneGraph/magnumSceneGraphVisibility.h @@ -24,16 +24,13 @@ DEALINGS IN THE SOFTWARE. */ -#ifdef _WIN32 - #if defined(MagnumSceneGraph_EXPORTS) || defined(MagnumSceneGraphObjects_EXPORTS) - #define MAGNUM_SCENEGRAPH_EXPORT __declspec(dllexport) - #else - #define MAGNUM_SCENEGRAPH_EXPORT __declspec(dllimport) - #endif - #define MAGNUM_SCENEGRAPH_LOCAL +#include + +#if defined(MagnumSceneGraph_EXPORTS) || defined(MagnumSceneGraphObjects_EXPORTS) + #define MAGNUM_SCENEGRAPH_EXPORT CORRADE_VISIBILITY_EXPORT #else - #define MAGNUM_SCENEGRAPH_EXPORT __attribute__ ((visibility ("default"))) - #define MAGNUM_SCENEGRAPH_LOCAL __attribute__ ((visibility ("hidden"))) + #define MAGNUM_SCENEGRAPH_EXPORT CORRADE_VISIBILITY_IMPORT #endif +#define MAGNUM_SCENEGRAPH_LOCAL CORRADE_VISIBILITY_LOCAL #endif diff --git a/src/Shader.cpp b/src/Shader.cpp index 741d2b3c3..64e3679e5 100644 --- a/src/Shader.cpp +++ b/src/Shader.cpp @@ -59,7 +59,7 @@ Shader::Shader(Version version, Type type): _type(type), _state(State::Initializ CORRADE_ASSERT(false, "Shader::Shader(): unsupported version" << version, ); } - CORRADE_INTERNAL_ASSERT(false); + CORRADE_ASSERT_UNREACHABLE(); } Shader::Shader(Shader&& other): _type(other._type), _state(other._state), sources(other.sources), shader(other.shader) { diff --git a/src/Shaders/magnumShadersVisibility.h b/src/Shaders/magnumShadersVisibility.h index 238ddeb04..93c270176 100644 --- a/src/Shaders/magnumShadersVisibility.h +++ b/src/Shaders/magnumShadersVisibility.h @@ -24,14 +24,12 @@ DEALINGS IN THE SOFTWARE. */ -#ifdef _WIN32 - #ifdef MagnumShaders_EXPORTS - #define MAGNUM_SHADERS_EXPORT __declspec(dllexport) - #else - #define MAGNUM_SHADERS_EXPORT __declspec(dllimport) - #endif +#include + +#ifdef MagnumShaders_EXPORTS + #define MAGNUM_SHADERS_EXPORT CORRADE_VISIBILITY_EXPORT #else - #define MAGNUM_SHADERS_EXPORT __attribute__ ((visibility ("default"))) + #define MAGNUM_SHADERS_EXPORT CORRADE_VISIBILITY_IMPORT #endif #endif diff --git a/src/Text/AbstractFont.h b/src/Text/AbstractFont.h index df2d06437..495af5f5e 100644 --- a/src/Text/AbstractFont.h +++ b/src/Text/AbstractFont.h @@ -96,7 +96,7 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public Corrade::PluginManager::AbstractPl * * Fills the cache with given characters. */ - virtual void createGlyphCache(GlyphCache* const cache, const std::string& characters) = 0; + virtual void createGlyphCache(GlyphCache* cache, const std::string& characters) = 0; /** * @brief Layout the text using font own layouter @@ -106,7 +106,7 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public Corrade::PluginManager::AbstractPl * * @see createGlyphCache() */ - virtual AbstractLayouter* layout(const GlyphCache* const cache, const Float size, const std::string& text) = 0; + virtual AbstractLayouter* layout(const GlyphCache* cache, Float size, const std::string& text) = 0; #ifdef DOXYGEN_GENERATING_OUTPUT private: @@ -144,7 +144,7 @@ class MAGNUM_TEXT_EXPORT AbstractLayouter { * Returns quad position, texture coordinates and advance to next * glyph. */ - virtual std::tuple renderGlyph(const Vector2& cursorPosition, const UnsignedInt i) = 0; + virtual std::tuple renderGlyph(const Vector2& cursorPosition, UnsignedInt i) = 0; #ifdef DOXYGEN_GENERATING_OUTPUT private: diff --git a/src/Text/DistanceFieldGlyphCache.h b/src/Text/DistanceFieldGlyphCache.h index 80bcaceba..e9161a95f 100644 --- a/src/Text/DistanceFieldGlyphCache.h +++ b/src/Text/DistanceFieldGlyphCache.h @@ -72,7 +72,7 @@ class MAGNUM_TEXT_EXPORT DistanceFieldGlyphCache: public GlyphCache { * Uploads image for one or more glyphs to given offset in original * cache texture. The texture is then converted to distance field. */ - void setImage(const Vector2i& offset, Image2D* const image) override; + void setImage(const Vector2i& offset, Image2D* image) override; /** * @brief Set distance field cache image @@ -80,7 +80,7 @@ class MAGNUM_TEXT_EXPORT DistanceFieldGlyphCache: public GlyphCache { * Uploads already computed distance field image to given offset in * distance field texture. */ - void setDistanceFieldImage(const Vector2i& offset, Image2D* const image); + void setDistanceFieldImage(const Vector2i& offset, Image2D* image); private: const Vector2 scale; diff --git a/src/Text/GlyphCache.h b/src/Text/GlyphCache.h index 92f91544b..6d452a72c 100644 --- a/src/Text/GlyphCache.h +++ b/src/Text/GlyphCache.h @@ -62,7 +62,7 @@ class MAGNUM_TEXT_EXPORT GlyphCache { * @param size Glyph cache texture size * @param internalFormat Internal texture format */ - explicit GlyphCache(const Vector2i& size, const Texture2D::InternalFormat internalFormat); + explicit GlyphCache(const Vector2i& size, Texture2D::InternalFormat internalFormat); /** * @brief Constructor @@ -97,7 +97,7 @@ class MAGNUM_TEXT_EXPORT GlyphCache { * second element is glyph region in texture atlas. If no glyph is * found, glyph on zero index is returned. */ - inline std::pair operator[](const UnsignedInt glyph) const { + inline std::pair operator[](UnsignedInt glyph) const { auto it = glyphs.find(glyph); return it == glyphs.end() ? glyphs.at(0) : it->second; } @@ -124,7 +124,7 @@ class MAGNUM_TEXT_EXPORT GlyphCache { * You can obtain unused non-overlapping regions with reserve(). See * also setImage() to upload glyph image. */ - void insert(const UnsignedInt glyph, Vector2i position, Rectanglei rectangle); + void insert(UnsignedInt glyph, Vector2i position, Rectanglei rectangle); /** * @brief Set cache image @@ -132,7 +132,7 @@ class MAGNUM_TEXT_EXPORT GlyphCache { * Uploads image for one or more glyphs to given offset in cache * texture. */ - virtual void setImage(const Vector2i& offset, Image2D* const image); + virtual void setImage(const Vector2i& offset, Image2D* image); #ifdef DOXYGEN_GENERATING_OUTPUT private: @@ -142,7 +142,7 @@ class MAGNUM_TEXT_EXPORT GlyphCache { /* Used from DistanceFieldGlyphCache */ explicit MAGNUM_LOCAL GlyphCache(const Vector2i& size, const Vector2i& padding); - void MAGNUM_LOCAL initialize(const Texture2D::InternalFormat internalFormat, const Vector2i& size); + void MAGNUM_LOCAL initialize(Texture2D::InternalFormat internalFormat, const Vector2i& size); const Vector2i _size; Texture2D _texture; diff --git a/src/Text/TextRenderer.h b/src/Text/TextRenderer.h index 2d722f681..b4f470723 100644 --- a/src/Text/TextRenderer.h +++ b/src/Text/TextRenderer.h @@ -60,7 +60,7 @@ class MAGNUM_TEXT_EXPORT AbstractTextRenderer { * Returns tuple with vertex positions, texture coordinates, indices * and rectangle spanning the rendered text. */ - static std::tuple, std::vector, std::vector, Rectangle> render(AbstractFont* const font, const GlyphCache* const cache, Float size, const std::string& text); + static std::tuple, std::vector, std::vector, Rectangle> render(AbstractFont* font, const GlyphCache* cache, Float size, const std::string& text); /** * @brief Constructor @@ -68,7 +68,7 @@ class MAGNUM_TEXT_EXPORT AbstractTextRenderer { * @param cache Glyph cache * @param size Font size */ - explicit AbstractTextRenderer(AbstractFont* const font, const GlyphCache* const cache, Float size); + explicit AbstractTextRenderer(AbstractFont* font, const GlyphCache* cache, Float size); virtual ~AbstractTextRenderer() = 0; @@ -97,7 +97,7 @@ class MAGNUM_TEXT_EXPORT AbstractTextRenderer { * Initially zero capacity is reserved. * @see capacity() */ - void reserve(const UnsignedInt glyphCount, const Buffer::Usage vertexBufferUsage, const Buffer::Usage indexBufferUsage); + void reserve(UnsignedInt glyphCount, Buffer::Usage vertexBufferUsage, Buffer::Usage indexBufferUsage); /** * @brief Render text @@ -117,7 +117,7 @@ class MAGNUM_TEXT_EXPORT AbstractTextRenderer { #else private: #endif - static std::tuple MAGNUM_LOCAL render(AbstractFont* const font, const GlyphCache* const cache, Float size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage); + static std::tuple MAGNUM_LOCAL render(AbstractFont* font, const GlyphCache* cache, Float size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage); Mesh _mesh; Buffer vertexBuffer, indexBuffer; diff --git a/src/Text/magnumTextVisibility.h b/src/Text/magnumTextVisibility.h index a5608044a..b69855471 100644 --- a/src/Text/magnumTextVisibility.h +++ b/src/Text/magnumTextVisibility.h @@ -24,16 +24,13 @@ DEALINGS IN THE SOFTWARE. */ -#ifdef _WIN32 - #ifdef MagnumText_EXPORTS - #define MAGNUM_TEXT_EXPORT __declspec(dllexport) - #else - #define MAGNUM_TEXT_EXPORT __declspec(dllimport) - #endif - #define MAGNUM_TEXT_LOCAL +#include + +#ifdef MagnumText_EXPORTS + #define MAGNUM_TEXT_EXPORT CORRADE_VISIBILITY_EXPORT #else - #define MAGNUM_TEXT_EXPORT __attribute__ ((visibility ("default"))) - #define MAGNUM_TEXT_LOCAL __attribute__ ((visibility ("hidden"))) + #define MAGNUM_TEXT_EXPORT CORRADE_VISIBILITY_IMPORT #endif +#define MAGNUM_TEXT_LOCAL CORRADE_VISIBILITY_LOCAL #endif diff --git a/src/TextureTools/DistanceField.h b/src/TextureTools/DistanceField.h index a88ab940e..dfe8c409d 100644 --- a/src/TextureTools/DistanceField.h +++ b/src/TextureTools/DistanceField.h @@ -67,7 +67,7 @@ http://www.valvesoftware.com/publications/2007/SIGGRAPH2007_AlphaTestedMagnifica @attention This is GPU-only implementation, so it expects active context. */ -void MAGNUM_TEXTURETOOLS_EXPORT distanceField(Texture2D* input, Texture2D* output, const Rectanglei& rectangle, const Int radius); +void MAGNUM_TEXTURETOOLS_EXPORT distanceField(Texture2D* input, Texture2D* output, const Rectanglei& rectangle, Int radius); }} diff --git a/src/TextureTools/magnumTextureToolsVisibility.h b/src/TextureTools/magnumTextureToolsVisibility.h index ad0dbb333..30f40eb1c 100644 --- a/src/TextureTools/magnumTextureToolsVisibility.h +++ b/src/TextureTools/magnumTextureToolsVisibility.h @@ -24,14 +24,12 @@ DEALINGS IN THE SOFTWARE. */ -#ifdef _WIN32 - #ifdef MagnumTextureTools_EXPORTS - #define MAGNUM_TEXTURETOOLS_EXPORT __declspec(dllexport) - #else - #define MAGNUM_TEXTURETOOLS_EXPORT __declspec(dllimport) - #endif +#include + +#ifdef MagnumTextureTools_EXPORTS + #define MAGNUM_TEXTURETOOLS_EXPORT CORRADE_VISIBILITY_EXPORT #else - #define MAGNUM_TEXTURETOOLS_EXPORT __attribute__ ((visibility ("default"))) + #define MAGNUM_TEXTURETOOLS_EXPORT CORRADE_VISIBILITY_IMPORT #endif #endif diff --git a/src/Trade/AbstractImageConverter.h b/src/Trade/AbstractImageConverter.h index 5434618db..b0870c87b 100644 --- a/src/Trade/AbstractImageConverter.h +++ b/src/Trade/AbstractImageConverter.h @@ -91,7 +91,7 @@ class MAGNUM_EXPORT AbstractImageConverter: public Corrade::PluginManager::Abstr * Returns converted image on success, `nullptr` otherwise. * @see features(), convertToData(), convertToFile() */ - virtual Image2D* convertToImage(const Image2D* const image) const; + virtual Image2D* convertToImage(const Image2D* image) const; /** * @brief Convert image to raw data @@ -100,7 +100,7 @@ class MAGNUM_EXPORT AbstractImageConverter: public Corrade::PluginManager::Abstr * Returns data pointer and size on success, `nullptr` otherwise. * @see features(), convertToImage(), convertToFile() */ - virtual std::pair convertToData(const Image2D* const image) const; + virtual std::pair convertToData(const Image2D* image) const; /** * @brief Convert image and save it to file @@ -109,7 +109,7 @@ class MAGNUM_EXPORT AbstractImageConverter: public Corrade::PluginManager::Abstr * Returns `true` on success, `false` otherwise. * @see features(), convertToImage(), convertToData() */ - virtual bool convertToFile(const Image2D* const image, const std::string& filename) const; + virtual bool convertToFile(const Image2D* image, const std::string& filename) const; }; CORRADE_ENUMSET_OPERATORS(AbstractImageConverter::Features) diff --git a/src/Trade/MeshData2D.cpp b/src/Trade/MeshData2D.cpp index 96ec803ba..98c649596 100644 --- a/src/Trade/MeshData2D.cpp +++ b/src/Trade/MeshData2D.cpp @@ -30,26 +30,17 @@ namespace Magnum { namespace Trade { MeshData2D::MeshData2D(Mesh::Primitive primitive, std::vector* indices, std::vector*> positions, std::vector*> textureCoords2D): _primitive(primitive), _indices(indices), _positions(std::move(positions)), _textureCoords2D(std::move(textureCoords2D)) {} -#ifndef CORRADE_GCC44_COMPATIBILITY -MeshData2D::MeshData2D(MeshData2D&&) = default; -#else MeshData2D::MeshData2D(MeshData2D&& other): _primitive(other._primitive), _indices(other._indices), _positions(std::move(other._positions)), _textureCoords2D(std::move(other._textureCoords2D)) { other._indices = nullptr; } -#endif -#ifndef CORRADE_GCC45_COMPATIBILITY -MeshData2D& MeshData2D::operator=(MeshData2D&&) = default; -#else MeshData2D& MeshData2D::operator=(MeshData2D&& other) { - std::swap(_primitive, other._primitive); + _primitive = other._primitive; std::swap(_indices, other._indices); std::swap(_positions, other._positions); std::swap(_textureCoords2D, other._textureCoords2D); - return *this; } -#endif MeshData2D::~MeshData2D() { delete _indices; diff --git a/src/Trade/MeshData3D.cpp b/src/Trade/MeshData3D.cpp index c619a5ae8..a2904dbd3 100644 --- a/src/Trade/MeshData3D.cpp +++ b/src/Trade/MeshData3D.cpp @@ -30,27 +30,18 @@ namespace Magnum { namespace Trade { MeshData3D::MeshData3D(Mesh::Primitive primitive, std::vector* indices, std::vector*> positions, std::vector*> normals, std::vector*> textureCoords2D): _primitive(primitive), _indices(indices), _positions(std::move(positions)), _normals(std::move(normals)), _textureCoords2D(std::move(textureCoords2D)) {} -#ifndef CORRADE_GCC44_COMPATIBILITY -MeshData3D::MeshData3D(MeshData3D&&) = default; -#else MeshData3D::MeshData3D(MeshData3D&& other): _primitive(other._primitive), _indices(other._indices), _positions(std::move(other._positions)), _normals(std::move(other._normals)), _textureCoords2D(std::move(other._textureCoords2D)) { other._indices = nullptr; } -#endif -#ifndef CORRADE_GCC45_COMPATIBILITY -MeshData3D& MeshData3D::operator=(MeshData3D&&) = default; -#else MeshData3D& MeshData3D::operator=(MeshData3D&& other) { - std::swap(_primitive, other._primitive); + _primitive = other._primitive; std::swap(_indices, other._indices); std::swap(_positions, other._positions); std::swap(_normals, other._normals); std::swap(_textureCoords2D, other._textureCoords2D); - return *this; } -#endif MeshData3D::~MeshData3D() { delete _indices; diff --git a/src/magnumVisibility.h b/src/magnumVisibility.h index c23a8066b..60e1f8cca 100644 --- a/src/magnumVisibility.h +++ b/src/magnumVisibility.h @@ -24,16 +24,13 @@ DEALINGS IN THE SOFTWARE. */ -#ifdef _WIN32 - #if defined(Magnum_EXPORTS) || defined(MagnumObjects_EXPORTS) - #define MAGNUM_EXPORT __declspec(dllexport) - #else - #define MAGNUM_EXPORT __declspec(dllimport) - #endif - #define MAGNUM_LOCAL +#include + +#if defined(Magnum_EXPORTS) || defined(MagnumObjects_EXPORTS) + #define MAGNUM_EXPORT CORRADE_VISIBILITY_EXPORT #else - #define MAGNUM_EXPORT __attribute__ ((visibility ("default"))) - #define MAGNUM_LOCAL __attribute__ ((visibility ("hidden"))) + #define MAGNUM_EXPORT CORRADE_VISIBILITY_IMPORT #endif +#define MAGNUM_LOCAL CORRADE_VISIBILITY_LOCAL #endif