Tools.cc 4.82 KB
Newer Older
Robert Menzel's avatar
Robert Menzel committed
1 2 3 4 5
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2011, Computer Graphics Group RWTH Aachen University         //
// All rights reserved.                                                       //
////////////////////////////////////////////////////////////////////////////////

Robert Menzel's avatar
Robert Menzel committed
6
#include <ACGL/ACGL.hh>
Robert Menzel's avatar
Robert Menzel committed
7
#include <ACGL/OpenGL/Tools.hh>
Robert Menzel's avatar
Robert Menzel committed
8 9

namespace ACGL{
Robert Menzel's avatar
Robert Menzel committed
10
namespace OpenGL{
Robert Menzel's avatar
Robert Menzel committed
11

12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
//
// This is a "private" function that should not be called from outside of this file.
//
// glGetIntegerv(GL_MAJOR_VERSION... and glGetIntegerv(GL_MINOR_VERSION... are great, but
// require OpenGL 3.0 and are not supported on ES :-( so the VERSION string has to get parsed...
//
// OpenGL spec:
// The VERSION ... strings are laid out as follows:
// <version number><space><vendor-specific information>
//
// OpenGL ES spec:
// The VERSION string is laid out as follows:
// "OpenGL ES N.M vendor-specific information"
//
// both specs:
// The version number is either of the form major_number.minor_number or
// major_number.minor_number.release_number, where the numbers all have one or more digits.
//
uint32_t privateGetOpenGLVersion( int _type )
{
    static uint32_t OGLminor   = 0;
    static uint32_t OGLmajor   = 0;
    static uint32_t OGLversion = 0;

    if (OGLversion == 0) {
        // calculate the version numbers once:
        // NOTE: similar to GLEW we assume here, that the minor and major numbers
        //       only have one digit. We also ignore release numbers. This will fail e.g. for OpenGL 10.0
        const GLubyte* versionString;
        versionString = glGetString(GL_VERSION);
        if (openGLRareErrorOccured()) {
            ACGL::Utils::error() << "could not query OpenGL version!" << std::endl;
            return false;
        }

        int positionOfFirstDot = 0;
        while ((versionString[positionOfFirstDot] != '\0') && (versionString[positionOfFirstDot] != '.')) ++positionOfFirstDot;

        OGLmajor = versionString[positionOfFirstDot-1] - '0';
        OGLminor = versionString[positionOfFirstDot+1] - '0';

        if (OGLmajor < 0 || OGLmajor > 9) OGLmajor = 0;
        if (OGLminor < 0 || OGLminor > 9) OGLminor = 0;

        OGLversion = OGLmajor*10 + OGLminor;
    }
    switch (_type) {
        case 0: return OGLminor;
        case 1: return OGLmajor;
        default: return OGLversion;
    };
}

uint32_t getOpenGLMinorVersionNumber()
{
    return privateGetOpenGLVersion( 0 );
}

uint32_t getOpenGLMajorVersionNumber()
{
    return privateGetOpenGLVersion( 1 );
}

uint32_t getOpenGLVersionNumber()
{
    return privateGetOpenGLVersion( 2 );
}

80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
bool doesSupportGeometryShader()
{
#ifdef ACGL_OPENGL_ES
    return false;
#else
#   if defined(ACGL_USE_GLEW)
        return (GLEW_EXT_geometry_shader4 || GLEW_ARB_geometry_shader4 || (getOpenGLVersionNumber() >= 32));
#   else
        return (getOpenGLVersionNumber() >= 32);
#   endif
#endif
}

bool doesSupportTessellationShader()
{
#ifdef ACGL_OPENGL_ES
    return false;
#else
#   if defined(ACGL_USE_GLEW)
        return ( GLEW_ARB_tessellation_shader || (getOpenGLVersionNumber() >= 40));
#   else
        return (getOpenGLVersionNumber() >= 40);
#   endif
#endif
}

106
const GLubyte* acglErrorString( GLenum _errorCode )
Robert Menzel's avatar
Robert Menzel committed
107
{
108
#ifndef ACGL_USE_GLEW
Robert Menzel's avatar
Robert Menzel committed
109
    // no gluErrorString on iOS
110
    // this should only get used on OpenGL ES plattforms or if compiled without GLEW, so error strings from the compatibility profile
Robert Menzel's avatar
Robert Menzel committed
111
    // are ignored. Only 3.2+ Core and ES 2.0+ errors belong here:
112 113
    if      (_errorCode == GL_INVALID_ENUM)                  { return (GLubyte*) "GL_INVALID_ENUM"; }
    else if (_errorCode == GL_INVALID_VALUE)                 { return (GLubyte*) "GL_INVALID_VALUE"; }
Robert Menzel's avatar
Robert Menzel committed
114
    else if (_errorCode == GL_INVALID_OPERATION)             { return (GLubyte*) "GL_INVALID_OPERATION"; }
115
    else if (_errorCode == GL_INVALID_FRAMEBUFFER_OPERATION) { return (GLubyte*) "GL_INVALID_FRAMEBUFFER_OPERATION"; }
Robert Menzel's avatar
Robert Menzel committed
116
    else if (_errorCode == GL_OUT_OF_MEMORY)                 { return (GLubyte*) "GL_OUT_OF_MEMORY"; }
117
    else if (_errorCode == GL_NO_ERROR)                      { return (GLubyte*) "GL_NO_ERROR"; }
Robert Menzel's avatar
Robert Menzel committed
118
    else {
119
        return (GLubyte*) "unknown error";
Robert Menzel's avatar
Robert Menzel committed
120 121
    }
#else
122
    return gluErrorString( _errorCode );
Robert Menzel's avatar
Robert Menzel committed
123 124 125 126 127 128 129
#endif
}



GLenum openGLError_( const char *_fileName, const unsigned long _lineNumber )
{
130 131 132 133 134 135 136 137 138
    GLenum currentError = glGetError();
    GLenum lastError    = currentError;

    // OpenGL does not forbit the implementation to stack up more than one error code
    // so we have to check those in a loop:
    while ( currentError != GL_NO_ERROR ) {
        ACGL::Utils::error() << "GL error in file " << _fileName << ":" << _lineNumber << " - " << acglErrorString( currentError ) << std::endl;
        lastError    = currentError;
        currentError = glGetError();
Robert Menzel's avatar
Robert Menzel committed
139 140
    }

141
    return lastError; // returns the last real error (in case there was at least one!)
Robert Menzel's avatar
Robert Menzel committed
142 143 144
}


Robert Menzel's avatar
Robert Menzel committed
145
} // OpenGL
Robert Menzel's avatar
Robert Menzel committed
146 147
} // ACGL