Browse Source

Classes for handling version and extension information.

vectorfields
Vladimír Vondruš 14 years ago
parent
commit
ae28de197b
  1. 3
      src/CMakeLists.txt
  2. 188
      src/Context.cpp
  3. 216
      src/Context.h
  4. 141
      src/Extensions.h

3
src/CMakeLists.txt

@ -22,6 +22,7 @@ set(Magnum_SRCS
AbstractTexture.cpp
AbstractShaderProgram.cpp
BufferedTexture.cpp
Context.cpp
Framebuffer.cpp
IndexedMesh.cpp
Mesh.cpp
@ -42,8 +43,10 @@ set(Magnum_HEADERS
BufferedTexture.h
Buffer.h
Color.h
Context.h
CubeMapTextureArray.h
CubeMapTexture.h
Extensions.h
Framebuffer.h
Image.h
ImageWrapper.h

188
src/Context.cpp

@ -0,0 +1,188 @@
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
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 "Context.h"
#include <string>
#include <unordered_map>
#include <Utility/Debug.h>
#include "Extensions.h"
using namespace std;
namespace Magnum {
const std::vector<Extension>& Extension::extensions(Version version) {
#define _extension(prefix, vendor, extension) \
{Extensions::prefix::vendor::extension::Index, Extensions::prefix::vendor::extension::requiredVersion(), Extensions::prefix::vendor::extension::coreVersion(), Extensions::prefix::vendor::extension::string()}
static std::vector<Extension> empty;
static std::vector<Extension> extensions{
_extension(GL,EXT,texture_filter_anisotropic)};
static std::vector<Extension> extensions300{
_extension(GL,APPLE,flush_buffer_range),
_extension(GL,APPLE,vertex_array_object),
_extension(GL,ARB,color_buffer_float),
_extension(GL,ARB,half_float_pixel),
_extension(GL,ARB,texture_float),
_extension(GL,ARB,depth_buffer_float),
_extension(GL,ARB,texture_rg),
_extension(GL,EXT,framebuffer_object),
_extension(GL,EXT,packed_depth_stencil),
_extension(GL,EXT,framebuffer_blit),
_extension(GL,EXT,framebuffer_multisample),
_extension(GL,EXT,gpu_shader4),
_extension(GL,EXT,packed_float),
_extension(GL,EXT,texture_array),
_extension(GL,EXT,texture_compression_rgtc),
_extension(GL,EXT,texture_shared_exponent),
_extension(GL,EXT,framebuffer_sRGB),
_extension(GL,EXT,draw_buffers2),
_extension(GL,EXT,texture_integer),
_extension(GL,EXT,transform_feedback),
_extension(GL,NV,half_float),
_extension(GL,NV,depth_buffer_float),
_extension(GL,NV,conditional_render)};
static std::vector<Extension> extensions310{
_extension(GL,ARB,texture_rectangle),
_extension(GL,ARB,draw_instanced),
_extension(GL,ARB,texture_buffer_object),
_extension(GL,ARB,uniform_buffer_object),
_extension(GL,ARB,copy_buffer),
_extension(GL,EXT,texture_snorm),
_extension(GL,NV,primitive_restart)};
static std::vector<Extension> extensions320{
_extension(GL,ARB,geometry_shader4),
_extension(GL,ARB,depth_clamp),
_extension(GL,ARB,draw_elements_base_vertex),
_extension(GL,ARB,fragment_coord_conventions),
_extension(GL,ARB,provoking_vertex),
_extension(GL,ARB,seamless_cube_map),
_extension(GL,ARB,sync),
_extension(GL,ARB,texture_multisample),
_extension(GL,ARB,vertex_array_bgra)};
static std::vector<Extension> extensions330{
_extension(GL,ARB,instanced_arrays),
_extension(GL,ARB,blend_func_extended),
_extension(GL,ARB,explicit_attrib_location),
_extension(GL,ARB,occlusion_query2),
_extension(GL,ARB,sampler_objects),
_extension(GL,ARB,shader_bit_encoding),
_extension(GL,ARB,texture_rgb10_a2ui),
_extension(GL,ARB,texture_swizzle),
_extension(GL,ARB,timer_query),
_extension(GL,ARB,vertex_type_2_10_10_10_rev)};
static std::vector<Extension> extensions400{
_extension(GL,ARB,draw_buffers_blend),
_extension(GL,ARB,sample_shading),
_extension(GL,ARB,texture_cube_map_array),
_extension(GL,ARB,texture_gather),
_extension(GL,ARB,texture_query_lod),
_extension(GL,ARB,draw_indirect),
_extension(GL,ARB,gpu_shader5),
_extension(GL,ARB,gpu_shader_fp64),
_extension(GL,ARB,shader_subroutine),
_extension(GL,ARB,tessellation_shader),
_extension(GL,ARB,texture_buffer_object_rgb32),
_extension(GL,ARB,transform_feedback2),
_extension(GL,ARB,transform_feedback3)};
static std::vector<Extension> extensions410{
_extension(GL,ARB,ES2_compatibility),
_extension(GL,ARB,get_program_binary),
_extension(GL,ARB,separate_shader_objects),
_extension(GL,ARB,shader_precision),
_extension(GL,ARB,vertex_attrib_64bit),
_extension(GL,ARB,viewport_array)};
static std::vector<Extension> extensions420{
_extension(GL,ARB,texture_compression_bptc),
_extension(GL,ARB,base_instance),
_extension(GL,ARB,shading_language_420pack),
_extension(GL,ARB,transform_feedback_instanced),
_extension(GL,ARB,compressed_texture_pixel_storage),
_extension(GL,ARB,conservative_depth),
_extension(GL,ARB,internalformat_query),
_extension(GL,ARB,map_buffer_alignment),
_extension(GL,ARB,shader_atomic_counters),
_extension(GL,ARB,shader_image_load_store),
_extension(GL,ARB,texture_storage)};
static std::vector<Extension> extensions430;
#undef _extension
switch(version) {
case Version::None: return extensions;
case Version::GL300: return extensions300;
case Version::GL310: return extensions310;
case Version::GL320: return extensions320;
case Version::GL330: return extensions330;
case Version::GL400: return extensions400;
case Version::GL410: return extensions410;
case Version::GL420: return extensions420;
case Version::GL430: return extensions430;
default: return empty;
}
}
Context* Context::_current = nullptr;
Context::Context() {
/* Version */
glGetIntegerv(GL_MAJOR_VERSION, &_majorVersion);
glGetIntegerv(GL_MINOR_VERSION, &_minorVersion);
_version = static_cast<Version>(_majorVersion*100+_minorVersion*10);
/* Future versions */
vector<Version> versions{
Version::GL300,
Version::GL310,
Version::GL320,
Version::GL330,
Version::GL400,
Version::GL410,
Version::GL420,
Version::GL430,
Version::None
};
size_t future = 0;
while(versions[future] != Version::None && versions[future] < _version)
++future;
/* Extensions */
unordered_map<string, Extension> futureExtensions;
for(size_t i = future; i != versions.size(); ++i)
for(const Extension& extension: Extension::extensions(versions[i]))
futureExtensions.insert(make_pair(extension._string, extension));
/* Check for presence of extensions in future versions */
GLuint index = 0;
const char* extension;
while((extension = reinterpret_cast<const char*>(glGetStringi(GL_EXTENSIONS, index++)))) {
auto found = futureExtensions.find(extension);
if(found != futureExtensions.end()) {
_supportedExtensions.push_back(found->second);
extensionStatus.set(found->second._index);
}
}
/* Set this context as current */
CORRADE_ASSERT(!_current, "Context: Another context currently active", );
_current = this;
}
Context::~Context() {
CORRADE_ASSERT(_current == this, "Context: Cannot destroy context which is not currently active", );
_current = nullptr;
}
}

216
src/Context.h

@ -0,0 +1,216 @@
#ifndef Magnum_Context_h
#define Magnum_Context_h
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
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.
*/
/** @file
* @brief Enum Version, class Magnum::Context, Magnum::Extension
*/
#include <bitset>
#include <vector>
#include "Magnum.h"
#include "magnumVisibility.h"
namespace Magnum {
/** @brief OpenGL version */
enum class Version: GLint {
None = 0, /**< @brief Unspecified */
#ifndef MAGNUM_TARGET_GLES
GL210 = 210, /**< @brief OpenGL 2.1 / GLSL 1.20 */
GL300 = 300, /**< @brief OpenGL 3.0 / GLSL 1.30 */
GL310 = 310, /**< @brief OpenGL 3.1 / GLSL 1.40 */
GL320 = 320, /**< @brief OpenGL 3.2 / GLSL 1.50 */
GL330 = 330, /**< @brief OpenGL 3.3, GLSL 3.30 */
GL400 = 400, /**< @brief OpenGL 4.0, GLSL 4.00 */
GL410 = 410, /**< @brief OpenGL 4.1, GLSL 4.10 */
GL420 = 420, /**< @brief OpenGL 4.2, GLSL 4.20 */
GL430 = 430 /**< @brief OpenGL 4.3, GLSL 4.30 */
#else
GLES200 = 200, /**< @brief OpenGL ES 2.0, GLSL ES 1.00 */
GLES300 = 300 /**< @brief OpenGL ES 3.0, GLSL ES 3.00 */
#endif
};
/**
@brief Run-time information about OpenGL extension
Encapsulates runtime information about OpenGL extension, such as name string,
minimal required OpenGL version and version in which the extension was adopted
to core.
See also Extensions namespace, which contain compile-time information about
OpenGL extensions.
*/
class MAGNUM_EXPORT Extension {
friend class Context;
public:
/** @brief All extensions for given OpenGL version */
static const std::vector<Extension>& extensions(Version version);
/** @brief Minimal version required by this extension */
inline constexpr Version requiredVersion() const { return _requiredVersion; }
/** @brief Version in which this extension was adopted to core */
inline constexpr Version coreVersion() const { return _coreVersion; }
/** @brief %Extension string */
inline constexpr const char* string() const { return _string; }
private:
const size_t _index;
const Version _requiredVersion;
const Version _coreVersion;
const char* const _string;
inline constexpr Extension(size_t index, Version requiredVersion, Version coreVersion, const char* string): _index(index), _requiredVersion(requiredVersion), _coreVersion(coreVersion), _string(string) {}
};
/**
@brief OpenGL context
Provides access to version and extension information.
*/
class MAGNUM_EXPORT Context {
Context(const Context&) = delete;
Context(Context&&) = delete;
Context& operator=(const Context&) = delete;
Context& operator=(Context&&) = delete;
public:
/**
* @brief Constructor
*
* @see @fn_gl{Get} with @def_gl{MAJOR_VERSION}, @def_gl{MINOR_VERSION},
* @fn_gl{GetString} with @def_gl{EXTENSIONS}
*/
Context();
~Context();
/** @brief Current context */
inline static Context* current() { return _current; }
/** @brief OpenGL version */
inline Version version() const { return _version; }
/** @brief Major OpenGL version (e.g. `4`) */
inline GLint majorVersion() const { return _majorVersion; }
/** @brief Minor OpenGL version (e.g. `3`) */
inline GLint minorVersion() const { return _minorVersion; }
/**
* @brief Vendor string
*
* @see @fn_gl{GetString} with @def_gl{VENDOR}
*/
inline std::string vendorString() const {
return reinterpret_cast<const char*>(glGetString(GL_VENDOR));
}
/**
* @brief Renderer string
*
* @see @fn_gl{GetString} with @def_gl{RENDERER}
*/
inline std::string rendererString() const {
return reinterpret_cast<const char*>(glGetString(GL_RENDERER));
}
/**
* @brief Version string
*
* @see @fn_gl{GetString} with @def_gl{VERSION}
*/
inline std::string versionString() const {
return reinterpret_cast<const char*>(glGetString(GL_VERSION));
}
/**
* @brief Shading language version string
*
* @see @fn_gl{GetString} with @def_gl{SHADING_LANGUAGE_VERSION}
*/
inline std::string shadingLanguageVersionString() const {
return reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION));
}
/**
* @brief Supported extensions
*
* The list contains only extensions from OpenGL versions newer than
* the current.
*
* @see isExtensionSupported(), Extension::extensions()
*/
inline const std::vector<Extension>& supportedExtensions() const {
return _supportedExtensions;
}
/** @brief Whether given OpenGL version is supported */
inline bool isVersionSupported(Version version) const {
return _version >= version;
}
/**
* @brief Whether given extension is supported
*
* %Extensions usable with this function are listed in Extensions
* namespace in header Extensions.h. Example usage:
* @code
* if(Context::current()->isExtensionSupported<Extensions::GL::ARB::tessellation_shader>()) {
* // draw fancy detailed model
* } else {
* // texture fallback
* }
* @endcode
*
* @see isExtensionSupported(const Extension&) const
*/
template<class T> inline bool isExtensionSupported() const {
return _version >= T::coreVersion() || (_version >= T::requiredVersion() && extensionStatus[T::Index]);
}
/**
* @brief Whether given extension is supported
*
* Can be used e.g. for listing extensions available on current
* hardware, but for general usage prefer isExtensionSupported() const,
* as it does most operations in compile time.
*
* @see supportedExtensions(), Extension::extensions()
*/
inline bool isExtensionSupported(const Extension& extension) const {
return _version >= extension._coreVersion || (_version >= extension._requiredVersion && extensionStatus[extension._index]);
}
private:
static Context* _current;
Version _version;
GLint _majorVersion;
GLint _minorVersion;
std::bitset<128> extensionStatus;
std::vector<Extension> _supportedExtensions;
};
}
#endif

