Browse Source

Support for object labels from KHR_debug and EXT_debug_label.

Can't test EXT_debug_label, as that is apparently OSX 10.9-only. Added
GL tests for all implemented objects. KHR_debug is selected first, if
that is not available, fall back to EXT_debug_label. If neither is
available, the functions are no-op.

I hope EXT_debug_label gets replaced by KHR_debug later, thus it is now
only "emulated" through KHR_debug enums.
pull/38/head
Vladimír Vondruš 13 years ago
parent
commit
b2325dda2f
  1. 219
      src/AbstractObject.cpp
  2. 81
      src/AbstractObject.h
  3. 18
      src/AbstractShaderProgram.cpp
  4. 30
      src/AbstractShaderProgram.h
  5. 10
      src/AbstractTexture.cpp
  6. 29
      src/AbstractTexture.h
  7. 18
      src/Buffer.cpp
  8. 31
      src/Buffer.h
  9. 12
      src/BufferTexture.h
  10. 2
      src/CMakeLists.txt
  11. 2
      src/Context.cpp
  12. 4
      src/CubeMapTexture.h
  13. 4
      src/CubeMapTextureArray.h
  14. 10
      src/Framebuffer.cpp
  15. 28
      src/Framebuffer.h
  16. 46
      src/Implementation/DebugState.cpp
  17. 48
      src/Implementation/DebugState.h
  18. 17
      src/Implementation/State.cpp
  19. 8
      src/Implementation/State.h
  20. 18
      src/Mesh.cpp
  21. 28
      src/Mesh.h
  22. 21
      src/Query.cpp
  23. 56
      src/Query.h
  24. 12
      src/Renderbuffer.cpp
  25. 30
      src/Renderbuffer.h
  26. 18
      src/Shader.cpp
  27. 30
      src/Shader.h
  28. 55
      src/Test/AbstractObjectGLTest.cpp
  29. 60
      src/Test/AbstractQueryGLTest.cpp
  30. 65
      src/Test/AbstractShaderProgramGLTest.cpp
  31. 60
      src/Test/AbstractTextureGLTest.cpp
  32. 17
      src/Test/BufferGLTest.cpp
  33. 8
      src/Test/CMakeLists.txt
  34. 62
      src/Test/FramebufferGLTest.cpp
  35. 60
      src/Test/MeshGLTest.cpp
  36. 60
      src/Test/RenderbufferGLTest.cpp
  37. 60
      src/Test/ShaderGLTest.cpp
  38. 4
      src/Texture.h

219
src/AbstractObject.cpp

@ -0,0 +1,219 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include "AbstractObject.h"
#include <Utility/Assert.h>
#include "Extensions.h"
#include "Implementation/State.h"
#include "Implementation/DebugState.h"
namespace Magnum {
namespace {
/* What the hell, Apple? Why you had to create this abomination _after_
KHR_debug was released?! */
inline GLenum extTypeFromKhrIdentifier(GLenum khrIdentifier) {
switch(khrIdentifier) {
#ifndef MAGNUM_TARGET_GLES
case GL_BUFFER:
#else
case GL_BUFFER_KHR:
#endif
return GL_BUFFER_OBJECT_EXT;
#ifndef MAGNUM_TARGET_GLES
case GL_SHADER:
#else
case GL_SHADER_KHR:
#endif
return GL_SHADER_OBJECT_EXT;
#ifndef MAGNUM_TARGET_GLES
case GL_PROGRAM:
#else
case GL_PROGRAM_KHR:
#endif
return GL_PROGRAM_OBJECT_EXT;
#ifndef MAGNUM_TARGET_GLES
case GL_VERTEX_ARRAY:
#else
case GL_VERTEX_ARRAY_KHR:
#endif
return GL_VERTEX_ARRAY_OBJECT_EXT;
#ifndef MAGNUM_TARGET_GLES
case GL_QUERY:
#else
case GL_QUERY_KHR:
#endif
return GL_QUERY_OBJECT_EXT;
/** @todo Why isn't `GL_PROGRAM_PIPELINE_KHR` in ES's KHR_debug? */
#ifndef MAGNUM_TARGET_GLES
case GL_PROGRAM_PIPELINE:
#else
case 0x82E4: //GL_PROGRAM_PIPELINE_KHR:
#endif
return GL_PROGRAM_PIPELINE_OBJECT_EXT;
/**
* @todo Shouldn't ES2's KHR_debug have `GL_TRANSFORM_FEEDBACK_KHR`
* instead of `GL_TRANSFORM_FEEDBACK`? (it's a new enum in 2.0)
*/
case GL_TRANSFORM_FEEDBACK:
#ifndef MAGNUM_TARGET_GLES
case GL_SAMPLER:
#else
case GL_SAMPLER_KHR:
#endif
case GL_TEXTURE:
case GL_RENDERBUFFER:
case GL_FRAMEBUFFER:
return khrIdentifier;
}
CORRADE_ASSERT_UNREACHABLE();
}
}
Int AbstractObject::maxLabelLength() {
if(!Context::current()->isExtensionSupported<Extensions::GL::KHR::debug>())
return 0;
GLint& value = Context::current()->state().debug->maxLabelLength;
if(value == 0) {
#ifndef MAGNUM_TARGET_GLES
glGetIntegerv(GL_MAX_LABEL_LENGTH, &value);
#else
glGetIntegerv(GL_MAX_LABEL_LENGTH_KHR, &value);
#endif
}
return value;
}
void AbstractObject::labelImplementationNoOp(GLenum, GLuint, const std::string&) {}
void AbstractObject::labelImplementationKhr(const GLenum identifier, const GLuint name, const std::string& label) {
#ifndef MAGNUM_TARGET_GLES
glObjectLabel(identifier, name, label.size(), label.data());
#else
static_cast<void>(identifier);
static_cast<void>(name);
static_cast<void>(label);
CORRADE_INTERNAL_ASSERT(false);
//glObjectLabelKHR(identifier, name, label.size(), label.data());
#endif
}
void AbstractObject::labelImplementationExt(const GLenum identifier, const GLuint name, const std::string& label) {
const GLenum type = extTypeFromKhrIdentifier(identifier);
/** @todo Re-enable when extension wrangler is available for ES */
#ifndef MAGNUM_TARGET_GLES
glLabelObjectEXT(type, name, label.size(), label.data());
#else
static_cast<void>(type);
static_cast<void>(name);
static_cast<void>(label);
CORRADE_INTERNAL_ASSERT(false);
#endif
}
std::string AbstractObject::getLabelImplementationNoOp(GLenum, GLuint) { return {}; }
std::string AbstractObject::getLabelImplementationKhr(const GLenum identifier, const GLuint name) {
/**
* @todo Get rid of this workaround when NVidia returns proper size for
* length=0 & label=nullptr (even crashes on length>0 & label=nullptr)
*/
#if 0
/* Get label size (w/o null terminator) */
GLsizei size;
#ifndef MAGNUM_TARGET_GLES
glGetObjectLabel(type, name, 0, &size, nullptr);
#else
glGetObjectLabelKHR(type, name, 0, &size, nullptr);
#endif
/* Make place also for the null terminator */
std::string label;
label.resize(size+1);
#ifndef MAGNUM_TARGET_GLES
glGetObjectLabel(identifier, name, size+1, nullptr, &label[0]);
#else
glGetObjectLabelKHR(identifier, name, size+1, nullptr, &label[0]);
#endif
/* Pop null terminator and return the string */
label.pop_back();
return label;
#else
GLsizei size;
std::string label;
label.resize(maxLabelLength());
/** @todo Re-enable when extension wrangler is available for ES */
#ifndef MAGNUM_TARGET_GLES
glGetObjectLabel(identifier, name, label.size(), &size, &label[0]);
#else
static_cast<void>(identifier);
static_cast<void>(name);
CORRADE_INTERNAL_ASSERT(false);
//glGetObjectLabelKHR(identifier, name, label.size(), &size, &label[0]);
#endif
return label.substr(0, size);
#endif
}
std::string AbstractObject::getLabelImplementationExt(const GLenum identifier, const GLuint name) {
const GLenum type = extTypeFromKhrIdentifier(identifier);
/* Get label size (w/o null terminator) */
GLsizei size;
/** @todo Re-enable when extension wrangler is available for ES */
#ifndef MAGNUM_TARGET_GLES
glGetObjectLabelEXT(type, name, 0, &size, nullptr);
#else
static_cast<void>(type);
static_cast<void>(name);
CORRADE_INTERNAL_ASSERT(false);
#endif
/* Make place also for the null terminator */
std::string label;
label.resize(size+1);
/** @todo Re-enable when extension wrangler is available for ES */
#ifndef MAGNUM_TARGET_GLES
glGetObjectLabelEXT(identifier, name, size+1, nullptr, &label[0]);
#endif
/* Pop null terminator and return the string */
label.pop_back();
return label;
}
}

