diff --git a/src/BufferedTexture.cpp b/src/BufferedTexture.cpp new file mode 100644 index 000000000..edd88e000 --- /dev/null +++ b/src/BufferedTexture.cpp @@ -0,0 +1,52 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include "BufferedTexture.h" + +namespace Magnum { + +BufferedTexture::InternalFormat::InternalFormat(Components components, ComponentType type) { + #define internalFormatSwitch(c) switch(type) { \ + case ComponentType::UnsignedByte: \ + internalFormat = GL_##c##8UI; break; \ + case ComponentType::Byte: \ + internalFormat = GL_##c##8I; break; \ + case ComponentType::UnsignedShort: \ + internalFormat = GL_##c##16UI; break; \ + case ComponentType::Short: \ + internalFormat = GL_##c##16I; break; \ + case ComponentType::UnsignedInt: \ + internalFormat = GL_##c##32UI; break; \ + case ComponentType::Int: \ + internalFormat = GL_##c##32I; break; \ + case ComponentType::Half: \ + internalFormat = GL_##c##16F; break; \ + case ComponentType::Float: \ + internalFormat = GL_##c##32F; break; \ + case ComponentType::NormalizedUnsignedByte: \ + internalFormat = GL_##c##8; break; \ + case ComponentType::NormalizedUnsignedShort: \ + internalFormat = GL_##c##16; break; \ + } + if(components == Components::Red) + internalFormatSwitch(R) + else if(components == Components::RedGreen) + internalFormatSwitch(RG) + else if(components == Components::RGBA) + internalFormatSwitch(RGBA) + #undef internalFormatSwitch +} + +} diff --git a/src/BufferedTexture.h b/src/BufferedTexture.h index b53ce7c82..d4ee3a939 100644 --- a/src/BufferedTexture.h +++ b/src/BufferedTexture.h @@ -45,11 +45,63 @@ class BufferedTexture { BufferedTexture& operator=(BufferedTexture&& other) = delete; public: + /** @{ @name Internal buffered texture formats */ + /** @copydoc Renderbuffer::Components */ - typedef Renderbuffer::Components Components; + enum class Components { + Red, RedGreen, RGBA + }; /** @copydoc Renderbuffer::ComponentType */ - typedef Renderbuffer::ComponentType ComponentType; + enum class ComponentType { + UnsignedByte, Byte, UnsignedShort, Short, UnsignedInt, Int, Half, + Float, NormalizedUnsignedByte, NormalizedUnsignedShort + }; + + /** @copydoc AbstractTexture::Format */ + enum class Format: GLenum { + /** + * Three-component RGB, float, each component 32bit, 96bit total. + * + * @requires_gl40 Extension ARB_texture_buffer_object_rgb32 + */ + RGB32Float = GL_RGB32F, + + /** + * Three-component RGB, unsigned non-normalized, each component + * 32bit, 96bit total. + * + * @requires_gl40 Extension ARB_texture_buffer_object_rgb32 + */ + RGB32UnsignedInt = GL_RGB32UI, + + /** + * Three-component RGB, signed non-normalized, each component + * 32bit, 96bit total. + * + * @requires_gl40 Extension ARB_texture_buffer_object_rgb32 + */ + RGB32Int = GL_RGB32I + }; + + /** @copydoc AbstractTexture::InternalFormat */ + class MAGNUM_EXPORT InternalFormat { + public: + /** @copydoc AbstractTexture::InternalFormat::InternalFormat(AbstractTexture::Components, AbstractTexture::ComponentType) */ + InternalFormat(Components components, ComponentType type); + + /** @copydoc AbstractTexture::InternalFormat::InternalFormat(AbstractTexture::Format) */ + inline constexpr InternalFormat(Format format): internalFormat(static_cast(format)) {} + + /** @brief OpenGL internal format ID */ + /* doxygen: @copydoc AbstractTexture::InternalFormat::operator GLint() doesn't work */ + inline constexpr operator GLint() const { return internalFormat; } + + private: + GLint internalFormat; + }; + + /*@}*/ /** * @brief Constructor @@ -76,17 +128,16 @@ class BufferedTexture { /** * @brief Set texture buffer - * @param components Component count - * @param type Data type per component - * @param buffer %Buffer with data + * @param internalFormat Internal format + * @param buffer %Buffer with data * * Binds given buffer to this texture. The buffer itself can be then * filled with data of proper format at any time using Buffer own data * setting functions. */ - void setBuffer(Components components, ComponentType type, Buffer* buffer) { + void setBuffer(InternalFormat internalFormat, Buffer* buffer) { bind(); - glTexBuffer(GL_TEXTURE_BUFFER, components|type, buffer->id()); + glTexBuffer(GL_TEXTURE_BUFFER, internalFormat, buffer->id()); } private: @@ -94,6 +145,15 @@ class BufferedTexture { GLuint texture; }; +/** @copydoc operator|(AbstractTexture::Components, AbstractTexture::ComponentType) */ +inline BufferedTexture::InternalFormat operator|(BufferedTexture::Components components, BufferedTexture::ComponentType type) { + return BufferedTexture::InternalFormat(components, type); +} +/** @copydoc operator|(AbstractTexture::ComponentType, AbstractTexture::Components) */ +inline BufferedTexture::InternalFormat operator|(BufferedTexture::ComponentType type, BufferedTexture::Components components) { + return BufferedTexture::InternalFormat(components, type); +} + } #endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3883a5f9b..4628ede79 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -13,6 +13,7 @@ set(Magnum_SRCS AbstractImage.cpp AbstractTexture.cpp AbstractShaderProgram.cpp + BufferedTexture.cpp Camera.cpp Framebuffer.cpp IndexedMesh.cpp