141
src/Extensions.h

@ -0,0 +1,141 @@
#ifndef Magnum_Extensions_h
#define Magnum_Extensions_h
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
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.
*/
/** @file
* @brief Namespace Magnum::Extensions
*/
#include "Context.h"
namespace Magnum {
/**
@brief Compile-time information about OpenGL extensions
Each extension is `struct` named hierarchically by prefix, vendor and
extension name, for example `GL::APPLE::vertex_array_object`. Each struct has
the same public methods as Extension class (requiredVersion(), coreVersion()
and string(), but these structs are better suited for compile-time decisions
rather than Extension instances. See Context::isExtensionSupported() for
example usage.
*/
namespace Extensions {
#ifndef DOXYGEN_GENERATING_OUTPUT
#define _extension(prefix, vendor, extension, _requiredVersion, _coreVersion) \
struct extension { \
enum: size_t { Index = __LINE__-1 }; \
constexpr static Version requiredVersion() { return Version::_requiredVersion; } \
constexpr static Version coreVersion() { return Version::_coreVersion; } \
constexpr static const char* string() { return #prefix "_" #vendor "_" #extension; } \
};
namespace GL {
#line 1
namespace APPLE {
_extension(GL,APPLE,flush_buffer_range, GL210, GL300) // #321
_extension(GL,APPLE,vertex_array_object, GL210, GL300) // #273
} namespace ARB {
_extension(GL,ARB,texture_rectangle, GL210, GL310) // #38
_extension(GL,ARB,color_buffer_float, GL210, GL300) // #39
_extension(GL,ARB,half_float_pixel, GL210, GL300) // #40
_extension(GL,ARB,texture_float, GL210, GL300) // #41
_extension(GL,ARB,depth_buffer_float, GL210, GL300) // #43
_extension(GL,ARB,draw_instanced, GL210, GL310) // #44
_extension(GL,ARB,geometry_shader4, GL210, GL320) // #47
_extension(GL,ARB,instanced_arrays, GL210, GL330) // #49
_extension(GL,ARB,texture_buffer_object, GL210, GL310) // #51
_extension(GL,ARB,texture_rg, GL210, GL300) // #53
_extension(GL,ARB,uniform_buffer_object, GL210, GL310) // #57
_extension(GL,ARB,copy_buffer, /*?*/ GL210, GL310) // #59
_extension(GL,ARB,depth_clamp, /*?*/ GL210, GL320) // #61
_extension(GL,ARB,draw_elements_base_vertex, /*?*/ GL210, GL320) // #62
_extension(GL,ARB,fragment_coord_conventions, /*?*/ GL210, GL320) // #63
_extension(GL,ARB,provoking_vertex, /*?*/ GL210, GL320) // #64
_extension(GL,ARB,seamless_cube_map, GL210, GL320) // #65
_extension(GL,ARB,sync, GL310, GL320) // #66
_extension(GL,ARB,texture_multisample, /*?*/ GL210, GL320) // #67
_extension(GL,ARB,vertex_array_bgra, GL210, GL320) // #68
_extension(GL,ARB,draw_buffers_blend, GL210, GL400) // #69
_extension(GL,ARB,sample_shading, GL210, GL400) // #70
_extension(GL,ARB,texture_cube_map_array, /*?*/ GL210, GL400) // #71
_extension(GL,ARB,texture_gather, GL210, GL400) // #72
_extension(GL,ARB,texture_query_lod, GL210, GL400) // #73
_extension(GL,ARB,texture_compression_bptc, GL310, GL420) // #77
_extension(GL,ARB,blend_func_extended, GL210, GL330) // #78
_extension(GL,ARB,explicit_attrib_location, GL210, GL330) // #79
_extension(GL,ARB,occlusion_query2, GL210, GL330) // #80
_extension(GL,ARB,sampler_objects, GL210, GL330) // #81
_extension(GL,ARB,shader_bit_encoding, /*?*/ GL210, GL330) // #82
_extension(GL,ARB,texture_rgb10_a2ui, GL210, GL330) // #83
_extension(GL,ARB,texture_swizzle, /*?*/ GL210, GL330) // #84
_extension(GL,ARB,timer_query, /*?*/ GL210, GL330) // #85
_extension(GL,ARB,vertex_type_2_10_10_10_rev, GL210, GL330) // #86
_extension(GL,ARB,draw_indirect, GL310, GL400) // #87
_extension(GL,ARB,gpu_shader5, GL320, GL400) // #88
_extension(GL,ARB,gpu_shader_fp64, GL320, GL400) // #89
_extension(GL,ARB,shader_subroutine, GL320, GL400) // #90
_extension(GL,ARB,tessellation_shader, GL320, GL400) // #91
_extension(GL,ARB,texture_buffer_object_rgb32, /*?*/ GL210, GL400) // #92
_extension(GL,ARB,transform_feedback2, GL210, GL400) // #93
_extension(GL,ARB,transform_feedback3, GL210, GL400) // #94
_extension(GL,ARB,ES2_compatibility, /*?*/ GL210, GL410) // #95
_extension(GL,ARB,get_program_binary, GL300, GL410) // #96
_extension(GL,ARB,separate_shader_objects, GL210, GL410) // #97
_extension(GL,ARB,shader_precision, GL400, GL410) // #98
_extension(GL,ARB,vertex_attrib_64bit, GL300, GL410) // #99
_extension(GL,ARB,viewport_array, GL210, GL410) // #100
_extension(GL,ARB,base_instance, GL210, GL420) // #107
_extension(GL,ARB,shading_language_420pack, GL300, GL420) // #108
_extension(GL,ARB,transform_feedback_instanced, GL210, GL420) // #109
_extension(GL,ARB,compressed_texture_pixel_storage, GL210, GL420) // #110
_extension(GL,ARB,conservative_depth, GL300, GL420) // #111
_extension(GL,ARB,internalformat_query, GL210, GL420) // #112
_extension(GL,ARB,map_buffer_alignment, GL210, GL420) // #113
_extension(GL,ARB,shader_atomic_counters, GL300, GL420) // #114
_extension(GL,ARB,shader_image_load_store, GL300, GL420) // #115
_extension(GL,ARB,texture_storage, GL210, GL420) // #117
} namespace EXT {
_extension(GL,EXT,texture_filter_anisotropic, GL210, None) // #187
_extension(GL,EXT,framebuffer_object, GL210, GL300) // #310
_extension(GL,EXT,packed_depth_stencil, GL210, GL300) // #312
_extension(GL,EXT,framebuffer_blit, GL210, GL300) // #316
_extension(GL,EXT,framebuffer_multisample, GL210, GL300) // #317
_extension(GL,EXT,gpu_shader4, GL210, GL300) // #326
_extension(GL,EXT,packed_float, GL210, GL300) // #328
_extension(GL,EXT,texture_array, GL210, GL300) // #329
_extension(GL,EXT,texture_compression_rgtc, GL210, GL300) // #332
_extension(GL,EXT,texture_shared_exponent, GL210, GL300) // #333
_extension(GL,EXT,framebuffer_sRGB, GL210, GL300) // #337
_extension(GL,EXT,draw_buffers2, GL210, GL300) // #340
_extension(GL,EXT,texture_integer, GL210, GL300) // #343
_extension(GL,EXT,transform_feedback, GL210, GL300) // #352
_extension(GL,EXT,texture_snorm, GL300, GL310) // #365
} namespace NV {
_extension(GL,NV,half_float, GL210, GL300) // #283
_extension(GL,NV,primitive_restart, GL210, GL310) // #285
_extension(GL,NV,depth_buffer_float, GL210, GL300) // #334
_extension(GL,NV,conditional_render, GL210, GL300) // #346
}
}
#undef _extension
#endif
}
}
#endif
Loading…
Cancel
Save