Пример #1
0
// -------------------------------------------------------------------
void ObjFileParser::getVector( std::vector<aiVector3D> &point3d_array ) {
    size_t numComponents = getNumComponentsInLine();
    float x, y, z;
    if( 2 == numComponents ) {
        copyNextWord( m_buffer, Buffersize );
        x = ( float ) fast_atof( m_buffer );

        copyNextWord( m_buffer, Buffersize );
        y = ( float ) fast_atof( m_buffer );
        z = 0.0;
    } else if( 3 == numComponents ) {
        copyNextWord( m_buffer, Buffersize );
        x = ( float ) fast_atof( m_buffer );

        copyNextWord( m_buffer, Buffersize );
        y = ( float ) fast_atof( m_buffer );

        copyNextWord( m_buffer, Buffersize );
        z = ( float ) fast_atof( m_buffer );
    } else {
        throw DeadlyImportError( "OBJ: Invalid number of components" );
    }
    point3d_array.push_back( aiVector3D( x, y, z ) );
    m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
}
Пример #2
0
// -------------------------------------------------------------------
void ObjFileParser::getVector( std::vector<aiVector3D> &point3d_array ) {
    size_t numComponents( 0 );
    DataArrayIt tmp( m_DataIt );
    while( !IsLineEnd( *tmp ) ) {
        if( *tmp == ' ' ) {
            ++numComponents;
        }
        tmp++;
    }
    float x, y, z;
    if( 2 == numComponents ) {
        copyNextWord( m_buffer, BUFFERSIZE );
        x = ( float ) fast_atof( m_buffer );

        copyNextWord( m_buffer, BUFFERSIZE );
        y = ( float ) fast_atof( m_buffer );
        z = 0.0;
    } else if( 3 == numComponents ) {
        copyNextWord( m_buffer, BUFFERSIZE );
        x = ( float ) fast_atof( m_buffer );

        copyNextWord( m_buffer, BUFFERSIZE );
        y = ( float ) fast_atof( m_buffer );

        copyNextWord( m_buffer, BUFFERSIZE );
        z = ( float ) fast_atof( m_buffer );
    } else {
        ai_assert( !"Invalid number of components" );
    }
    point3d_array.push_back( aiVector3D( x, y, z ) );
    m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
}
// -------------------------------------------------------------------
void ObjFileParser::getVector( std::vector<aiVector3D> &point3d_array ) {
    size_t numComponents( 0 );
    const char* tmp( &m_DataIt[0] );
    while( !IsLineEnd( *tmp ) ) {
        if ( !SkipSpaces( &tmp ) ) {
            break;
        }
        SkipToken( tmp );
        ++numComponents;
    }
    float x, y, z;
    if( 2 == numComponents ) {
        copyNextWord( m_buffer, BUFFERSIZE );
        x = ( float ) fast_atof( m_buffer );

        copyNextWord( m_buffer, BUFFERSIZE );
        y = ( float ) fast_atof( m_buffer );
        z = 0.0;
    } else if( 3 == numComponents ) {
        copyNextWord( m_buffer, BUFFERSIZE );
        x = ( float ) fast_atof( m_buffer );

        copyNextWord( m_buffer, BUFFERSIZE );
        y = ( float ) fast_atof( m_buffer );

        copyNextWord( m_buffer, BUFFERSIZE );
        z = ( float ) fast_atof( m_buffer );
    } else {
        throw DeadlyImportError( "OBJ: Invalid number of components" );
    }
    point3d_array.push_back( aiVector3D( x, y, z ) );
    m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
}
Пример #4
0
// -------------------------------------------------------------------
//	Get values for a new 2D vector instance
void ObjFileParser::getVector2( std::vector<aiVector2D> &point2d_array ) {
	float x, y;
	copyNextWord(m_buffer, BUFFERSIZE);
	x = (float) fast_atof(m_buffer);	
	
	copyNextWord(m_buffer, BUFFERSIZE);
	y = (float) fast_atof(m_buffer);

	point2d_array.push_back(aiVector2D(x, y));

	m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
}
Пример #5
0
void MeshManager::getVector2(std::vector<glm::vec2>* vertices, char* buffer, int* i){
	getNextWord(buffer, i);
	float x, y;

	copyNextWord(tempBuffer, BUFFERSIZE, buffer, i);
	x = (float) fast_atof(tempBuffer);

	copyNextWord(tempBuffer, BUFFERSIZE, buffer, i);
	y = (float) fast_atof(tempBuffer);

	vertices->push_back(glm::vec2(x, y));

	skipLine(buffer, i);
}
Пример #6
0
// -------------------------------------------------------------------
//  Get values for a new 3D vector instance
void ObjFileParser::getVector3( std::vector<aiVector3D> &point3d_array ) {
    float x, y, z;
    copyNextWord(m_buffer, Buffersize);
    x = (float) fast_atof(m_buffer);

    copyNextWord(m_buffer, Buffersize);
    y = (float) fast_atof(m_buffer);

    copyNextWord( m_buffer, Buffersize );
    z = ( float ) fast_atof( m_buffer );

    point3d_array.push_back( aiVector3D( x, y, z ) );
    m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
}
Пример #7
0
float
XMLReader::getFloat(const char* name) const noexcept
{
	auto value = getString(name);
	if (!value.empty())
		return fast_atof(value.c_str());

	return 0.0;
}
Пример #8
0
// ------------------------------------------------------------------------------------------------
float ParseTokenAsFloat(const Token& t, const char*& err_out)
{
    err_out = NULL;

    if (t.Type() != TokenType_DATA) {
        err_out = "expected TOK_DATA token";
        return 0.0f;
    }

    if(t.IsBinary())
    {
        const char* data = t.begin();
        if (data[0] != 'F' && data[0] != 'D') {
            err_out = "failed to parse F(loat) or D(ouble), unexpected data type (binary)";
            return 0.0f;
        }

        if (data[0] == 'F') {
            return SafeParse<float>(data+1, t.end());
        }
        else {
            return static_cast<float>( SafeParse<double>(data+1, t.end()) );
        }
    }

    // need to copy the input string to a temporary buffer
    // first - next in the fbx token stream comes ',',
    // which fast_atof could interpret as decimal point.
#define MAX_FLOAT_LENGTH 31
    char temp[MAX_FLOAT_LENGTH + 1];
    const size_t length = static_cast<size_t>(t.end()-t.begin());
    std::copy(t.begin(),t.end(),temp);
    temp[std::min(static_cast<size_t>(MAX_FLOAT_LENGTH),length)] = '\0';

    return fast_atof(temp);
}
Пример #9
0
// -------------------------------------------------------------------
//	Loads a single float value. 
void ObjFileMtlImporter::getFloatValue( float &value )
{
	m_DataIt = CopyNextWord<DataArrayIt>( m_DataIt, m_DataItEnd, m_buffer, BUFFERSIZE );
	value = (float) fast_atof(m_buffer);
}
Пример #10
0
Mesh* MeshManager::parseMD5(string filename, char* buffer, int lenght){
    Mesh* resultMesh = new Mesh(filename, getNewId());
	int numJoints = 0;
	int numMeshes = 0;
	int numVerts = 0;
	int numTris = 0;
	int numWeights = 0;
	unsigned int idSubMesh = 0;
	int n = 0;
	copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);//autoincrease i
	while (buffer[n] != '\0'){
		if(strncmp(tempBuffer, "MD5Version", 10) == 0){
			copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);
			//resultMesh->versionMD5 = (int) atoi(tempBuffer);
			//logInf("md5 version %s", tempBuffer);
		}
		else if(strncmp(tempBuffer, "commandline", 11) == 0){
			skipLine(buffer, &n);
		}
		else if(strncmp(tempBuffer, "numJoints", 9) == 0){
			copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);
			numJoints = (int) atoi(tempBuffer);
			resultMesh->joints.reserve(numJoints);
		}
		else if(strncmp(tempBuffer, "numMeshes", 9) == 0){
			copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);
			numMeshes = (int) atoi(tempBuffer);
			resultMesh->subMeshes.reserve(numMeshes);
		}
		else if(strncmp(tempBuffer, "joints", 6) == 0){
			copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); //read the '{' character
			Mesh::Joint auxJoint;
			for(int i = 0; i < numJoints; i++){
				copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);
				auxJoint.jointName = tempBuffer;
				copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);
				auxJoint.jointParentID = (int) atoi(tempBuffer);
				copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);// '(' char
				copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);
				auxJoint.jointPos.x = (float) fast_atof(tempBuffer);
				copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);
				auxJoint.jointPos.y = (float) fast_atof(tempBuffer);
				copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);
				auxJoint.jointPos.z = (float) fast_atof(tempBuffer);
				copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);// ')' char
				copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);// '(' char
				copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);
				auxJoint.jointOrient.x = (float) fast_atof(tempBuffer);
				copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);
				auxJoint.jointOrient.y = (float) fast_atof(tempBuffer);
				copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);
				auxJoint.jointOrient.z = (float) fast_atof(tempBuffer);
				skipLine(buffer, &n);

				removeQuotes(&(auxJoint.jointName));
				computeQuaternionW(&(auxJoint.jointOrient));

				resultMesh->joints.push_back(auxJoint);
			}
		}
		else if(strncmp(tempBuffer, "mesh", 4) == 0){
			SubMesh* auxSubMesh = new SubMesh(idSubMesh);
			idSubMesh++;
			copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);// char {
			copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);
			while(strncmp(tempBuffer, "}", 1) != 0){
				if(strncmp(tempBuffer, "shader", 6) == 0){
					///////////////TODO
					//shader factory
					//used to set the texture!! be careful
					copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);
					auxSubMesh->setSubMeshTextureName(tempBuffer);
					skipLine(buffer, &n);
				}
				else if(strncmp(tempBuffer, "numverts", 8) == 0){
					copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);
					numVerts = (int) atoi(tempBuffer);
					glm::vec2 textCoord;
					glm::i32vec2 weightStartAndCount;
					for(int i = 0; i < numVerts; ++i){
						copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);//"vert"
						copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);//id (sorted)
						copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);//'('

						copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);
						textCoord.x = (float) fast_atof(tempBuffer);
						copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);
						textCoord.y = (float) fast_atof(tempBuffer);

						copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);//')'

						copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);
						weightStartAndCount.x = (int) atoi(tempBuffer);
						copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);
						weightStartAndCount.y = (int) atoi(tempBuffer);

						auxSubMesh->textureCoord.push_back(textCoord);
						auxSubMesh->weightsIndex.push_back(weightStartAndCount);
					}
				}
				else if(strncmp(tempBuffer, "numtris", 7) == 0){
					copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);
					numTris = (int) atoi(tempBuffer);
					glm::i32vec3 tri;
					auxSubMesh->elements.reserve(numTris);
					for (int i = 0; i < numTris; ++i){
						copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);
						copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);
						copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);
						tri.x = (int) atoi(tempBuffer);
						copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);
						tri.z = (int) atoi(tempBuffer);
						copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);
						tri.y = (int) atoi(tempBuffer);
						auxSubMesh->elements.push_back(tri);
					}
				}
				else if(strncmp(tempBuffer, "numweights", 10) == 0){
					copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);
					numWeights = (int) atoi(tempBuffer);
					SubMesh::Weight auxWeight;
					auxSubMesh->weights.reserve(numWeights);
					for (int i = 0; i < numWeights; ++i){
						//logInf("Weight[%i]",i);
						copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);//weight
						copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);//id (sorted)
						copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);//id joint
						auxWeight.weightJointID = (int) atoi(tempBuffer);
						copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);//bias
						auxWeight.weightBias = (float) fast_atof(tempBuffer);
						copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);//'('
						copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);
						auxWeight.weightPos.x = (float) fast_atof(tempBuffer);
						copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);
						auxWeight.weightPos.y = (float) fast_atof(tempBuffer);
						copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);
						auxWeight.weightPos.z = (float) fast_atof(tempBuffer);
						copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);//')'

						auxSubMesh->weights.push_back(auxWeight);
						//logInf("Weight[%i]",i);
					}
				}
				else if(strncmp(tempBuffer, "//", 2) == 0){
					skipLine(buffer, &n);
				}
				copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);

			}
			prepareSubMeshVertex(resultMesh, auxSubMesh);
			prepareSubMeshNormals(resultMesh, auxSubMesh);
			resultMesh->subMeshes.push_back(auxSubMesh);
		}

		copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);//autoincrease i
        if(n>=lenght)break;

	}
	return resultMesh;
}
Пример #11
0
	/*! Set the value from a string.
	  \param from value to set
	  \return original value (double) */
	virtual const double& set_from_raw(const f8String& from) { return _value = fast_atof(from.c_str()); }