81
src/AbstractObject.h

@ -0,0 +1,81 @@
#ifndef Magnum_AbstractObject_h
#define Magnum_AbstractObject_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
/** @file
* @brief Class @ref Magnum::AbstractObject
*/
#include <string>
#include "OpenGL.h"
#include "Types.h"
#include "magnumVisibility.h"
namespace Magnum {
namespace Implementation {
struct DebugState;
}
/**
@brief Base for all OpenGL objects
*/
class MAGNUM_EXPORT AbstractObject {
friend class Context;
friend class Implementation::DebugState;
public:
/**
* @brief Max object label length
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If @extension{KHR,debug} desktop or ES extension is
* not available, returns `0`. Note that @extension{EXT,debug_label}
* has no such limit.
* @see @ref AbstractQuery::setLabel(), @ref AbstractShaderProgram::setLabel(),
* @ref AbstractTexture::setLabel(), @ref Buffer::setLabel(),
* @ref BufferTexture::setLabel(), @ref Framebuffer::setLabel(),
* @ref Mesh::setLabel(), @ref Renderbuffer::setLabel(),
* @ref Shader::setLabel(), @fn_gl{Get} with @def_gl{MAX_LABEL_LENGTH}
*/
static Int maxLabelLength();
protected:
MAGNUM_LOCAL AbstractObject() = default;
MAGNUM_LOCAL ~AbstractObject() = default;
private:
static MAGNUM_LOCAL void labelImplementationNoOp(GLenum, GLuint, const std::string&);
static MAGNUM_LOCAL void labelImplementationExt(GLenum identifier, GLuint name, const std::string& label);
static MAGNUM_LOCAL void labelImplementationKhr(GLenum identifier, GLuint name, const std::string& label);
static MAGNUM_LOCAL std::string getLabelImplementationNoOp(GLenum, GLuint);
static MAGNUM_LOCAL std::string getLabelImplementationExt(GLenum identifier, GLuint name);
static MAGNUM_LOCAL std::string getLabelImplementationKhr(GLenum identifier, GLuint name);
};
}
#endif

18
src/AbstractShaderProgram.cpp