Пример #12
0
	/*! Construct from string ctor.
	  \param from string to construct field from
	  \param rlm pointer to the realmbase for this field (if available) */
	Field (const f8String& from, const RealmBase *rlm=0) : BaseField(field, rlm), _value(fast_atof(from.c_str())), _precision(2) {}
Пример #13
0
std::vector<Vertex> parseObj(const char* filename, const std::string& shading_model){
	bool has_texture = false;
	FILE* file;
	char line[128];
	
	// Hold the data from the object file
	std::vector<glm::vec3> temp_vertices;
	std::vector<glm::vec3> temp_vnormals;
	std::vector<glm::vec2> temp_vt;
	
	std::vector<ushort> normal_elements;
	std::vector<ushort> vertex_elements;
	std::vector<ushort> vt_elements;
	
	std::vector<Vertex> vertices;
	
	file = fopen(filename, "r");
	
	while( fgets(line, sizeof(line), file) != NULL){
		switch(line[0]){
		case 'v':
			switch(line[1]){
			case ' ':{
				uchar nchar = 2;
				glm::vec3 v;
				for(int i = 0; i < 3; i++){
					char buff[32];
					nchar += getNextWord(line + nchar, buff);
					v[i] = fast_atof(buff);
				}
				temp_vertices.push_back(v);
				break;
			}
			case 'n':{
				uchar nchar = 3;
				glm::vec3 vn;
				for(int i = 0; i < 3; i++){
					char buff[32];
					nchar += getNextWord(line + nchar, buff);
					vn[i] = fast_atof(buff);
				}
				temp_vnormals.push_back(vn);
				break;
			}
			case 't':{
				has_texture = true;
				uchar nchar = 3;
				glm::vec2 vt;
				for(int i = 0; i < 2; i++){
					char buff[32];
					nchar += getNextWord(line + nchar, buff);
					vt[i] = fast_atof(buff);
				}
				temp_vt.push_back(vt);
				break;
			}
			}
			break;
		case 'f':{
			ushort f,fn;
			if(!has_texture){
				uchar nchar = 2;
				for(int i = 0; i < 3; i++){
					char buff[32];
					nchar += getNextWord(line + nchar, buff);
					uchar nextpos = findCharAndTerminate(buff, '/');
					nextpos++;
					f = (ushort)strtoul10(buff);
					fn = (ushort)strtoul10(buff + nextpos);
					vertex_elements.push_back(--f);
					normal_elements.push_back(--fn);
				}
			}
			else{
				ushort vt;
				uchar nchar = 2;
				for(int i = 0; i < 3; i++){
					char buff[32];
					char *a = buff;
					nchar += getNextWord(line + nchar, buff);
					uchar nextpos = findCharAndTerminate(a, '/');
					f = (ushort)strtoul10(a);
					a += nextpos;
					nextpos = findCharAndTerminate(a, '/');
					vt = (ushort)strtoul10(a);
					a += nextpos;
					fn = (ushort)strtoul10(a);
					vertex_elements.push_back(--f);
					normal_elements.push_back(--fn);
					vt_elements.push_back(--vt);
				}
			}
			break;
		}
		default:
			break;
		}
	}
	
	fclose(file);
	// Make the vertex and normal lists
	int f_size = vertex_elements.size();
	
	if(shading_model == "smooth"){
		
		std::vector<glm::vec3> vertexnormals;
		int v_size = temp_vertices.size();
		
		for(int i = 0; i < v_size; i++){ //For every vertex
			glm::vec3 normal(0.0,0.0,0.0);
			for(int j = 0; j < f_size; j++){ //For every vertex of the triangles
				if(i == vertex_elements[j]){ //If they share the vertex
					normal+=temp_vnormals[normal_elements[j]];
				}
			}
			glm::normalize(normal);
			vertexnormals.push_back(normal);
		}
		if(!has_texture){
			for(int i = 0; i < f_size; i++){
				Vertex vertex(temp_vertices[vertex_elements[i]], vertexnormals[vertex_elements[i]]);
				vertices.push_back(vertex);
			}
		}
		else{
			for(int i = 0; i < f_size; i++){
				Vertex vertex(temp_vertices[vertex_elements[i]], vertexnormals[vertex_elements[i]], temp_vt[vt_elements[i]]);
				vertices.push_back(vertex);
			}
		}
	}
	else{
		if(!has_texture){
			for(int i = 0; i < f_size; i++){
				Vertex vertex(temp_vertices[vertex_elements[i]], temp_vnormals[normal_elements[i]]);
				vertices.push_back(vertex);
			}
		}
		else{
			for(int i = 0; i < f_size; i++){
				Vertex vertex(temp_vertices[vertex_elements[i]], temp_vnormals[normal_elements[i]], temp_vt[vt_elements[i]]);
				vertices.push_back(vertex);
			}
		}
	}
	return vertices;
}
	void COpenGLExtensionHandler::initExtensions(bool stencilBuffer)
	{
		const Real ogl_ver = fast_atof(reinterpret_cast<const c8*>(glGetString(GL_VERSION)));
		Version = static_cast<UINT16>(floor32(ogl_ver) * 100 + round32(fract(ogl_ver)*10.0f));
		if (Version >= 102)
			Printer::log("OpenGL driver version is 1.2 or better.", LML_NORMAL);
		else
			Printer::log("OpenGL driver version is not 1.2 or better.", LML_CRITICAL);

		{
			const char* t = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
			size_t len = 0;
			c8 *str = 0;
			if (t)
			{
				len = strlen(t);
				str = new c8[len + 1];
			}
			c8* p = str;

			for (size_t i = 0; i<len; ++i)
			{
				str[i] = static_cast<char>(t[i]);

				if (str[i] == ' ')
				{
					str[i] = 0;
					for (UINT32 j = 0; j<SAPPHIRE_OpenGL_Feature_Count; ++j)
					{
						if (!strcmp(OpenGLFeatureStrings[j], p))
						{
							FeatureAvailable[j] = true;
							break;
						}
					}

					p = p + strlen(p) + 1;
				}
			}

			delete[] str;
		}

		MultiTextureExtension = FeatureAvailable[SAPPHIRE_ARB_multitexture];
		TextureCompressionExtension = FeatureAvailable[SAPPHIRE_ARB_texture_compression];
		StencilBuffer = stencilBuffer;

#ifdef SAPPHIRE_OPENGL_USE_EXTPOINTER
#if (SAPPHIRE_PLATFORM == SAPPHIRE_PLATFORM_WIN32)
#define SAPPHIRE_OGL_LOAD_EXTENSION(x) wglGetProcAddress(reinterpret_cast<const char*>(x))
#elif defined(_SAPPHIRE_COMPILE_WITH_SDL_DEVICE_) && !defined(_SAPPHIRE_COMPILE_WITH_X11_DEVICE_)
#define SAPPHIRE_OGL_LOAD_EXTENSION(x) SDL_GL_GetProcAddress(reinterpret_cast<const char*>(x))
#else
		// Accessing the correct function is quite complex
		// All libraries should support the ARB version, however
		// since GLX 1.4 the non-ARB version is the official one
		// So we have to check the runtime environment and
		// choose the proper symbol
		// In case you still have problems please enable the
		// next line by uncommenting it
		// #define _SAPPHIRE_GETPROCADDRESS_WORKAROUND_

#ifndef _SAPPHIRE_GETPROCADDRESS_WORKAROUND_
		__GLXextFuncPtr(*SAPPHIRE_OGL_LOAD_EXTENSION_FUNCP)(const GLubyte*) = 0;
#ifdef GLX_VERSION_1_4
		int major = 0, minor = 0;
		if (glXGetCurrentDisplay())
			glXQueryVersion(glXGetCurrentDisplay(), &major, &minor);
		if ((major>1) || (minor>3))
			SAPPHIRE_OGL_LOAD_EXTENSION_FUNCP = glXGetProcAddress;
		else
#endif
			SAPPHIRE_OGL_LOAD_EXTENSION_FUNCP = glXGetProcAddressARB;
#define SAPPHIRE_OGL_LOAD_EXTENSION(X) SAPPHIRE_OGL_LOAD_EXTENSION_FUNCP(reinterpret_cast<const GLubyte*>(X))
#else
#define SAPPHIRE_OGL_LOAD_EXTENSION(X) glXGetProcAddressARB(reinterpret_cast<const GLubyte*>(X))
#endif // workaround
#endif // Windows, SDL, or Linux

		// get multitexturing function pointers
		pGlActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glActiveTextureARB");
		pGlClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glClientActiveTextureARB");

		// get fragment and vertex program function pointers
		pGlGenProgramsARB = (PFNGLGENPROGRAMSARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGenProgramsARB");
		pGlGenProgramsNV = (PFNGLGENPROGRAMSNVPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGenProgramsNV");
		pGlBindProgramARB = (PFNGLBINDPROGRAMARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glBindProgramARB");
		pGlBindProgramNV = (PFNGLBINDPROGRAMNVPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glBindProgramNV");
		pGlProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glProgramStringARB");
		pGlLoadProgramNV = (PFNGLLOADPROGRAMNVPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glLoadProgramNV");
		pGlDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glDeleteProgramsARB");
		pGlDeleteProgramsNV = (PFNGLDELETEPROGRAMSNVPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glDeleteProgramsNV");
		pGlProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glProgramLocalParameter4fvARB");
		pGlCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glCreateShaderObjectARB");
		pGlCreateShader = (PFNGLCREATESHADERPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glCreateShader");
		pGlShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glShaderSourceARB");
		pGlShaderSource = (PFNGLSHADERSOURCEPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glShaderSource");
		pGlCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glCompileShaderARB");
		pGlCompileShader = (PFNGLCOMPILESHADERPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glCompileShader");
		pGlCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glCreateProgramObjectARB");
		pGlCreateProgram = (PFNGLCREATEPROGRAMPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glCreateProgram");
		pGlAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glAttachObjectARB");
		pGlAttachShader = (PFNGLATTACHSHADERPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glAttachShader");
		pGlLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glLinkProgramARB");
		pGlLinkProgram = (PFNGLLINKPROGRAMPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glLinkProgram");
		pGlUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glUseProgramObjectARB");
		pGlUseProgram = (PFNGLUSEPROGRAMPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glUseProgram");
		pGlDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glDeleteObjectARB");
		pGlDeleteProgram = (PFNGLDELETEPROGRAMPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glDeleteProgram");
		pGlDeleteShader = (PFNGLDELETESHADERPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glDeleteShader");
		pGlGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGetAttachedShaders");
		pGlGetAttachedObjectsARB = (PFNGLGETATTACHEDOBJECTSARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGetAttachedObjectsARB");
		pGlGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGetInfoLogARB");
		pGlGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGetShaderInfoLog");
		pGlGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGetProgramInfoLog");
		pGlGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGetObjectParameterivARB");
		pGlGetShaderiv = (PFNGLGETSHADERIVPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGetShaderiv");
		pGlGetProgramiv = (PFNGLGETPROGRAMIVPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGetProgramiv");
		pGlGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGetUniformLocationARB");
		pGlGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGetUniformLocation");
		pGlUniform1fvARB = (PFNGLUNIFORM1FVARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glUniform1fvARB");
		pGlUniform2fvARB = (PFNGLUNIFORM2FVARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glUniform2fvARB");
		pGlUniform3fvARB = (PFNGLUNIFORM3FVARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glUniform3fvARB");
		pGlUniform4fvARB = (PFNGLUNIFORM4FVARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glUniform4fvARB");
		pGlUniform1ivARB = (PFNGLUNIFORM1IVARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glUniform1ivARB");
		pGlUniform2ivARB = (PFNGLUNIFORM2IVARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glUniform2ivARB");
		pGlUniform3ivARB = (PFNGLUNIFORM3IVARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glUniform3ivARB");
		pGlUniform4ivARB = (PFNGLUNIFORM4IVARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glUniform4ivARB");
		pGlUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glUniformMatrix2fvARB");
		pGlUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glUniformMatrix3fvARB");
		pGlUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glUniformMatrix4fvARB");
		pGlGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGetActiveUniformARB");
		pGlGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGetActiveUniform");

		// get point parameter extension
		pGlPointParameterfARB = (PFNGLPOINTPARAMETERFARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glPointParameterfARB");
		pGlPointParameterfvARB = (PFNGLPOINTPARAMETERFVARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glPointParameterfvARB");

		// get stencil extension
		pGlStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glStencilFuncSeparate");
		pGlStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glStencilOpSeparate");
		pGlStencilFuncSeparateATI = (PFNGLSTENCILFUNCSEPARATEATIPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glStencilFuncSeparateATI");
		pGlStencilOpSeparateATI = (PFNGLSTENCILOPSEPARATEATIPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glStencilOpSeparateATI");

		// compressed textures
		pGlCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glCompressedTexImage2D");

		// ARB FrameBufferObjects
		pGlBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glBindFramebuffer");
		pGlDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glDeleteFramebuffers");
		pGlGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGenFramebuffers");
		pGlCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glCheckFramebufferStatus");
		pGlFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glFramebufferTexture2D");
		pGlBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glBindRenderbuffer");
		pGlDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glDeleteRenderbuffers");
		pGlGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGenRenderbuffers");
		pGlRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glRenderbufferStorage");
		pGlFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glFramebufferRenderbuffer");
		pGlGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGenerateMipmap");

		// EXT FrameBufferObjects
		pGlBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glBindFramebufferEXT");
		pGlDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glDeleteFramebuffersEXT");
		pGlGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGenFramebuffersEXT");
		pGlCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glCheckFramebufferStatusEXT");
		pGlFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glFramebufferTexture2DEXT");
		pGlBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glBindRenderbufferEXT");
		pGlDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glDeleteRenderbuffersEXT");
		pGlGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGenRenderbuffersEXT");
		pGlRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glRenderbufferStorageEXT");
		pGlFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glFramebufferRenderbufferEXT");
		pGlGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGenerateMipmapEXT");
		pGlDrawBuffersARB = (PFNGLDRAWBUFFERSARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glDrawBuffersARB");
		pGlDrawBuffersATI = (PFNGLDRAWBUFFERSATIPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glDrawBuffersATI");

		// get vertex buffer extension
		pGlGenBuffersARB = (PFNGLGENBUFFERSARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGenBuffersARB");
		pGlBindBufferARB = (PFNGLBINDBUFFERARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glBindBufferARB");
		pGlBufferDataARB = (PFNGLBUFFERDATAARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glBufferDataARB");
		pGlDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glDeleteBuffersARB");
		pGlBufferSubDataARB = (PFNGLBUFFERSUBDATAARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glBufferSubDataARB");
		pGlGetBufferSubDataARB = (PFNGLGETBUFFERSUBDATAARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGetBufferSubDataARB");
		pGlMapBufferARB = (PFNGLMAPBUFFERARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glMapBufferARB");
		pGlUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glUnmapBufferARB");
		pGlIsBufferARB = (PFNGLISBUFFERARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glIsBufferARB");
		pGlGetBufferParameterivARB = (PFNGLGETBUFFERPARAMETERIVARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGetBufferParameterivARB");
		pGlGetBufferPointervARB = (PFNGLGETBUFFERPOINTERVARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGetBufferPointervARB");
		pGlProvokingVertexARB = (PFNGLPROVOKINGVERTEXPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glProvokingVertex");
		pGlProvokingVertexEXT = (PFNGLPROVOKINGVERTEXEXTPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glProvokingVertexEXT");
		pGlColorMaskIndexedEXT = (PFNGLCOLORMASKINDEXEDEXTPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glColorMaskIndexedEXT");
		pGlEnableIndexedEXT = (PFNGLENABLEINDEXEDEXTPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glEnableIndexedEXT");
		pGlDisableIndexedEXT = (PFNGLDISABLEINDEXEDEXTPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glDisableIndexedEXT");
		pGlBlendFuncIndexedAMD = (PFNGLBLENDFUNCINDEXEDAMDPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glBlendFuncIndexedAMD");
		pGlBlendFunciARB = (PFNGLBLENDFUNCIPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glBlendFunciARB");
		pGlBlendEquationIndexedAMD = (PFNGLBLENDEQUATIONINDEXEDAMDPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glBlendEquationIndexedAMD");
		pGlBlendEquationiARB = (PFNGLBLENDEQUATIONIPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glBlendEquationiARB");
		pGlProgramParameteriARB = (PFNGLPROGRAMPARAMETERIARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glProgramParameteriARB");
		pGlProgramParameteriEXT = (PFNGLPROGRAMPARAMETERIEXTPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glProgramParameteriEXT");

		// occlusion query
		pGlGenQueriesARB = (PFNGLGENQUERIESARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGenQueriesARB");
		pGlDeleteQueriesARB = (PFNGLDELETEQUERIESARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glDeleteQueriesARB");
		pGlIsQueryARB = (PFNGLISQUERYARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glIsQueryARB");
		pGlBeginQueryARB = (PFNGLBEGINQUERYARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glBeginQueryARB");
		pGlEndQueryARB = (PFNGLENDQUERYARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glEndQueryARB");
		pGlGetQueryivARB = (PFNGLGETQUERYIVARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGetQueryivARB");
		pGlGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGetQueryObjectivARB");
		pGlGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGetQueryObjectuivARB");
		pGlGenOcclusionQueriesNV = (PFNGLGENOCCLUSIONQUERIESNVPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGenOcclusionQueriesNV");
		pGlDeleteOcclusionQueriesNV = (PFNGLDELETEOCCLUSIONQUERIESNVPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glDeleteOcclusionQueriesNV");
		pGlIsOcclusionQueryNV = (PFNGLISOCCLUSIONQUERYNVPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glIsOcclusionQueryNV");
		pGlBeginOcclusionQueryNV = (PFNGLBEGINOCCLUSIONQUERYNVPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glBeginOcclusionQueryNV");
		pGlEndOcclusionQueryNV = (PFNGLENDOCCLUSIONQUERYNVPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glEndOcclusionQueryNV");
		pGlGetOcclusionQueryivNV = (PFNGLGETOCCLUSIONQUERYIVNVPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGetOcclusionQueryivNV");
		pGlGetOcclusionQueryuivNV = (PFNGLGETOCCLUSIONQUERYUIVNVPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glGetOcclusionQueryuivNV");

		// blend equation
		pGlBlendEquationEXT = (PFNGLBLENDEQUATIONEXTPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glBlendEquationEXT");
		pGlBlendEquation = (PFNGLBLENDEQUATIONPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glBlendEquation");

		// get vsync extension
#if defined(WGL_EXT_swap_control) && !defined(_SAPPHIRE_COMPILE_WITH_SDL_DEVICE_)
		pWglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)SAPPHIRE_OGL_LOAD_EXTENSION("wglSwapIntervalEXT");
#endif
#if defined(GLX_SGI_swap_control) && !defined(_SAPPHIRE_COMPILE_WITH_SDL_DEVICE_)
		pGlxSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glXSwapIntervalSGI");
#endif
#if defined(GLX_EXT_swap_control) && !defined(_SAPPHIRE_COMPILE_WITH_SDL_DEVICE_)
		pGlxSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glXSwapIntervalEXT");
#endif
#if defined(GLX_MESA_swap_control) && !defined(_SAPPHIRE_COMPILE_WITH_SDL_DEVICE_)
		pGlxSwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)SAPPHIRE_OGL_LOAD_EXTENSION("glXSwapIntervalMESA");
#endif
#endif // use extension pointer

		GLint num = 0;
		// set some properties
#if defined(GL_ARB_multitexture) || defined(GL_VERSION_1_3)
		if (Version>102 || FeatureAvailable[SAPPHIRE_ARB_multitexture])
		{
#if defined(GL_MAX_TEXTURE_UNITS)
			glGetIntegerv(GL_MAX_TEXTURE_UNITS, &num);
#elif defined(GL_MAX_TEXTURE_UNITS_ARB)
			glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &num);
#endif
			MaxSupportedTextures = static_cast<UINT8>(num);
		}
#endif
#if defined(GL_ARB_vertex_shader) || defined(GL_VERSION_2_0)
		if (Version >= 200 || FeatureAvailable[SAPPHIRE_ARB_vertex_shader])
		{
			num = 0;
#if defined(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS)
			glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &num);
#elif defined(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB)
			glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, &num);
#endif
			MaxSupportedTextures = Math::_max<UINT8>(MaxSupportedTextures, static_cast<UINT8>(num));
		}
#endif
		glGetIntegerv(GL_MAX_LIGHTS, &num);
		MaxLights = static_cast<UINT8>(num);
#ifdef GL_EXT_texture_filter_anisotropic
		if (FeatureAvailable[SAPPHIRE_EXT_texture_filter_anisotropic])
		{
			glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &num);
			MaxAnisotropy = static_cast<UINT8>(num);
		}
#endif
#ifdef GL_VERSION_1_2
		if (Version>101)
		{
			glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &num);
			MaxIndices = num;
		}
#endif
		glGetIntegerv(GL_MAX_TEXTURE_SIZE, &num);
		MaxTextureSize = static_cast<UINT32>(num);
		if (queryFeature(EVDF_GEOMETRY_SHADER))
		{
#if defined(GL_ARB_geometry_shader4) || defined(GL_EXT_geometry_shader4) || defined(GL_NV_geometry_shader4)
			glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &num);
			MaxGeometryVerticesOut = static_cast<UINT32>(num);
#elif defined(GL_NV_geometry_program4)
			extGlGetProgramiv(GEOMETRY_PROGRAM_NV, GL_MAX_PROGRAM_OUTPUT_VERTICES_NV, &num);
			MaxGeometryVerticesOut = static_cast<UINT32>(num);
#endif
		}
#ifdef GL_EXT_texture_lod_bias
		if (FeatureAvailable[SAPPHIRE_EXT_texture_lod_bias])
			glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS_EXT, &MaxTextureLODBias);
#endif
		glGetIntegerv(GL_MAX_CLIP_PLANES, &num);
		MaxUserClipPlanes = static_cast<UINT8>(num);
		glGetIntegerv(GL_AUX_BUFFERS, &num);
		MaxAuxBuffers = static_cast<UINT8>(num);
#ifdef GL_ARB_draw_buffers
		if (FeatureAvailable[SAPPHIRE_ARB_draw_buffers])
		{
			glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &num);
			MaxMultipleRenderTargets = static_cast<UINT8>(num);
		}
#endif
#if defined(GL_ATI_draw_buffers)
#ifdef GL_ARB_draw_buffers
		else
#endif
			if (FeatureAvailable[SAPPHIRE_ATI_draw_buffers])
			{
				glGetIntegerv(GL_MAX_DRAW_BUFFERS_ATI, &num);
				MaxMultipleRenderTargets = static_cast<UINT8>(num);
			}
#endif
		glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, DimAliasedLine);
		glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, DimAliasedPoint);
		glGetFloatv(GL_SMOOTH_LINE_WIDTH_RANGE, DimSmoothedLine);
		glGetFloatv(GL_SMOOTH_POINT_SIZE_RANGE, DimSmoothedPoint);
#if defined(GL_ARB_shading_language_100) || defined (GL_VERSION_2_0)
		if (FeatureAvailable[SAPPHIRE_ARB_shading_language_100] || Version >= 200)
		{
			glGetError(); // clean error buffer
#ifdef GL_SHADING_LANGUAGE_VERSION
			const GLubyte* shaderVersion = glGetString(GL_SHADING_LANGUAGE_VERSION);
#else
			const GLubyte* shaderVersion = glGetString(GL_SHADING_LANGUAGE_VERSION_ARB);
#endif
			if (glGetError() == GL_INVALID_ENUM)
				ShaderLanguageVersion = 100;
			else
			{
				const Real sl_ver = fast_atof(reinterpret_cast<const c8*>(shaderVersion));
				ShaderLanguageVersion = static_cast<UINT16>(floor32(sl_ver) * 100 + round32(fract(sl_ver)*10.0f));
			}
		}
#endif

#ifdef SAPPHIRE_OPENGL_USE_EXTPOINTER
		if (!pGlActiveTextureARB || !pGlClientActiveTextureARB)
		{
			MultiTextureExtension = false;
			Printer::log("Failed to load OpenGL's multitexture extension, proceeding without.", LML_CRITICAL);
		}
		else
#endif
			MaxTextureUnits = Math::_min(MaxSupportedTextures, static_cast<UINT8>(MATERIAL_MAX_TEXTURES));
		if (MaxTextureUnits < 2)
		{
			MultiTextureExtension = false;
			Printer::log("Warning: OpenGL device only has one texture unit. Disabling multitexturing.", LML_CRITICAL);
		}

#ifdef GL_ARB_occlusion_query
		if (FeatureAvailable[SAPPHIRE_ARB_occlusion_query])
		{
			extGlGetQueryiv(GL_SAMPLES_PASSED_ARB, GL_QUERY_COUNTER_BITS_ARB,
				&num);
			OcclusionQuerySupport = (num>0);
		}
		else
#endif
#ifdef GL_NV_occlusion_query
			if (FeatureAvailable[SAPPHIRE_NV_occlusion_query])
			{
				glGetIntegerv(GL_PIXEL_COUNTER_BITS_NV, &num);
				OcclusionQuerySupport = (num>0);
			}
			else
#endif
				OcclusionQuerySupport = false;

#ifdef _DEBUG
		if (FeatureAvailable[SAPPHIRE_NVX_gpu_memory_info])
		{
			// undocumented flags, so use the RAW values
			GLint val = 0;
			StringUtil::StrStreamType ss;
			ss << val;
			glGetIntegerv(0x9047, &val);
			Printer::log("Dedicated video memory (kB)", ss.str());
			glGetIntegerv(0x9048, &val);
			Printer::log("Total video memory (kB)", ss.str());
			glGetIntegerv(0x9049, &val);
			Printer::log("Available video memory (kB)", ss.str());
		}
#ifdef GL_ATI_meminfo
		if (FeatureAvailable[SAPPHIRE_ATI_meminfo])
		{
			GLint val[4];
			StringUtil::StrStreamType ss;
			ss << val;
			glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, val);
			Printer::log("Free texture memory (kB)", ss.str());
			glGetIntegerv(GL_VBO_FREE_MEMORY_ATI, val);
			Printer::log("Free VBO memory (kB)", ss.str());
			glGetIntegerv(GL_RENDERBUFFER_FREE_MEMORY_ATI, val);
			Printer::log("Free render buffer memory (kB)", ss.str());
		}
#endif
#endif
	}