@ -27,6 +27,7 @@
#include "Math/RectangularMatrix.h"
#include "Extensions.h"
#include "Shader.h"
#include "Implementation/DebugState.h"
#include "Implementation/ShaderProgramState.h"
#include "Implementation/State.h"
@ -251,6 +252,23 @@ AbstractShaderProgram& AbstractShaderProgram::operator=(AbstractShaderProgram&&
return *this;
}
std::string AbstractShaderProgram::label() const {
#ifndef MAGNUM_TARGET_GLES
return Context::current()->state().debug->getLabelImplementation(GL_PROGRAM, _id);
#else
return Context::current()->state().debug->getLabelImplementation(GL_PROGRAM_KHR, _id);
#endif
}
AbstractShaderProgram& AbstractShaderProgram::setLabel(const std::string& label) {
#ifndef MAGNUM_TARGET_GLES
Context::current()->state().debug->labelImplementation(GL_PROGRAM, _id, label);
#else
Context::current()->state().debug->labelImplementation(GL_PROGRAM_KHR, _id, label);
#endif
return *this;
}
std::pair<bool, std::string> AbstractShaderProgram::validate() {
glValidateProgram(_id);

30
src/AbstractShaderProgram.h

@ -31,8 +31,8 @@
#include <string>
#include <Containers/EnumSet.h>
#include "AbstractObject.h"
#include "Magnum.h"
#include "OpenGL.h"
#include "magnumVisibility.h"
namespace Magnum {
@ -317,7 +317,7 @@ comes in handy.
status, should be faster -- https://twitter.com/g_truc/status/352778836657700866
@todo `GL_NUM_{PROGRAM,SHADER}_BINARY_FORMATS` + `GL_{PROGRAM,SHADER}_BINARY_FORMATS` (vector), (@extension{ARB,ES2_compatibility})
*/
class MAGNUM_EXPORT AbstractShaderProgram {
class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject {
friend class Context;
public:
@ -508,6 +508,32 @@ class MAGNUM_EXPORT AbstractShaderProgram {
/** @brief OpenGL program ID */
GLuint id() const { return _id; }
/**
* @brief %Shader program label
*
* The result is *not* cached, repeated queries will result in repeated
* OpenGL calls. If neither @extension{KHR,debug} nor
* @extension{EXT,debug_label} desktop or ES extension is available,
* this function returns empty string.
* @see @fn_gl{GetObjectLabel} with @def_gl{PROGRAM} or
* @fn_gl_extension{GetObjectLabel,EXT,object_label} with
* @def_gl{PROGRAM_OBJECT_EXT}
*/
std::string label() const;
/**
* @brief Set shader program label
* @return Reference to self (for method chaining)
*
* Default is empty string. If neither @extension{KHR,debug} nor
* @extension{EXT,debug_label} desktop or ES extension is available,
* this function does nothing.
* @see @ref maxLabelLength(), @fn_gl{ObjectLabel} with
* @def_gl{PROGRAM} or @fn_gl_extension{LabelObject,EXT,object_label}
* with @def_gl{PROGRAM_OBJECT_EXT}
*/
AbstractShaderProgram& setLabel(const std::string& label);
/**
* @brief Validate program
*

10
src/AbstractTexture.cpp

@ -31,6 +31,7 @@
#include "Image.h"
#include "Shader.h"
#include "TextureFormat.h"
#include "Implementation/DebugState.h"
#include "Implementation/State.h"
#include "Implementation/TextureState.h"
@ -158,6 +159,15 @@ AbstractTexture& AbstractTexture::operator=(AbstractTexture&& other) {
return *this;
}
std::string AbstractTexture::label() const {
return Context::current()->state().debug->getLabelImplementation(GL_TEXTURE, _id);
}
AbstractTexture& AbstractTexture::setLabel(const std::string& label) {
Context::current()->state().debug->labelImplementation(GL_TEXTURE, _id, label);
return *this;
}
void AbstractTexture::bind(Int layer) {
Implementation::TextureState* const textureState = Context::current()->state().texture;

29
src/AbstractTexture.h

@ -31,6 +31,7 @@
#include "Array.h"
#include "Color.h"
#include "Sampler.h"
#include "AbstractObject.h"
namespace Magnum {
@ -95,7 +96,7 @@ nothing.
@todo `GL_NUM_COMPRESSED_TEXTURE_FORMATS` when compressed textures are implemented
@todo `GL_MAX_SAMPLE_MASK_WORDS` when @extension{ARB,texture_multisample} is done
*/
class MAGNUM_EXPORT AbstractTexture {
class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
friend class Context;
public:
@ -165,6 +166,32 @@ class MAGNUM_EXPORT AbstractTexture {
/** @brief Move assignment */
AbstractTexture& operator=(AbstractTexture&& other);
/**
* @brief %Texture label
*
* The result is *not* cached, repeated queries will result in repeated
* OpenGL calls. If neither @extension{KHR,debug} nor
* @extension{EXT,debug_label} desktop or ES extension is available,
* this function returns empty string.
* @see @fn_gl{GetObjectLabel} or
* @fn_gl_extension{GetObjectLabel,EXT,object_label} with
* @def_gl{TEXTURE}
*/
std::string label() const;
/**
* @brief Set texture label
* @return Reference to self (for method chaining)
*
* Default is empty string. If neither @extension{KHR,debug} nor
* @extension{EXT,debug_label} desktop or ES extension is available,
* this function does nothing.
* @see @ref maxLabelLength(), @fn_gl{ObjectLabel} or
* @fn_gl_extension{LabelObject,EXT,object_label} with
* @def_gl{TEXTURE}
*/
AbstractTexture& setLabel(const std::string& label);
/** @brief OpenGL texture ID */
GLuint id() const { return _id; }

18
src/Buffer.cpp

@ -30,6 +30,7 @@
#include "Extensions.h"
#include "Implementation/State.h"
#include "Implementation/BufferState.h"
#include "Implementation/DebugState.h"
namespace Magnum {
@ -160,6 +161,23 @@ Buffer::~Buffer() {
glDeleteBuffers(1, &_id);
}
std::string Buffer::label() const {
#ifndef MAGNUM_TARGET_GLES
return Context::current()->state().debug->getLabelImplementation(GL_BUFFER, _id);
#else
return Context::current()->state().debug->getLabelImplementation(GL_BUFFER_KHR, _id);
#endif
}
Buffer& Buffer::setLabel(const std::string& label) {
#ifndef MAGNUM_TARGET_GLES
Context::current()->state().debug->labelImplementation(GL_BUFFER, _id, label);
#else
Context::current()->state().debug->labelImplementation(GL_BUFFER_KHR, _id, label);
#endif
return *this;
}
void Buffer::bind(Target target, GLuint id) {
GLuint& bound = Context::current()->state().buffer->bindings[Implementation::BufferState::indexForTarget(target)];

31
src/Buffer.h

@ -35,9 +35,8 @@
#include <Containers/EnumSet.h>
#include <Utility/Assert.h>
#include "AbstractObject.h"
#include "Magnum.h"
#include "OpenGL.h"
#include "magnumVisibility.h"
namespace Magnum {
@ -189,7 +188,7 @@ nothing.
@todo Support for AMD/ARB's query buffer (@extension{AMD,query_buffer_object}, @extension{ARB,query_buffer_object})
@todo BindBufferRange/BindBufferOffset/BindBufferBase for transform feedback (3.0, @extension{EXT,transform_feedback})
*/
class MAGNUM_EXPORT Buffer {
class MAGNUM_EXPORT Buffer: public AbstractObject {
friend class Context;
public:
@ -549,6 +548,32 @@ class MAGNUM_EXPORT Buffer {
/** @brief OpenGL buffer ID */
GLuint id() const { return _id; }
/**
* @brief %Buffer label
*
* The result is *not* cached, repeated queries will result in repeated
* OpenGL calls. If neither @extension{KHR,debug} nor
* @extension{EXT,debug_label} desktop or ES extension is available,
* this function returns empty string.
* @see @fn_gl{GetObjectLabel} with @def_gl{BUFFER} or
* @fn_gl_extension{GetObjectLabel,EXT,object_label} with
* @def_gl{BUFFER_OBJECT_EXT}
*/
std::string label() const;
/**
* @brief Set buffer label
* @return Reference to self (for method chaining)
*
* Default is empty string. If neither @extension{KHR,debug} nor
* @extension{EXT,debug_label} desktop or ES extension is available,
* this function does nothing.
* @see @ref maxLabelLength(), @fn_gl{ObjectLabel} with
* @def_gl{BUFFER} or @fn_gl_extension{LabelObject,EXT,object_label}
* with @def_gl{BUFFER_OBJECT_EXT}
*/
Buffer& setLabel(const std::string& label);
/** @brief Target hint */
Target targetHint() const { return _targetHint; }

12
src/BufferTexture.h

@ -207,8 +207,20 @@ class MAGNUM_EXPORT BufferTexture: private AbstractTexture {
BufferTexture& operator=(BufferTexture&&) = delete;
public:
/** @copydoc AbstractTexture::maxLabelLength() */
static Int maxLabelLength() { return AbstractTexture::maxLabelLength(); }
explicit BufferTexture(): AbstractTexture(GL_TEXTURE_BUFFER) {}
/** @copydoc AbstractTexture::label() */
std::string label() const { return AbstractTexture::label(); }
/** @copydoc AbstractTexture::setLabel() */
BufferTexture& setLabel(const std::string& label) {
AbstractTexture::setLabel(label);
return *this;
}
/** @copydoc AbstractTexture::bind() */
void bind(Int layer) { AbstractTexture::bind(layer); }

2
src/CMakeLists.txt

@ -48,6 +48,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/magnumConfigure.h.cmake
set(Magnum_SRCS
AbstractFramebuffer.cpp
AbstractImage.cpp
AbstractObject.cpp
AbstractTexture.cpp
AbstractShaderProgram.cpp
Buffer.cpp
@ -69,6 +70,7 @@ set(Magnum_SRCS
Timeline.cpp
Implementation/BufferState.cpp
Implementation/DebugState.cpp
Implementation/State.cpp
Implementation/TextureState.cpp

2
src/Context.cpp

@ -420,7 +420,7 @@ Context::Context() {
_current = this;
/* Initialize state tracker */
_state = new Implementation::State;
_state = new Implementation::State(*this);
/* Initialize functionality based on current OpenGL version and extensions */
AbstractFramebuffer::initializeContextBasedFunctionality(*this);

4
src/CubeMapTexture.h

@ -224,6 +224,10 @@ class CubeMapTexture: public AbstractTexture {
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
CubeMapTexture& setLabel(const std::string& label) {
AbstractTexture::setLabel(label);
return *this;
}
CubeMapTexture& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap);
return *this;

4
src/CubeMapTextureArray.h

@ -229,6 +229,10 @@ class CubeMapTextureArray: public AbstractTexture {
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
CubeMapTextureArray& setLabel(const std::string& label) {
AbstractTexture::setLabel(label);
return *this;
}
CubeMapTextureArray& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap);
return *this;

10
src/Framebuffer.cpp

@ -31,6 +31,7 @@
#include "Renderbuffer.h"
#include "Texture.h"
#include "Implementation/DebugState.h"
#include "Implementation/State.h"
#include "Implementation/FramebufferState.h"
@ -86,6 +87,15 @@ Framebuffer::~Framebuffer() {
glDeleteFramebuffers(1, &_id);
}
std::string Framebuffer::label() const {
return Context::current()->state().debug->getLabelImplementation(GL_FRAMEBUFFER, _id);
}
Framebuffer& Framebuffer::setLabel(const std::string& label) {
Context::current()->state().debug->labelImplementation(GL_FRAMEBUFFER, _id, label);
return *this;
}
Framebuffer& Framebuffer::mapForDraw(std::initializer_list<std::pair<UnsignedInt, DrawAttachment>> attachments) {
/* Max attachment location */
std::size_t max = 0;

28
src/Framebuffer.h

@ -100,7 +100,7 @@ documentation for more information.
@requires_gl30 %Extension @extension{ARB,framebuffer_object}
*/
class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObject {
friend class Context;
public:
@ -304,6 +304,32 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
*/
~Framebuffer();
/**
* @brief %Framebuffer label
*
* The result is *not* cached, repeated queries will result in repeated
* OpenGL calls. If neither @extension{KHR,debug} nor
* @extension{EXT,debug_label} desktop or ES extension is available,
* this function returns empty string.
* @see @fn_gl{GetObjectLabel} or
* @fn_gl_extension{GetObjectLabel,EXT,object_label} with
* @def_gl{FRAMEBUFFER}
*/
std::string label() const;
/**
* @brief Set framebuffer label
* @return Reference to self (for method chaining)
*
* Default is empty string. If neither @extension{KHR,debug} nor
* @extension{EXT,debug_label} desktop or ES extension is available,
* this function does nothing.
* @see @ref maxLabelLength(), @fn_gl{ObjectLabel} or
* @fn_gl_extension{LabelObject,EXT,object_label} with
* @def_gl{FRAMEBUFFER}
*/
Framebuffer& setLabel(const std::string& label);
/**
* @brief Check framebuffer status
* @param target Target for which check the status

46
src/Implementation/DebugState.cpp

@ -0,0 +1,46 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include "DebugState.h"
#include "AbstractObject.h"
#include "Context.h"
#include "Extensions.h"
namespace Magnum { namespace Implementation {
DebugState::DebugState(Context& context): maxLabelLength(0) {
if(context.isExtensionSupported<Extensions::GL::KHR::debug>()) {
getLabelImplementation = &AbstractObject::getLabelImplementationKhr;
labelImplementation = &AbstractObject::labelImplementationKhr;
} else if(context.isExtensionSupported<Extensions::GL::EXT::debug_label>()) {
getLabelImplementation = &AbstractObject::getLabelImplementationExt;
labelImplementation = &AbstractObject::labelImplementationExt;
} else {
getLabelImplementation = &AbstractObject::getLabelImplementationNoOp;
labelImplementation = &AbstractObject::labelImplementationNoOp;
}
}
}}

48
src/Implementation/DebugState.h

@ -0,0 +1,48 @@
#ifndef Magnum_Implementation_DebugState_h
#define Magnum_Implementation_DebugState_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include <string>
#include "Magnum.h"
#include "OpenGL.h"
namespace Magnum { namespace Implementation {
struct DebugState {
DebugState(Context& context);
typedef std::string(*GetLabelImplementation)(GLenum, GLuint);
GetLabelImplementation getLabelImplementation;
typedef void(*LabelImplementation)(GLenum, GLuint, const std::string&);
LabelImplementation labelImplementation;
GLint maxLabelLength;
};
}}
#endif

17
src/Implementation/State.cpp

@ -24,7 +24,10 @@
#include "State.h"
#include "Context.h"
#include "Extensions.h"
#include "Implementation/BufferState.h"
#include "Implementation/DebugState.h"
#include "Implementation/FramebufferState.h"
#include "Implementation/MeshState.h"
#include "Implementation/RendererState.h"
@ -34,14 +37,23 @@
namespace Magnum { namespace Implementation {
State::State():
State::State(Context& context):
buffer(new BufferState),
debug(new DebugState(context)),
framebuffer(new FramebufferState),
mesh(new MeshState),
renderer(new RendererState),
shader(new ShaderState),
shaderProgram(new ShaderProgramState),
texture(new TextureState) {}
texture(new TextureState) {
Debug() << "Using optional features:";
if(context.isExtensionSupported<Extensions::GL::KHR::debug>())
Debug() << " " << Extensions::GL::KHR::debug::string();
else if(context.isExtensionSupported<Extensions::GL::EXT::debug_label>())
Debug() << " " << Extensions::GL::EXT::debug_label::string();
}
State::~State() {
delete texture;
@ -50,6 +62,7 @@ State::~State() {
delete renderer;
delete mesh;
delete framebuffer;
delete debug;
delete buffer;
}

8
src/Implementation/State.h

@ -24,9 +24,12 @@
DEALINGS IN THE SOFTWARE.
*/
#include "Magnum.h"
namespace Magnum { namespace Implementation {
struct BufferState;
struct DebugState;
struct FramebufferState;
struct MeshState;
struct RendererState;
@ -35,10 +38,13 @@ struct ShaderProgramState;
struct TextureState;
struct State {
State();
/* Initializes context-based functionality */
State(Context& context);
~State();
BufferState* const buffer;
DebugState* const debug;
FramebufferState* const framebuffer;
MeshState* const mesh;
RendererState* const renderer;

18
src/Mesh.cpp

@ -29,6 +29,7 @@
#include "Buffer.h"
#include "Context.h"
#include "Extensions.h"
#include "Implementation/DebugState.h"
#include "Implementation/BufferState.h"
#include "Implementation/MeshState.h"
#include "Implementation/State.h"
@ -137,6 +138,23 @@ Mesh& Mesh::operator=(Mesh&& other) noexcept {
return *this;
}
std::string Mesh::label() const {
#ifndef MAGNUM_TARGET_GLES
return Context::current()->state().debug->getLabelImplementation(GL_VERTEX_ARRAY, _id);
#else
return Context::current()->state().debug->getLabelImplementation(GL_VERTEX_ARRAY_KHR, _id);
#endif
}
Mesh& Mesh::setLabel(const std::string& label) {
#ifndef MAGNUM_TARGET_GLES
Context::current()->state().debug->labelImplementation(GL_VERTEX_ARRAY, _id, label);
#else
Context::current()->state().debug->labelImplementation(GL_VERTEX_ARRAY_KHR, _id, label);
#endif
return *this;
}
Mesh& Mesh::setIndexBuffer(Buffer& buffer, GLintptr offset, IndexType type, UnsignedInt start, UnsignedInt end) {
#if defined(CORRADE_TARGET_NACL) || defined(CORRADE_TARGET_EMSCRIPTEN)
CORRADE_ASSERT(buffer.targetHint() == Buffer::Target::ElementArray,

28
src/Mesh.h

@ -307,7 +307,7 @@ drawing commands are used on desktop OpenGL and OpenGL ES 3.0. See also
@todo test vertex specification & drawing
@todo How to glDrawElementsBaseVertex()/vertex offset -- in draw()?
*/
class MAGNUM_EXPORT Mesh {
class MAGNUM_EXPORT Mesh: public AbstractObject {
friend class Context;
friend class MeshView;
@ -415,6 +415,32 @@ class MAGNUM_EXPORT Mesh {
*/
GLuint id() const { return _id; }
/**
* @brief %Mesh label
*
* The result is *not* cached, repeated queries will result in repeated
* OpenGL calls. If neither @extension{KHR,debug} nor
* @extension{EXT,debug_label} desktop or ES extension is available,
* this function returns empty string.
* @see @fn_gl{GetObjectLabel} with @def_gl{VERTEX_ARRAY} or
* @fn_gl_extension{GetObjectLabel,EXT,object_label} with
* @def_gl{VERTEX_ARRAY_OBJECT_EXT}
*/
std::string label() const;
/**
* @brief Set mesh label
* @return Reference to self (for method chaining)
*
* Default is empty string. If neither @extension{KHR,debug} nor
* @extension{EXT,debug_label} desktop or ES extension is available,
* this function does nothing.
* @see @ref maxLabelLength(), @fn_gl{ObjectLabel} with
* @def_gl{VERTEX_ARRAY} or @fn_gl_extension{LabelObject,EXT,object_label}
* with @def_gl{VERTEX_ARRAY_OBJECT_EXT}
*/
Mesh& setLabel(const std::string& label);
/**
* @brief Index size
*

21
src/Query.cpp

@ -26,6 +26,10 @@
#include <Utility/Assert.h>
#include "Context.h"
#include "Implementation/DebugState.h"
#include "Implementation/State.h"
namespace Magnum {
AbstractQuery::AbstractQuery(): target() {
@ -48,6 +52,23 @@ AbstractQuery::~AbstractQuery() {
#endif
}
std::string AbstractQuery::label() const {
#ifndef MAGNUM_TARGET_GLES
return Context::current()->state().debug->getLabelImplementation(GL_QUERY, _id);
#else
return Context::current()->state().debug->getLabelImplementation(GL_QUERY_KHR, _id);
#endif
}
AbstractQuery& AbstractQuery::setLabel(const std::string& label) {
#ifndef MAGNUM_TARGET_GLES
Context::current()->state().debug->labelImplementation(GL_QUERY, _id, label);
#else
Context::current()->state().debug->labelImplementation(GL_QUERY_KHR, _id, label);
#endif
return *this;
}
bool AbstractQuery::resultAvailable() {
CORRADE_ASSERT(!target, "AbstractQuery::resultAvailable(): the query is currently running", false);

56
src/Query.h

@ -30,10 +30,8 @@
#include <Utility/Assert.h>
#include "OpenGL.h"
#include "Types.h"
#include "AbstractObject.h"
#include "magnumConfigure.h"
#include "magnumVisibility.h"
namespace Magnum {
@ -45,11 +43,37 @@ information.
@todo Support for AMD's query buffer (@extension{AMD,query_buffer_object})
@requires_gles30 %Extension @es_extension{EXT,occlusion_query_boolean}
*/
class MAGNUM_EXPORT AbstractQuery {
class MAGNUM_EXPORT AbstractQuery: public AbstractObject {
public:
/** @brief OpenGL query ID */
GLuint id() const { return _id; }
/**
* @brief %Query label
*
* The result is *not* cached, repeated queries will result in repeated
* OpenGL calls. If neither @extension{KHR,debug} nor
* @extension{EXT,debug_label} desktop or ES extension is available,
* this function returns empty string.
* @see @fn_gl{GetObjectLabel} with @def_gl{QUERY} or
* @fn_gl_extension{GetObjectLabel,EXT,object_label} with
* @def_gl{QUERY_OBJECT_EXT}
*/
std::string label() const;
/**
* @brief Set query label
* @return Reference to self (for method chaining)
*
* Default is empty string. If neither @extension{KHR,debug} nor
* @extension{EXT,debug_label} desktop or ES extension is available,
* this function does nothing.
* @see @ref maxLabelLength(), @fn_gl{ObjectLabel} with
* @def_gl{QUERY} or @fn_gl_extension{LabelObject,EXT,object_label}
* with @def_gl{QUERY_OBJECT_EXT}
*/
AbstractQuery& setLabel(const std::string& label);
/**
* @brief Whether the result is available
*
@ -166,6 +190,14 @@ class PrimitiveQuery: public AbstractQuery {
void begin(Target target) {
AbstractQuery::begin(GLenum(target));
}
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
PrimitiveQuery& setLabel(const std::string& label) {
AbstractQuery::setLabel(label);
return *this;
}
#endif
};
#endif
@ -303,6 +335,14 @@ class SampleQuery: public AbstractQuery {
glEndConditionalRender();
}
#endif
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
SampleQuery& setLabel(const std::string& label) {
AbstractQuery::setLabel(label);
return *this;
}
#endif
};
/**
@ -370,6 +410,14 @@ class TimeQuery: public AbstractQuery {
void begin(Target target) {
AbstractQuery::begin(GLenum(target));
}
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
TimeQuery& setLabel(const std::string& label) {
AbstractQuery::setLabel(label);
return *this;
}
#endif
};
}

12
src/Renderbuffer.cpp

@ -27,8 +27,9 @@
#include "Context.h"
#include "Extensions.h"
#include "Implementation/State.h"
#include "Implementation/DebugState.h"
#include "Implementation/FramebufferState.h"
#include "Implementation/State.h"
namespace Magnum {
@ -78,6 +79,15 @@ Renderbuffer::~Renderbuffer() {
glDeleteRenderbuffers(1, &_id);
}
std::string Renderbuffer::label() const {
return Context::current()->state().debug->getLabelImplementation(GL_RENDERBUFFER, _id);
}
Renderbuffer& Renderbuffer::setLabel(const std::string& label) {
Context::current()->state().debug->labelImplementation(GL_RENDERBUFFER, _id, label);
return *this;
}
void Renderbuffer::bind() {
GLuint& binding = Context::current()->state().framebuffer->renderbufferBinding;

30
src/Renderbuffer.h

@ -28,8 +28,8 @@
* @brief Class Magnum::Renderbuffer
*/
#include "AbstractObject.h"
#include "Magnum.h"
#include "OpenGL.h"
#include "magnumVisibility.h"
namespace Magnum {
@ -53,7 +53,7 @@ See its documentation for more information.
@requires_gl30 %Extension @extension{ARB,framebuffer_object}
*/
class MAGNUM_EXPORT Renderbuffer {
class MAGNUM_EXPORT Renderbuffer: public AbstractObject {
friend class Context;
Renderbuffer(const Renderbuffer&) = delete;
@ -102,6 +102,32 @@ class MAGNUM_EXPORT Renderbuffer {
/** @brief OpenGL internal renderbuffer ID */
GLuint id() const { return _id; }
/**
* @brief %Renderbuffer label
*
* The result is *not* cached, repeated queries will result in repeated
* OpenGL calls. If neither @extension{KHR,debug} nor
* @extension{EXT,debug_label} desktop or ES extension is available,
* this function returns empty string.
* @see @fn_gl{GetObjectLabel} or
* @fn_gl_extension{GetObjectLabel,EXT,object_label} with
* @def_gl{RENDERBUFFER}
*/
std::string label() const;
/**
* @brief Set renderbuffer label
* @return Reference to self (for method chaining)
*
* Default is empty string. If neither @extension{KHR,debug} nor
* @extension{EXT,debug_label} desktop or ES extension is available,
* this function does nothing.
* @see @ref maxLabelLength(), @fn_gl{ObjectLabel} or
* @fn_gl_extension{LabelObject,EXT,object_label} with
* @def_gl{RENDERBUFFER}
*/
Renderbuffer& setLabel(const std::string& label);
/**
* @brief Set renderbuffer storage
* @param internalFormat Internal format

18
src/Shader.cpp

@ -29,6 +29,7 @@
#include <Utility/Directory.h>
#include "Extensions.h"
#include "Implementation/DebugState.h"
#include "Implementation/State.h"
#include "Implementation/ShaderState.h"
@ -581,6 +582,23 @@ Shader& Shader::operator=(Shader&& other) {
return *this;
}
std::string Shader::label() const {
#ifndef MAGNUM_TARGET_GLES
return Context::current()->state().debug->getLabelImplementation(GL_SHADER, _id);
#else
return Context::current()->state().debug->getLabelImplementation(GL_SHADER_KHR, _id);
#endif
}
Shader& Shader::setLabel(const std::string& label) {
#ifndef MAGNUM_TARGET_GLES
Context::current()->state().debug->labelImplementation(GL_SHADER, _id, label);
#else
Context::current()->state().debug->labelImplementation(GL_SHADER_KHR, _id, label);
#endif
return *this;
}
Shader& Shader::addSource(std::string source) {
if(!source.empty()) {
#if defined(CORRADE_TARGET_NACL_NEWLIB) || defined(__MINGW32__)

30
src/Shader.h

@ -31,7 +31,7 @@
#include <vector>
#include <string>
#include "Magnum.h"
#include "AbstractObject.h"
#include "Context.h"
#include "magnumVisibility.h"
@ -43,7 +43,7 @@ namespace Magnum {
See AbstractShaderProgram for more information.
*/
class MAGNUM_EXPORT Shader {
class MAGNUM_EXPORT Shader: public AbstractObject {
Shader(const Shader&) = delete;
Shader& operator=(const Shader&) = delete;
@ -456,6 +456,32 @@ class MAGNUM_EXPORT Shader {
/** @brief OpenGL shader ID */
GLuint id() const { return _id; }
/**
* @brief %Shader label
*
* The result is *not* cached, repeated queries will result in repeated
* OpenGL calls. If neither @extension{KHR,debug} nor
* @extension{EXT,debug_label} desktop or ES extension is available,
* this function returns empty string.
* @see @fn_gl{GetObjectLabel} with @def_gl{SHADER} or
* @fn_gl_extension{GetObjectLabel,EXT,object_label} with
* @def_gl{SHADER_OBJECT_EXT}
*/
std::string label() const;
/**
* @brief Set shader label
* @return Reference to self (for method chaining)
*
* Default is empty string. If neither @extension{KHR,debug} nor
* @extension{EXT,debug_label} desktop or ES extension is available,
* this function does nothing.
* @see @ref maxLabelLength(), @fn_gl{ObjectLabel} with
* @def_gl{SHADER} or @fn_gl_extension{LabelObject,EXT,object_label}
* with @def_gl{SHADER_OBJECT_EXT}
*/
Shader& setLabel(const std::string& label);
/**
* @brief Add shader source
* @param source String with shader source

55
src/Test/AbstractObjectGLTest.cpp

@ -0,0 +1,55 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include "Buffer.h"
#include "Context.h"
#include "Extensions.h"
#include "Test/AbstractOpenGLTester.h"
namespace Magnum { namespace Test {
class AbstractObjectGLTest: public AbstractOpenGLTester {
public:
explicit AbstractObjectGLTest();
void labelNoOp();
};
AbstractObjectGLTest::AbstractObjectGLTest() {
addTests({&AbstractObjectGLTest::labelNoOp});
}
void AbstractObjectGLTest::labelNoOp() {
if(Context::current()->isExtensionSupported<Extensions::GL::KHR::debug>())
CORRADE_SKIP(Extensions::GL::KHR::debug::string() + std::string(" is supported."));
Buffer buffer;
buffer.setLabel("MyBuffer");
CORRADE_COMPARE(buffer.label(), "");
MAGNUM_VERIFY_NO_ERROR();
}
}}
CORRADE_TEST_MAIN(Magnum::Test::AbstractObjectGLTest)

60
src/Test/AbstractQueryGLTest.cpp

@ -0,0 +1,60 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include "Context.h"
#include "Extensions.h"
#include "Query.h"
#include "Test/AbstractOpenGLTester.h"
namespace Magnum { namespace Test {
class AbstractQueryGLTest: public AbstractOpenGLTester {
public:
explicit AbstractQueryGLTest();
void label();
};
AbstractQueryGLTest::AbstractQueryGLTest() {
addTests({&AbstractQueryGLTest::label});
}
void AbstractQueryGLTest::label() {
/* No-Op version is tested in AbstractObjectGLTest */
if(!Context::current()->isExtensionSupported<Extensions::GL::KHR::debug>() &&
!Context::current()->isExtensionSupported<Extensions::GL::EXT::debug_label>())
CORRADE_SKIP("Required extension is not available");
SampleQuery query;
CORRADE_COMPARE(query.label(), "");
query.setLabel("MyQuery");
CORRADE_COMPARE(query.label(), "MyQuery");
MAGNUM_VERIFY_NO_ERROR();
}
}}
CORRADE_TEST_MAIN(Magnum::Test::AbstractQueryGLTest)

65
src/Test/AbstractShaderProgramGLTest.cpp

@ -0,0 +1,65 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include "AbstractShaderProgram.h"
#include "Context.h"
#include "Extensions.h"
#include "Test/AbstractOpenGLTester.h"
namespace Magnum { namespace Test {
class AbstractShaderProgramGLTest: public AbstractOpenGLTester {
public:
explicit AbstractShaderProgramGLTest();
void label();
};
AbstractShaderProgramGLTest::AbstractShaderProgramGLTest() {
addTests({&AbstractShaderProgramGLTest::label});
}
void AbstractShaderProgramGLTest::label() {
/* No-Op version is tested in AbstractObjectGLTest */
if(!Context::current()->isExtensionSupported<Extensions::GL::KHR::debug>() &&
!Context::current()->isExtensionSupported<Extensions::GL::EXT::debug_label>())
CORRADE_SKIP("Required extension is not available");
class MyShader: public AbstractShaderProgram {
public:
explicit MyShader() {}
};
MyShader shader;
CORRADE_COMPARE(shader.label(), "");
shader.setLabel("MyShader");
CORRADE_COMPARE(shader.label(), "MyShader");
MAGNUM_VERIFY_NO_ERROR();
}
}}
CORRADE_TEST_MAIN(Magnum::Test::AbstractShaderProgramGLTest)

60
src/Test/AbstractTextureGLTest.cpp

@ -0,0 +1,60 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include "Context.h"
#include "Extensions.h"
#include "Texture.h"
#include "Test/AbstractOpenGLTester.h"
namespace Magnum { namespace Test {
class AbstractTextureGLTest: public AbstractOpenGLTester {
public:
explicit AbstractTextureGLTest();
void label();
};
AbstractTextureGLTest::AbstractTextureGLTest() {
addTests({&AbstractTextureGLTest::label});
}
void AbstractTextureGLTest::label() {
/* No-Op version is tested in AbstractObjectGLTest */
if(!Context::current()->isExtensionSupported<Extensions::GL::KHR::debug>() &&
!Context::current()->isExtensionSupported<Extensions::GL::EXT::debug_label>())
CORRADE_SKIP("Required extension is not available");
Texture2D texture;
CORRADE_COMPARE(texture.label(), "");
texture.setLabel("MyTexture");
CORRADE_COMPARE(texture.label(), "MyTexture");
MAGNUM_VERIFY_NO_ERROR();
}
}}
CORRADE_TEST_MAIN(Magnum::Test::AbstractTextureGLTest)

17
src/Test/BufferGLTest.cpp

@ -38,6 +38,7 @@ class BufferGLTest: public AbstractOpenGLTester {
explicit BufferGLTest();
void construct();
void label();
void data();
void map();
#ifdef MAGNUM_TARGET_GLES2
@ -55,6 +56,7 @@ class BufferGLTest: public AbstractOpenGLTester {
BufferGLTest::BufferGLTest() {
addTests({&BufferGLTest::construct,
&BufferGLTest::label,
&BufferGLTest::data,
&BufferGLTest::map,
#ifdef MAGNUM_TARGET_GLES2
@ -81,6 +83,21 @@ void BufferGLTest::construct() {
MAGNUM_VERIFY_NO_ERROR();
}
void BufferGLTest::label() {
/* No-Op version is tested in AbstractObjectGLTest */
if(!Context::current()->isExtensionSupported<Extensions::GL::KHR::debug>() &&
!Context::current()->isExtensionSupported<Extensions::GL::EXT::debug_label>())
CORRADE_SKIP("Required extension is not available");
Buffer buffer;
CORRADE_COMPARE(buffer.label(), "");
buffer.setLabel("MyBuffer");
CORRADE_COMPARE(buffer.label(), "MyBuffer");
MAGNUM_VERIFY_NO_ERROR();
}
void BufferGLTest::data() {
Buffer buffer;

8
src/Test/CMakeLists.txt

@ -35,8 +35,16 @@ corrade_add_test(ResourceManagerTest ResourceManagerTest.cpp LIBRARIES MagnumTes
corrade_add_test(SamplerTest SamplerTest.cpp LIBRARIES Magnum)
if(BUILD_GL_TESTS)
corrade_add_test(AbstractObjectGLTest AbstractObjectGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES})
corrade_add_test(AbstractQueryGLTest AbstractQueryGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES})
corrade_add_test(AbstractShaderProgramGLTest AbstractShaderProgramGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES})
corrade_add_test(AbstractTextureGLTest AbstractTextureGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES})
corrade_add_test(BufferGLTest BufferGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES})
corrade_add_test(ContextGLTest ContextGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES})
corrade_add_test(FramebufferGLTest FramebufferGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES})
corrade_add_test(MeshGLTest MeshGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES})
corrade_add_test(RenderbufferGLTest RenderbufferGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES})
corrade_add_test(ShaderGLTest ShaderGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES})
endif()
set_target_properties(ResourceManagerTest PROPERTIES COMPILE_FLAGS -DCORRADE_GRACEFUL_ASSERT)

62
src/Test/FramebufferGLTest.cpp

@ -0,0 +1,62 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include "Context.h"
#include "Extensions.h"
#include "Framebuffer.h"
#include "Test/AbstractOpenGLTester.h"
namespace Magnum { namespace Test {
class FramebufferGLTest: public AbstractOpenGLTester {
public:
explicit FramebufferGLTest();
void label();
};
FramebufferGLTest::FramebufferGLTest() {
addTests({&FramebufferGLTest::label});
}
void FramebufferGLTest::label() {
/* No-Op version is tested in AbstractObjectGLTest */
if(!Context::current()->isExtensionSupported<Extensions::GL::KHR::debug>() &&
!Context::current()->isExtensionSupported<Extensions::GL::EXT::debug_label>())
CORRADE_SKIP("Required extension is not available");
Framebuffer framebuffer({{}, Vector2i(32)});
CORRADE_COMPARE(framebuffer.label(), "");
MAGNUM_VERIFY_NO_ERROR();
framebuffer.setLabel("MyFramebuffer");
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(framebuffer.label(), "MyFramebuffer");
}
}}
CORRADE_TEST_MAIN(Magnum::Test::FramebufferGLTest)

60
src/Test/MeshGLTest.cpp

@ -0,0 +1,60 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include "Context.h"
#include "Extensions.h"
#include "Mesh.h"
#include "Test/AbstractOpenGLTester.h"
namespace Magnum { namespace Test {
class MeshGLTest: public AbstractOpenGLTester {
public:
explicit MeshGLTest();
void label();
};
MeshGLTest::MeshGLTest() {
addTests({&MeshGLTest::label});
}
void MeshGLTest::label() {
/* No-Op version is tested in AbstractObjectGLTest */
if(!Context::current()->isExtensionSupported<Extensions::GL::KHR::debug>() &&
!Context::current()->isExtensionSupported<Extensions::GL::EXT::debug_label>())
CORRADE_SKIP("Required extension is not available");
Mesh mesh;
CORRADE_COMPARE(mesh.label(), "");
mesh.setLabel("MyMesh");
CORRADE_COMPARE(mesh.label(), "MyMesh");
MAGNUM_VERIFY_NO_ERROR();
}
}}
CORRADE_TEST_MAIN(Magnum::Test::MeshGLTest)

60
src/Test/RenderbufferGLTest.cpp

@ -0,0 +1,60 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include "Context.h"
#include "Extensions.h"
#include "Renderbuffer.h"
#include "Test/AbstractOpenGLTester.h"
namespace Magnum { namespace Test {
class RenderbufferGLTest: public AbstractOpenGLTester {
public:
explicit RenderbufferGLTest();
void label();
};
RenderbufferGLTest::RenderbufferGLTest() {
addTests({&RenderbufferGLTest::label});
}
void RenderbufferGLTest::label() {
/* No-Op version is tested in AbstractObjectGLTest */
if(!Context::current()->isExtensionSupported<Extensions::GL::KHR::debug>() &&
!Context::current()->isExtensionSupported<Extensions::GL::EXT::debug_label>())
CORRADE_SKIP("Required extension is not available");
Renderbuffer renderbuffer;
CORRADE_COMPARE(renderbuffer.label(), "");
renderbuffer.setLabel("MyRenderbuffer");
CORRADE_COMPARE(renderbuffer.label(), "MyRenderbuffer");
MAGNUM_VERIFY_NO_ERROR();
}
}}
CORRADE_TEST_MAIN(Magnum::Test::RenderbufferGLTest)

60
src/Test/ShaderGLTest.cpp

@ -0,0 +1,60 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include "Context.h"
#include "Extensions.h"
#include "Shader.h"
#include "Test/AbstractOpenGLTester.h"
namespace Magnum { namespace Test {
class ShaderGLTest: public AbstractOpenGLTester {
public:
explicit ShaderGLTest();
void label();
};
ShaderGLTest::ShaderGLTest() {
addTests({&ShaderGLTest::label});
}
void ShaderGLTest::label() {
/* No-Op version is tested in AbstractObjectGLTest */
if(!Context::current()->isExtensionSupported<Extensions::GL::KHR::debug>() &&
!Context::current()->isExtensionSupported<Extensions::GL::EXT::debug_label>())
CORRADE_SKIP("Required extension is not available");
Shader shader(Version::GL210, Shader::Type::Vertex);
CORRADE_COMPARE(shader.label(), "");
shader.setLabel("MyShader");
CORRADE_COMPARE(shader.label(), "MyShader");
MAGNUM_VERIFY_NO_ERROR();
}
}}
CORRADE_TEST_MAIN(Magnum::Test::ShaderGLTest)

4
src/Texture.h

@ -423,6 +423,10 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
Texture<Dimensions>& setLabel(const std::string& label) {
AbstractTexture::setLabel(label);
return *this;
}
Texture<Dimensions>& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap);
return *this;

Loading…
Cancel
Save