Commits

Jason McKesson  committed f6db273

First specification.

  • Participants

Comments (0)

Files changed (28)

File ConvertAllSpecFilesToLua.lua

+--[[
+Running this file will convert all of the current spec files into lua files.
+
+The lua files can have dofile run on them; this will return a table as formatted in
+ExtractSpecsToFile.lua.
+]]
+
+require "_ExtractSpecsToFile"
+
+ExtractSpecsToFile("glspec.lua", {
+	glspec = "gl.spec",
+	enumext = "enumext.spec",
+	gltm = "gl.tm"
+	})
+
+ExtractSpecsToFile("wglspec.lua", {
+	glspec = "wglext.spec",
+	enumext = "wglenumext.spec",
+	gltm = "wgl.tm"
+	},
+	"WGL")
+
+ExtractSpecsToFile("glxspec.lua", {
+	glspec = "glxext.spec",
+	enumext = "glxenumext.spec",
+	gltm = "glx.tm"
+	})
+
+<?xml version="1.0" encoding="UTF-8"?>
+<?oxygen RNGSchema="http://docbook.org/xml/5.0/rng/docbookxi.rng" type="xml"?>
+<?oxygen SCHSchema="http://docbook.org/xml/5.0/rng/docbookxi.rng"?>
+<article xmlns="http://docbook.org/ns/docbook" xmlns:xi="http://www.w3.org/2001/XInclude"
+    xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0">
+    <title>OpenGL XML Spec Documentation</title>
+    <para>G</para>
+</article>
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="11.2">
+    <meta>
+        <filters directoryPatterns="" filePatterns=""
+            positiveFilePatterns="" showHiddenFiles="false"/>
+        <options/>
+    </meta>
+    <projectTree name="Docs.xpr">
+        <file name="Docs.xml"/>
+    </projectTree>
+</project>

File XML Spec Format.rnc

+datatypes xsd = "http://www.w3.org/2001/XMLSchema-datatypes"
+namespace a = "http://relaxng.org/ns/compatibility/annotations/1.0"
+namespace gl = "http://www.opengl.org/registry/"
+
+
+start = gl.rootelements
+
+## Root and direct child elements.
+div
+{
+    gl.rootelements = 
+        gl.specification
+     
+    gl.specification =
+        ## The specification itself.
+        element gl:specification { gl.specification.contents }
+        
+    gl.specification.contents =
+        gl.specification.attributes, gl.typemap, gl.extensions, gl.enumerations, gl.functions
+        
+    gl.specification.attributes =
+        gl.specification.name.attribute,
+        gl.specification.glversion.attribute,
+        gl.specification.fileversion.attribute
+
+
+    gl.typemap =
+        ## The list of types and their associated language-specific versions.
+        element gl:typemap { gl.typemap.contents }
+        
+    gl.typemap.contents =
+        gl.type-def+
+
+
+    gl.extensions = 
+        ## The comprehensive list of all extensions.
+        element gl:extensions { gl.extensions.contents }
+        
+    gl.extensions.contents =
+        gl.ext+
+    
+    gl.enumerations =
+        ## The comprehensive list of all enumerators.
+        element gl:enumerations { gl.enumerations.contents }
+        
+    gl.enumerations.contents =
+        gl.enum+
+    
+    gl.functions =
+        ## The comprehensive list of all function definitions.
+        element gl:functions { gl.functions.contents }
+        
+    gl.functions.contents =
+        gl.passthru?,
+        gl.property-defs,
+        gl.function-defs
+}
+
+## Typemap elements.
+div
+{
+    gl.type-def =
+        element gl:type-def { gl.type-def.contents }
+
+    gl.type-def.contents =
+        gl.type-def.attributes
+        
+    gl.type-def.attributes =
+        gl.type-def.typename.attribute,
+        gl.type-def.C-lang.attribute
+}
+
+## Extensions elements.
+div
+{
+    gl.ext =
+        element gl:ext { gl.ext.contents }
+        
+    gl.ext.contents =
+        gl.ext.attributes
+        
+    gl.ext.attributes =
+        gl.ext.name.attribute
+}
+
+## Enumerators elements.
+div
+{
+    gl.enum =
+        element gl:enum { gl.enum.contents }
+        
+    gl.enum.contents =
+        gl.enum.attributes, gl.enum.ext*
+        
+    gl.enum.attributes =
+        gl.enum.name.attribute,
+        (gl.enum.value.attribute | gl.enum.ref.attribute),
+        gl.enum.version.attribute?,
+        gl.enum.deprecated.attribute?,
+        gl.enum.removed.attribute?
+        
+    gl.enum.ext =
+        element gl:ext { gl.enum.ext.contents }
+        
+    gl.enum.ext.contents =
+        gl.enum.ext.attributes
+        
+    gl.enum.ext.attributes =
+        gl.enum.ext.name.attribute
+}
+
+## Function elements
+div
+{
+    gl.passthru =
+        element gl:passthru { gl.passthru.contents }
+        
+    gl.passthru.contents =
+        text
+        
+    gl.property-defs =
+        element gl:property-defs { gl.property-defs.contents }
+
+    gl.property-defs.contents =
+        gl.property+
+        
+    gl.property =
+        element gl:property { gl.property.contents }
+    
+    gl.property.contents =
+        gl.property.name.attribute,
+        ( gl.property.any.attribute | gl.property.value+ )
+        
+    gl.property.value =
+        element gl:value { gl.property.value.contents }
+
+    gl.property.value.contents =
+        text
+
+    gl.function-defs =
+        element gl:function-defs { gl.function-defs.contents }
+
+    gl.function-defs.contents =
+        gl.function+
+
+    gl.function =
+        element gl:function { gl.function.contents }
+        
+    gl.function.contents =
+        gl.function.name.attribute,
+        gl.function.return.attribute,
+        gl.function.property.attribute*,
+        gl.function.param*
+        
+    gl.function.param =
+        element gl:param { gl.function.param.contents }
+        
+    gl.function.param.contents =
+        gl.param.name.attribute,
+        gl.param.kind.attribute,
+        gl.param.type.attribute,
+        gl.param.input.attribute,
+        gl.param.compute.attribute?
+}
+
+
+## Attributes
+div
+{
+    gl.specification.name.attribute =
+        attribute name {text}
+    
+    gl.specification.glversion.attribute =
+        attribute glversion {openglversion}
+
+    gl.specification.fileversion.attribute =
+        attribute fileversion {xsd:string {pattern = "\d+\.\d+\.\d+"}}
+
+    gl.type-def.typename.attribute =
+        attribute typename {text}
+
+    gl.type-def.C-lang.attribute =
+        attribute C-lang {text}
+
+    gl.ext.name.attribute =
+        attribute name {nondigitidentifier}
+
+    gl.enum.name.attribute =
+        attribute name {nondigitidentifier}
+
+    gl.enum.value.attribute =
+        attribute value {xsd:unsignedInt | xsd:string {pattern = "0x[\dabcdefABCDEF]+"}}
+
+    gl.enum.ref.attribute =
+        attribute ref {text}
+
+    gl.enum.version.attribute =
+        attribute version {openglversion}
+
+    gl.enum.deprecated.attribute =
+        attribute deprecated {openglversion}
+
+    gl.enum.removed.attribute =
+        attribute removed {openglversion}
+
+    gl.enum.ext.name.attribute =
+        attribute name {nondigitidentifier}
+
+    gl.property.name.attribute =
+        attribute name {text}
+
+    gl.property.any.attribute =
+        attribute any {"true"}
+
+    gl.property.value.attribute =
+        attribute value {text}
+
+    gl.function.name.attribute =
+        attribute name {identifier}
+
+    gl.function.return.attribute =
+        attribute return {text}
+
+    gl.function.property.attribute =
+        attribute * - (return | name) {text}
+
+    gl.param.name.attribute =
+        attribute name {identifier}
+
+    gl.param.kind.attribute =
+        attribute kind {"value" | "array"}
+
+    gl.param.type.attribute =
+        attribute type {text}
+
+    gl.param.input.attribute =
+        attribute input {xsd:boolean}
+
+    gl.param.compute.attribute =
+        attribute compute {text}
+
+}
+
+## Helpers
+div
+{
+    openglversion =
+        xsd:decimal {pattern = "\d+\.\d+"}
+        
+    nondigitidentifier =
+        xsd:string {pattern = "[\w_]+"}
+        
+    identifier =
+        xsd:string {pattern = "\i\c*"}
+}
+
+

File _ExtractEnums.lua

+--[[
+The exported function, ExtractEnums, returns the enum data as follows:
+
+An array of enumerators, ordered as in enumext.spec. Each enumerator is a table that contains
+these fields:
+
+- name: String containing the name of the enumerator.
+- value: String number containing the value of the enumerator, or the name of an enumerator to copy from.
+- copy: True if the value is an enumerator to copy from; false if it's a number.
+- version: String in A.B format contining the core version for this enumerator.
+- deprecated: String in A.B format for the version where the enumerator was deprecated.
+- removed: String in A.B format when the enumerator was removed from GL.
+- extension: An array of extension names.
+]]
+
+require("_line");
+
+--GLOBAL: Bad form, I know, but it's the easiest way to do this.
+local clipPattern = nil;
+
+
+local function AddExtToEnum(enumEntry, extName)
+	if(enumEntry.extensions == nil) then enumEntry.extensions = {}; end;
+	
+	if(clipPattern) then
+		local newExtName = string.match(extName, clipPattern);
+		if(newExtName) then extName = newExtName; end;
+	end
+	
+	table.insert(enumEntry.extensions, extName);
+end
+
+local function FetchEnum(currState, enumName)
+	if(clipPattern) then
+		local newEnumName = string.match(enumName, clipPattern);
+		if(newEnumName) then enumName = newEnumName; end;
+	end
+	
+	if(currState.enumMap[enumName] == nil) then
+		currState.enumMap[enumName] = {};
+		table.insert(currState.enumArray, currState.enumMap[enumName]);
+	end
+
+	local enumEntry = currState.enumMap[enumName];
+	enumEntry.name = enumName;
+	
+	if(currState.extDef.version) then
+		enumEntry.version = currState.extDef.version;
+	else
+		AddExtToEnum(enumEntry, currState.extDef.extName);
+	end
+	
+	if(enumEntry.deprecated == nil) then enumEntry.deprecated = currState.extDef.deprecated; end
+	if(enumEntry.removed == nil) then enumEntry.removed = currState.extDef.removed; end
+	
+	currState.enumMap[enumName] = enumEntry;
+	
+	return enumEntry;
+end
+
+--We process each line with this table. For the line, we match it with the given pattern.
+--If the pattern matches, then we call the associated function. If no patterns match, we skip it.
+--The first parameter to the functions is the current data for our enumerators.
+--The second parameter is the array of matches from the pattern test.
+local procTable =
+{
+	{["pattern"] = "passthru:%s+(.+)", ["func"] = function(currState, matchArray)
+end},
+
+--This pattern is hit when we reach a new extension.
+--This function sets it to be the current extension.
+	{["pattern"] = "(%S+)%s*enum:", ["func"] = function(currState, matchArray)
+		currState.extDef = {};
+		local bHasVersion = false;
+		
+		local baseExtName = string.match(matchArray[1], "(.*)_DEPRECATED$");
+		local testExtName = matchArray[1];
+		
+		if(baseExtName) then testExtName = baseExtName; end;
+
+		local versionNum = string.match(testExtName, "^VERSION_(.*)");
+		if(versionNum) then
+			currState.extDef.version = string.format("%s.%s", string.match(versionNum, "(.*)_(.*)"));
+			bHasVersion = true;
+		end
+		
+		if(baseExtName) then
+			currState.extDef.deprecated = "3.0";
+			currState.extDef.removed = "3.1";
+			if(not bHasVersion) then
+				currState.extDef.extName = baseExtName;
+			end
+		else
+			if(not bHasVersion) then
+				currState.extDef.extName = testExtName;
+			end
+		end
+	end},
+
+--This pattern is hit when we reach an enumeration definition by hexadecimal value.
+	{["pattern"] = "(%S+)%s*=%s*(0x%x+)", ["func"] = function(currState, matchArray)
+		local enumEntry = FetchEnum(currState, matchArray[1]);
+		
+		enumEntry.value = matchArray[2];
+		enumEntry.copy = false;
+	end},
+
+--This pattern is hit when we reach an enumeration definition by decimal value.
+	{["pattern"] = "(%S+)%s*=%s*(%d+)", ["func"] = function(currState, matchArray)
+		local enumEntry = FetchEnum(currState, matchArray[1]);
+		
+		enumEntry.value = matchArray[2];
+		enumEntry.copy = false;
+	end},
+
+--This pattern is hit when we reach an enumeration copy (copy the value from another enum).
+	{["pattern"] = "(%S+)%s*=%s*%S-_(%S+)", ["func"] = function(currState, matchArray)
+		local enumEntry = FetchEnum(currState, matchArray[1]);
+		
+		enumEntry.value = matchArray[2];
+		enumEntry.copy = true;
+	end},
+
+--This pattern is hit when we are saying that the given enum (param #2) is being used in
+--this context, so we should add the current context as extensions or core.
+--If the current context is an extension, then it's possible that
+--the thing using it is a core version.
+	{["pattern"] = "use (%S+)%s*(%S+)", ["func"] = function(currState, matchArray)
+		local enumEntry = FetchEnum(currState, matchArray[2]);
+end},
+};
+
+function ExtractEnums(hInFile, clipPrefix)
+	
+	local state = {};
+	state.enumArray = {};
+	state.enumMap = {};
+	state.FetchEnum = FetchEnum;
+	
+	if(clipPrefix) then
+		clipPattern = string.format("^%s_(.*)", clipPrefix);
+	else
+		clipPattern = nil;
+	end
+
+
+	for strCurrLine in hInFile:lines() do
+		local strOutLine = CullLine(strCurrLine);
+		if(strOutLine) then
+			for i, proc in ipairs(procTable) do
+				local test = {string.match(strOutLine, proc.pattern)};
+				if(#test ~= 0) then
+					proc.func(state, test);
+					break;
+				end;
+			end
+		end
+	end
+	
+	return state.enumArray;
+end
+
+
+

File _ExtractExts.lua

+--[[The funciton ExtractExts takes a file handle to an enumext.spec file. It returns an array of extension names.
+]]
+
+require "_line"
+
+local function IsExtension(heading)
+	if(string.match(heading, "^VERSION.*")) then return false; end;
+	
+	if(string.match(heading, "DEPRECATED$")) then return false; end;
+
+	return true;
+end
+
+function ExtractExts(hInFile, clipPrefix)
+	local ret = {};
+	local headingPattern = "^(%S+)%s*enum:";
+	
+	local clipPattern = nil;
+	if(clipPrefix) then
+		clipPattern = string.format("^%s_(.*)", clipPrefix);
+	end
+
+	for strCurrLine in hInFile:lines() do
+		local strOutLine = CullLine(strCurrLine);
+		if(strOutLine) then
+			local heading = string.match(strOutLine, headingPattern);
+			if(heading) then
+				if(IsExtension(heading)) then
+					if(clipPattern) then
+						local newHeading = string.match(heading, clipPattern);
+						if(newHeading) then heading = newHeading; end;
+					end
+					
+					table.insert(ret, heading);
+				end
+			end
+		end
+	end
+
+	return ret;
+end

File _ExtractFuncs.lua

+--[[The exported function, ExtractFuncs, takes an input file. It returns
+a table that contains these things:
+
+- properties: A table of property values. It is a map between property name and values. The value can either be "*" or an array of possible string values that the property can take.
+- passthru: A string that is the pass-through data that should be put infront of the function definition header.
+- functions: An array of functions. Each function is a table with:
+-- name:
+-- any of the properties defined in the properties table. This will have values culled from the list of possibles, except if the property was defined as "*", in which case it will be any string.
+-- params: An array of parameters, in the order that they are defined as. Each param is a table with:
+--- name: the name of the parameter.
+--- type: The basic type. Something in the type-map.
+--- input: True if it is an input variable, valse otherwise.
+--- array: True if it is a pointer; false otehrwise.
+--- other: A string containing the other data. Kept for backwards compatibility.
+]]
+
+require("_line");
+
+local function StoreParamOptions(param, paramData)
+	local testPattern = "(%S*)%s+(.*)";
+	
+	local glType, rest = string.match(paramData, testPattern);
+	
+	param.type = glType;
+	
+	local input;
+	input, rest = string.match(rest, testPattern);
+	
+	if(input == "in") then
+		param.input = true;
+	else
+		param.input = false;
+	end
+	
+	local oldRest = rest;
+	
+	local arrayKind;
+	arrayKind, rest = string.match(rest, testPattern);
+	
+	if(not arrayKind) then
+		param.kind = oldRest;
+	else
+		param.kind = arrayKind;
+	end
+	
+	if(rest and #rest ~= 0) then
+		param.other = rest;
+	end
+end
+
+
+local function CreateFunc(strFuncName, strParams)
+	local func = {};
+	func.name = strFuncName;
+	func.params = {};
+	func.AddParam = AddParamToFunc;
+
+
+	--Parse the parameters, in order, into paramList.
+	local currParamString = strParams;
+	while((currParamString ~= nil) and (#currParamString ~= 0)) do
+		local strCurrParam;
+		strCurrParam, currParamString = string.match(currParamString, "([%w_]+)(,?%s?.*)");
+
+		local paramData = {};
+		paramData.name = strCurrParam;
+		table.insert(func.params, paramData);
+	end
+	
+	return func;
+end
+
+--If the pattern matches, then the function will be called on that match data.
+local jumpTable = {
+	{pattern = "^required%-props:$", func = function(state, matchArray)
+		state.frontMatter = true;
+	end},
+
+	--Passthrough data.
+	{pattern = "passthru: (.*)", func = function(state, matchArray)
+		if(state.frontMatter) then
+			table.insert(state.funcData.passthru, matchArray[1]);
+		end
+	end},
+	
+	--Front matter
+	{pattern = "(%S*):%s*(.*)", func = function(state, matchArray)
+		if(state.frontMatter) then
+			local paramData = {};
+			state.funcData.properties[matchArray[1]] = paramData;
+			for term in string.gmatch(matchArray[2], "%S*") do
+				if(#term ~= 0) then
+					table.insert(paramData, term);
+				end
+			end
+		end
+	end},
+	
+	--Function definition
+	{pattern = "^([%w_]+)%((.*)%)", func = function(state, matchArray)
+		state.frontMatter = false;
+		state.currFunc = CreateFunc(matchArray[1], matchArray[2]);
+		table.insert(state.funcData.functions, state.currFunc);
+	end},
+
+	--Parameter Properties
+	{pattern = "^\tparam%s+(%S*)%s+(.*)", func = function(state, matchArray)
+		local bFound = false;
+		
+		for count = 1, #state.currFunc.params, 1 do
+			if(state.currFunc.params[count].name == matchArray[1]) then
+				StoreParamOptions(state.currFunc.params[count], matchArray[2]);
+				bFound = true;
+				break;
+			end
+		end
+		
+		if(not bFound) then
+			print(string.format("The func \"%s\" does not have parameter \"%s\".",
+				state.currFunc.name, matchArray[1]));
+			return true;
+		end;
+	end},
+	
+	--Non-param Properties
+	{pattern = "^\t(%S*)%s+(%S*)", func = function(state, matchArray)
+		state.currFunc[matchArray[1]] = matchArray[2];
+	end},
+}
+
+function ExtractFuncs(hFile)
+	local funcData = {};
+	funcData.properties = {};
+	funcData.passthru = {};
+	funcData.functions = {};
+	
+	local state = {};
+	state.funcData = funcData;
+	
+	for currLine in hFile:lines() do
+		local outLine = CullLine(currLine);
+		
+		if(outLine) then
+			for i, proc in ipairs(jumpTable) do
+				local parseArray = {string.match(outLine, proc.pattern);}
+				if(parseArray[1]) then
+					local bRet = proc.func(state, parseArray);
+					if(bRet) then
+						print("Bad line: " .. outLine);
+					end
+				end
+			end
+		end
+	end
+	
+	return state.funcData;
+end
+

File _ExtractSpecsToFile.lua

+--[[This file exposes a function that will write a Lua-based spec file. It takes a destination
+file and table of 3 files:
+
+-glspec: the gl.spec file.
+-enumext: the enumext.spec file.
+-gltm: the gl.tm file.
+
+The destination file is a lua file that, when "dofile" is run on it, returns the table. The table
+is formatted as follows:
+
+- extensions: A table formatted as in ExtractExts.
+- enumerations: A table formatted as in ExtractEnums.
+- typemap: A table formatted as in ExtractTypes.
+- funcData: A table formatted as in ExtractFuncs.
+]]
+
+require "_ExtractExts"
+require "_ExtractEnums"
+require "_ExtractTypes"
+require "_ExtractFuncs"
+require "_TableWriter"
+require "_util"
+
+
+function ExtractSpecsToFile(outFilename, inputFiles, clipPrefix)
+	local extractedData = {};
+	
+	local hFile = io.open(GetSpecFilePath() .. inputFiles.enumext, "r");
+	if(not hFile) then
+		print(string.format("Could not open enumext file: '%s'", inputFiles.enumext));
+		return;
+	end
+	extractedData.extensions = ExtractExts(hFile, clipPrefix);
+	hFile:close();
+
+	hFile = io.open(GetSpecFilePath() .. inputFiles.enumext, "r");
+	if(not hFile) then
+		print(string.format("Could not open enumext file: '%s'", inputFiles.enumext));
+		return;
+	end
+	extractedData.enumerations = ExtractEnums(hFile, clipPrefix);
+	hFile:close();
+
+	hFile = io.open(GetSpecFilePath() .. inputFiles.gltm, "r");
+	if(not hFile) then
+		print(string.format("Could not open gltm file: '%s'", inputFiles.gltm));
+		return;
+	end
+	extractedData.typemap = ExtractTypes(hFile);
+	hFile:close();
+
+	hFile = io.open(GetSpecFilePath() .. inputFiles.glspec, "r");
+	if(not hFile) then
+		print(string.format("Could not open glspec file: '%s'", inputFiles.glspec));
+		return;
+	end
+	extractedData.funcData = ExtractFuncs(hFile);
+	hFile:close();
+	
+	hFile = io.open(GetSpecFilePath() .. outFilename, "w");
+	if(not hFile) then
+		print(string.format("Could not open the output file: '%s'", outFilename));
+		return;
+	end
+	hFile:write("return ");
+	WriteTable(hFile, extractedData);
+	hFile:write(";\n");
+	hFile:close();
+end
+
+

File _ExtractTypes.lua

+--[[ This function takes a handle to a .tm file, and returns a table. The keys for the table are
+the GL-generic types, and the values are the actual C++ types for them.
+]]
+
+require("_line");
+
+function ExtractTypes(hInFile)
+	local typemapPattern = "^(%S-),.-,.-,%s-(%S.-),";
+	
+	local typeMap = {};
+
+	for strCurrLine in hInFile:lines() do
+		local strOutLine = CullLine(strCurrLine);
+		
+		if(strOutLine) then
+			local glType, realType = string.match(strOutLine, typemapPattern);
+			if(glType and realType) then
+				if(typeMap[glType]) then
+					print("typemap duplicate: " .. strOutLine);
+				else
+					typeMap[glType] = realType;
+				end
+			else
+				print("bad typemap line: " .. strOutLine);
+			end
+		end
+	end
+	
+	return typeMap;
+end

File _TableWriter.lua

+--This file exports a funciton, WriteTable, that writes a given table out to a given file handle.
+
+require "_util";
+
+local writeKey = {};
+
+function writeKey.string(hFile, value, iRecursion)
+	WriteFormatted(hFile, "[\"%s\"]", value);
+end
+
+function writeKey.number(hFile, value, iRecursion)
+	WriteFormatted(hFile, "[%i]", value);
+end
+
+local writeValue = {};
+
+function writeValue.string(hFile, value, iRecursion)
+	WriteFormatted(hFile, "[==[%s]==]", value);
+end
+
+function writeValue.number(hFile, value, iRecursion)
+	WriteFormatted(hFile, "%i", value);
+end
+
+function writeValue.boolean(hFile, value, iRecursion)
+	if(value) then hFile:write("true"); else hFile:write("false"); end;
+end
+
+function writeValue.table(hFile, value, iRecursion)
+	WriteTable(hFile, value, iRecursion)
+end
+
+local function WriteTabs(hFile, iRecursion)
+	for iCount = 1, iRecursion, 1 do
+		hFile:write("\t");
+	end
+end
+
+function WriteTable(hFile, outTable, iRecursion)
+	if(iRecursion == nil) then iRecursion = 1; end
+	
+	hFile:write("{\n");
+	
+	local bHasArray = false;
+	local arraySize = 0;
+	
+	if(#outTable > 0) then bHasArray = true; arraySize = #outTable; end;
+	
+	for key, value in pairs(outTable) do
+		if(writeKey[type(key)] == nil) then print("Malformed table key."); return; end
+		if(writeValue[type(value)] == nil) then
+			print( string.format("Bad value in table: key: '%s' value type '%s'.", key, type(value)));
+			return;
+		end
+		
+		--If the key is not an array index, process it.
+		if((not bHasArray) or
+				(type(key) ~= "number") or
+				not((1 <= key) and (key <= arraySize))) then
+			WriteTabs(hFile, iRecursion);
+			writeKey[type(key)](hFile, key, iRecursion + 1);
+			hFile:write(" = ");
+			writeValue[type(value)](hFile, value, iRecursion + 1);
+			
+			hFile:write(",\n");
+		end
+	end
+	
+	if(bHasArray) then
+		for i, value in ipairs(outTable) do
+			WriteTabs(hFile, iRecursion);
+			writeValue[type(value)](hFile, value, iRecursion + 1);
+			hFile:write(",\n");
+		end
+	end
+
+	WriteTabs(hFile, iRecursion - 1);
+	hFile:write("}");
+end
+
+-- This function will take the given line string and remove the comments from it.
+-- It may return an empty line.
+function CullLine(strLine)
+	if(string.find(strLine, "passthru:%s.+")) then
+		return strLine;
+	end
+
+	local iVal = string.find(strLine, "#", 1, true);
+	
+	if(iVal == nil) then
+		return strLine;
+	end
+	
+	local strCulled = string.sub(strLine, 1, iVal - 1);
+	if(#strCulled == 0) then
+		return nil;
+	end
+	
+	return strCulled;
+end
+
+--Works like the regular pairs, but returns the key/value pairs in a key-sorted order.
+--sortFunc is the function used to compare them.
+function sortPairs(theTable, sortFunc)
+	local keyTable = {};
+	
+	for key, value in pairs(theTable) do
+		table.insert(keyTable, key);
+	end
+	
+	table.sort(keyTable, sortFunc);
+	
+	local currIndex = 1;
+	local lenTable = #keyTable;
+	
+	return function()
+		local currKey = keyTable[currIndex];
+		currIndex = currIndex + 1;
+		return currKey, theTable[currKey];
+	end
+end
+
+--Works like ipairs, but returns the list as through it were in a sorted order.
+--It even returns the "wrong" indices.
+--sortFunc is the function used to compare them.
+function isortPairs(theTable, sortFunc)
+	local tempTable = {};
+	
+	for i, value in ipairs(theTable) do
+		table.insert(tempTable, value);
+	end
+	
+	table.sort(tempTable, sortFunc);
+	
+	local currIndex = 1;
+	local lenTable = #tempTable;
+	
+	return function()
+		local tempIndex = currIndex;
+		currIndex = currIndex + 1;
+		return tempIndex, theTable[tempIndex];
+	end
+end
+
+--ipairs in reverse order.
+function ripairs(theTable)
+	local currIndex = #theTable;
+
+	return function()
+		local tempIndex = currIndex;
+		currIndex = currIndex - 1;
+		if(currIndex < 0) then return nil, nil; end;
+		return tempIndex, theTable[tempIndex];
+	end
+end
+
+--Standard lessthan compare function. For use with the above.
+function CompLess(key1, key2)
+	return key1 < key2;
+end
+
+--A combined printf and hFile:write.
+function WriteFormatted(hFile, strFormat, ...)
+	hFile:write(string.format(strFormat, ...));
+end
+
+function WriteForm(hFile, strFormat, ...)
+	hFile:write(string.format(strFormat, ...));
+end
+
+function GetIncludePath()
+	return "..\\include\\glloader\\";
+end
+
+function GetSourcePath()
+	return "..\\source\\";
+end
+
+function GetSpecFilePath()
+	return "glspecs\\";
+end
+
+function GetDataFilePath()
+	return "data\\";
+end
+
+--This returns the starting part of a header's includeguard. Takes the name of the define.
+function GetFileIncludeGuardStart(defineName)
+	return string.format([[
+#ifndef %s
+#define %s
+
+]], defineName, defineName);
+end
+
+--This returns the ending part of a header's includeguard. Takes the name of the define.
+function GetFileIncludeGuardEnd(defineName)
+	return string.format([[
+#endif //%s
+
+]], defineName);
+end
+
+--Retrieves the beginning of the extern C block
+function GetExternCStart()
+	return [[
+#ifdef __cplusplus
+extern "C" {
+#endif //__cplusplus
+
+]]
+end
+
+--Retrieves the end of the extern C block.
+function GetExternCEnd()
+	return [[
+#ifdef __cplusplus
+}
+#endif //__cplusplus
+
+]]
+end
+
+--Retrieves a string for a C-style heading. Takes the name of the heading.
+function GetSectionHeading(headingName)
+	return string.format(
+[[/******************************
+* %s
+******************************/
+]], headingName);
+end
+

File glspecs/enum.spec

+# This is the OpenGL and OpenGL ES enumerant registry.
+#
+# It is an extremely important file. Do not mess with it unless
+# you know what you're doing and have permission to do so.
+#
+# $Revision: 12070 $ on $Date: 2010-07-22 17:00:28 -0700 (Thu, 22 Jul 2010) $
+
+###############################################################################
+#
+# Before modifying this file, read the following:
+#
+#   ONLY the Khronos API Registrar (Jon Leech, jon 'at' alumni.caltech.edu)
+#   may allocate new enumerants outside the 'experimental' range described
+#   below. Any modifications to this file not performed by the Registrar
+#   are incompatible with the OpenGL API. The master copy of the registry,
+#   showing up-to-date enumerant allocations, is maintained in the
+#   OpenGL registry at
+#
+#	http://www.opengl.org/registry/
+#
+#   The following guidelines are thus only for reference purposes
+#   (unless you're the Registrar)
+#
+#   Enumerant values for extensions CANNOT be chosen arbitrarily, since
+#   the enumerant value space is shared by all GL implementations. It is
+#   therefore imperative that the procedures described in this file be
+#   followed carefully when allocating extension enum values.
+#
+# - Use tabs, not spaces.
+#
+# - When adding enum values for a new extension, use existing extensions
+#   as a guide.
+#
+# - When a vendor has committed to releasing a new extension and needs to
+#   allocate enum values for that extension, the vendor may request that the
+#   ARB allocate a previously unallocated block of 16 enum values, in the
+#   range 0x8000-0xFFFF, for the vendor's exclusive use.
+#
+# - The vendor that introduces an extension will allocate enum values for
+#   it as if it is a single-vendor extension, even if it is a multi-vendor
+#   (EXT) extension.
+#
+# - The file enum.spec is primarily a reference. The file enumext.spec
+#   contains enumerants for all OpenGL 1.2 and OpenGL extensions in a form
+#   used to generate <GL/glext.h>.
+#
+# - If a vendor hasn't yet released an extension, just add a comment to
+#   enum.spec that contains the name of the extension and the range of enum
+#   values used by the extension. When the vendor releases the extension,
+#   put the actual enum assignments in enum.spec and enumext.spec.
+#
+# - Allocate all of the enum values for an extension in a single contiguous
+#   block.
+#
+# - If an extension is experimental, allocate temporary enum values in the
+#   range 0x6000-0x8000 during development work.  When the vendor commits to
+#   releasing the extension, allocate permanent enum values (see below).
+#   There are two reasons for this policy:
+#
+#   1.	It is desirable to keep extension enum values tightly packed and to
+#	make all of the enum values for an extension be contiguous.  This is
+#	possible only if permanent enum values for a new extension are not
+#	allocated until the extension spec is stable and the number of new
+#	enum values needed by the extension has therefore stopped changing.
+#
+#   2.	OpenGL ARB policy is that a vendor may allocate a new block of 16
+#	extension enum values only if it has committed to releasing an
+#	extension that will use values in that block.
+#
+# - To allocate a new block of permanent enum values for an extension, do the
+#   following:
+#
+#   1.	Start at the top of enum.spec and choose the first future_use
+#	range that is not allocated to another vendor and is large enough
+#	to contain the new block. This will almost certainly be the
+#	'Any_vendor_future_use' range near the end of enum.spec. This
+#	process helps keep allocated enum values tightly packed into
+#	the start of the 0x8000-0xFFFF range.
+#
+#   2.	Allocate a block of enum values at the start of this range.  If
+#	the enum definitions are going into enumfuture.spec, add a comment
+#	to enum.spec that contains the name of the extension and the range
+#	of values in the new block. Use existing extensions as a guide.
+#
+#   3.	Add the size of the block you just allocated to the start of the
+#	chosen future_use range.  If you have allocated the entire range,
+#	eliminate its future_use entry.
+#
+#   4.	Note that there are historical enum allocations above 0xFFFF, but
+#	no new allocations will be made there in the forseeable future.
+#
+###############################################################################
+
+Extensions define:
+	VERSION_1_1					= 1
+	VERSION_1_2					= 1
+	VERSION_1_3					= 1
+	VERSION_1_4					= 1
+	VERSION_1_5					= 1
+	VERSION_2_0					= 1
+	VERSION_2_1					= 1
+	VERSION_3_0					= 1
+	VERSION_3_1					= 1
+	VERSION_3_2					= 1
+	ARB_imaging					= 1
+	EXT_abgr					= 1
+	EXT_blend_color					= 1
+	EXT_blend_logic_op				= 1
+	EXT_blend_minmax				= 1
+	EXT_blend_subtract				= 1
+	EXT_cmyka					= 1
+	EXT_convolution					= 1
+	EXT_copy_texture				= 1
+	EXT_histogram					= 1
+	EXT_packed_pixels				= 1
+	EXT_point_parameters				= 1
+	EXT_polygon_offset				= 1
+	EXT_rescale_normal				= 1
+	EXT_shared_texture_palette			= 1
+	EXT_subtexture					= 1
+	EXT_texture					= 1
+	EXT_texture3D					= 1
+	EXT_texture_object				= 1
+	EXT_vertex_array				= 1
+	SGIS_detail_texture				= 1
+	SGIS_fog_function				= 1
+	SGIS_generate_mipmap				= 1
+	SGIS_multisample				= 1
+	SGIS_pixel_texture				= 1
+	SGIS_point_line_texgen				= 1
+	SGIS_point_parameters				= 1
+	SGIS_sharpen_texture				= 1
+	SGIS_texture4D					= 1
+	SGIS_texture_border_clamp			= 1
+	SGIS_texture_edge_clamp				= 1
+	SGIS_texture_filter4				= 1
+	SGIS_texture_lod				= 1
+	SGIS_texture_select				= 1
+	SGIX_async					= 1
+	SGIX_async_histogram				= 1
+	SGIX_async_pixel				= 1
+	SGIX_blend_alpha_minmax				= 1
+	SGIX_calligraphic_fragment			= 1
+	SGIX_clipmap					= 1
+	SGIX_convolution_accuracy			= 1
+	SGIX_depth_texture				= 1
+	SGIX_flush_raster				= 1
+	SGIX_fog_offset					= 1
+	SGIX_fragment_lighting				= 1
+	SGIX_framezoom					= 1
+	SGIX_icc_texture				= 1
+	SGIX_impact_pixel_texture			= 1
+	SGIX_instruments				= 1
+	SGIX_interlace					= 1
+	SGIX_ir_instrument1				= 1
+	SGIX_list_priority				= 1
+	SGIX_pixel_texture				= 1
+	SGIX_pixel_tiles				= 1
+	SGIX_polynomial_ffd				= 1
+	SGIX_reference_plane				= 1
+	SGIX_resample					= 1
+	SGIX_scalebias_hint				= 1
+	SGIX_shadow					= 1
+	SGIX_shadow_ambient				= 1
+	SGIX_sprite					= 1
+	SGIX_subsample					= 1
+	SGIX_tag_sample_buffer				= 1
+	SGIX_texture_add_env				= 1
+	SGIX_texture_coordinate_clamp			= 1
+	SGIX_texture_lod_bias				= 1
+	SGIX_texture_multi_buffer			= 1
+	SGIX_texture_scale_bias				= 1
+	SGIX_vertex_preclip				= 1
+	SGIX_ycrcb					= 1
+	SGI_color_matrix				= 1
+	SGI_color_table					= 1
+	SGI_texture_color_table				= 1
+
+###############################################################################
+
+AttribMask enum:
+	CURRENT_BIT					= 0x00000001
+	POINT_BIT					= 0x00000002
+	LINE_BIT					= 0x00000004
+	POLYGON_BIT					= 0x00000008
+	POLYGON_STIPPLE_BIT				= 0x00000010
+	PIXEL_MODE_BIT					= 0x00000020
+	LIGHTING_BIT					= 0x00000040
+	FOG_BIT						= 0x00000080
+	DEPTH_BUFFER_BIT				= 0x00000100
+	ACCUM_BUFFER_BIT				= 0x00000200
+	STENCIL_BUFFER_BIT				= 0x00000400
+	VIEWPORT_BIT					= 0x00000800
+	TRANSFORM_BIT					= 0x00001000
+	ENABLE_BIT					= 0x00002000
+	COLOR_BUFFER_BIT				= 0x00004000
+	HINT_BIT					= 0x00008000
+	EVAL_BIT					= 0x00010000
+	LIST_BIT					= 0x00020000
+	TEXTURE_BIT					= 0x00040000
+	SCISSOR_BIT					= 0x00080000
+	ALL_ATTRIB_BITS					= 0xFFFFFFFF
+#??? ALL_ATTRIB_BITS mask value changed to all-1s in OpenGL 1.3 - this affects covgl.
+#	use ARB_multisample MULTISAMPLE_BIT_ARB
+#	use EXT_multisample MULTISAMPLE_BIT_EXT
+#	use 3DFX_multisample MULTISAMPLE_BIT_3DFX
+
+VERSION_1_3 enum: (Promoted for OpenGL 1.3)
+	MULTISAMPLE_BIT					= 0x20000000
+
+ARB_multisample enum:
+	MULTISAMPLE_BIT_ARB				= 0x20000000
+
+EXT_multisample enum:
+	MULTISAMPLE_BIT_EXT				= 0x20000000
+
+3DFX_multisample enum:
+	MULTISAMPLE_BIT_3DFX				= 0x20000000
+
+###############################################################################
+
+# Note that COVERAGE_BUFFER_BIT_NV collides with AttribMask bit
+# HINT_BIT. This is OK since the extension is for OpenGL ES 2, which
+# doesn't have attribute groups.
+ClearBufferMask enum:
+	use AttribMask DEPTH_BUFFER_BIT			# = 0x00000100
+	use AttribMask ACCUM_BUFFER_BIT			# = 0x00000200
+	use AttribMask STENCIL_BUFFER_BIT		# = 0x00000400
+	use AttribMask COLOR_BUFFER_BIT			# = 0x00004000
+	use NV_coverage_sample COVERAGE_BUFFER_BIT_NV	# = 0x00008000
+
+###############################################################################
+
+ClientAttribMask enum:
+	CLIENT_PIXEL_STORE_BIT				= 0x00000001
+	CLIENT_VERTEX_ARRAY_BIT				= 0x00000002
+	CLIENT_ALL_ATTRIB_BITS				= 0xFFFFFFFF
+
+###############################################################################
+
+# There's no obvious better place to put non-attribute-group mask bits
+VERSION_3_0 enum:
+	use ARB_map_buffer_range	    MAP_READ_BIT
+	use ARB_map_buffer_range	    MAP_WRITE_BIT
+	use ARB_map_buffer_range	    MAP_INVALIDATE_RANGE_BIT
+	use ARB_map_buffer_range	    MAP_INVALIDATE_BUFFER_BIT
+	use ARB_map_buffer_range	    MAP_FLUSH_EXPLICIT_BIT
+	use ARB_map_buffer_range	    MAP_UNSYNCHRONIZED_BIT
+
+ARB_map_buffer_range enum:
+	MAP_READ_BIT					= 0x0001    # VERSION_3_0 / ARB_mbr
+	MAP_WRITE_BIT					= 0x0002    # VERSION_3_0 / ARB_mbr
+	MAP_INVALIDATE_RANGE_BIT			= 0x0004    # VERSION_3_0 / ARB_mbr
+	MAP_INVALIDATE_BUFFER_BIT			= 0x0008    # VERSION_3_0 / ARB_mbr
+	MAP_FLUSH_EXPLICIT_BIT				= 0x0010    # VERSION_3_0 / ARB_mbr
+	MAP_UNSYNCHRONIZED_BIT				= 0x0020    # VERSION_3_0 / ARB_mbr
+
+###############################################################################
+
+# CONTEXT_FLAGS_ARB bits (should be shared with WGL and GLX)
+
+VERSION_3_0 enum:
+	CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT		= 0x00000001 # VERSION_3_0
+
+# 0x00000001 used in WGL/GLX for CONTEXT_DEBUG_BIT_ARB, while
+# 0x00000002 used in WGL/GLX for CONTEXT_FORWARD_COMPATIBLE_BIT_ARB. Oops.
+# We do not currently expose CONTEXT_FLAG_DEBUG_BIT in GL, at least.
+
+ARB_robustness enum:
+	CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB		= 0x00000004 # ARB_robustness
+
+###############################################################################
+
+# UseProgramStages stage bits
+
+ARB_separate_shader_objects enum:
+	VERTEX_SHADER_BIT				= 0x00000001
+	FRAGMENT_SHADER_BIT				= 0x00000002
+	GEOMETRY_SHADER_BIT				= 0x00000004
+	TESS_CONTROL_SHADER_BIT				= 0x00000008
+	TESS_EVALUATION_SHADER_BIT			= 0x00000010
+	ALL_SHADER_BITS					= 0xFFFFFFFF
+
+###############################################################################
+
+Boolean enum:
+	FALSE						= 0
+	TRUE						= 1
+
+###############################################################################
+
+BeginMode enum:
+	POINTS						= 0x0000
+	LINES						= 0x0001
+	LINE_LOOP					= 0x0002
+	LINE_STRIP					= 0x0003
+	TRIANGLES					= 0x0004
+	TRIANGLE_STRIP					= 0x0005
+	TRIANGLE_FAN					= 0x0006
+	QUADS						= 0x0007
+	QUAD_STRIP					= 0x0008
+	POLYGON						= 0x0009
+
+VERSION_3_2 enum:
+	LINES_ADJACENCY					= 0x000A
+	LINE_STRIP_ADJACENCY				= 0x000B
+	TRIANGLES_ADJACENCY				= 0x000C
+	TRIANGLE_STRIP_ADJACENCY			= 0x000D
+
+ARB_geometry_shader4 enum: (additional; see below)
+	LINES_ADJACENCY_ARB				= 0x000A
+	LINE_STRIP_ADJACENCY_ARB			= 0x000B
+	TRIANGLES_ADJACENCY_ARB				= 0x000C
+	TRIANGLE_STRIP_ADJACENCY_ARB			= 0x000D
+
+NV_geometry_program4 enum: (additional; see below)
+	LINES_ADJACENCY_EXT				= 0x000A
+	LINE_STRIP_ADJACENCY_EXT			= 0x000B
+	TRIANGLES_ADJACENCY_EXT				= 0x000C
+	TRIANGLE_STRIP_ADJACENCY_EXT			= 0x000D
+
+ARB_tessellation_shader enum:
+	PATCHES						= 0x000E
+
+NV_gpu_shader5 enum:
+	use ARB_tessellation_shader	    PATCHES
+
+# BeginMode_future_use: 0x000E
+
+###############################################################################
+
+AccumOp enum:
+	ACCUM						= 0x0100
+	LOAD						= 0x0101
+	RETURN						= 0x0102
+	MULT						= 0x0103
+	ADD						= 0x0104
+
+###############################################################################
+
+AlphaFunction enum:
+	NEVER						= 0x0200
+	LESS						= 0x0201
+	EQUAL						= 0x0202
+	LEQUAL						= 0x0203
+	GREATER						= 0x0204
+	NOTEQUAL					= 0x0205
+	GEQUAL						= 0x0206
+	ALWAYS						= 0x0207
+
+###############################################################################
+
+BlendingFactorDest enum:
+	ZERO						= 0
+	ONE						= 1
+	SRC_COLOR					= 0x0300
+	ONE_MINUS_SRC_COLOR				= 0x0301
+	SRC_ALPHA					= 0x0302
+	ONE_MINUS_SRC_ALPHA				= 0x0303
+	DST_ALPHA					= 0x0304
+	ONE_MINUS_DST_ALPHA				= 0x0305
+	use EXT_blend_color CONSTANT_COLOR_EXT
+	use EXT_blend_color ONE_MINUS_CONSTANT_COLOR_EXT
+	use EXT_blend_color CONSTANT_ALPHA_EXT
+	use EXT_blend_color ONE_MINUS_CONSTANT_ALPHA_EXT
+
+###############################################################################
+
+BlendingFactorSrc enum:
+	use BlendingFactorDest ZERO
+	use BlendingFactorDest ONE
+	DST_COLOR					= 0x0306
+	ONE_MINUS_DST_COLOR				= 0x0307
+	SRC_ALPHA_SATURATE				= 0x0308
+	use BlendingFactorDest SRC_ALPHA
+	use BlendingFactorDest ONE_MINUS_SRC_ALPHA
+	use BlendingFactorDest DST_ALPHA
+	use BlendingFactorDest ONE_MINUS_DST_ALPHA
+	use EXT_blend_color CONSTANT_COLOR_EXT
+	use EXT_blend_color ONE_MINUS_CONSTANT_COLOR_EXT
+	use EXT_blend_color CONSTANT_ALPHA_EXT
+	use EXT_blend_color ONE_MINUS_CONSTANT_ALPHA_EXT
+
+###############################################################################
+
+BlendEquationModeEXT enum:
+	use GetPName LOGIC_OP
+	use EXT_blend_minmax FUNC_ADD_EXT
+	use EXT_blend_minmax MIN_EXT
+	use EXT_blend_minmax MAX_EXT
+	use EXT_blend_subtract FUNC_SUBTRACT_EXT
+	use EXT_blend_subtract FUNC_REVERSE_SUBTRACT_EXT
+	use SGIX_blend_alpha_minmax ALPHA_MIN_SGIX
+	use SGIX_blend_alpha_minmax ALPHA_MAX_SGIX
+
+###############################################################################
+
+ColorMaterialFace enum:
+	use DrawBufferMode FRONT
+	use DrawBufferMode BACK
+	use DrawBufferMode FRONT_AND_BACK
+
+###############################################################################
+
+ColorMaterialParameter enum:
+	use LightParameter AMBIENT
+	use LightParameter DIFFUSE
+	use LightParameter SPECULAR
+	use MaterialParameter EMISSION
+	use MaterialParameter AMBIENT_AND_DIFFUSE
+
+###############################################################################
+
+ColorPointerType enum:
+	use DataType BYTE
+	use DataType UNSIGNED_BYTE
+	use DataType SHORT
+	use DataType UNSIGNED_SHORT
+	use DataType INT
+	use DataType UNSIGNED_INT
+	use DataType FLOAT
+	use DataType DOUBLE
+
+###############################################################################
+
+ColorTableParameterPNameSGI enum:
+	use SGI_color_table COLOR_TABLE_SCALE_SGI
+	use SGI_color_table COLOR_TABLE_BIAS_SGI
+
+###############################################################################
+
+ColorTableTargetSGI enum:
+	use SGI_color_table COLOR_TABLE_SGI
+	use SGI_color_table POST_CONVOLUTION_COLOR_TABLE_SGI
+	use SGI_color_table POST_COLOR_MATRIX_COLOR_TABLE_SGI
+	use SGI_color_table PROXY_COLOR_TABLE_SGI
+	use SGI_color_table PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI
+	use SGI_color_table PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI
+	use SGI_texture_color_table TEXTURE_COLOR_TABLE_SGI
+	use SGI_texture_color_table PROXY_TEXTURE_COLOR_TABLE_SGI
+
+###############################################################################
+
+ConvolutionBorderModeEXT enum:
+	use EXT_convolution REDUCE_EXT
+
+###############################################################################
+
+ConvolutionParameterEXT enum:
+	use EXT_convolution CONVOLUTION_BORDER_MODE_EXT
+	use EXT_convolution CONVOLUTION_FILTER_SCALE_EXT
+	use EXT_convolution CONVOLUTION_FILTER_BIAS_EXT
+
+###############################################################################
+
+ConvolutionTargetEXT enum:
+	use EXT_convolution CONVOLUTION_1D_EXT
+	use EXT_convolution CONVOLUTION_2D_EXT
+
+###############################################################################
+
+CullFaceMode enum:
+	use DrawBufferMode FRONT
+	use DrawBufferMode BACK
+	use DrawBufferMode FRONT_AND_BACK
+
+###############################################################################
+
+DepthFunction enum:
+	use AlphaFunction NEVER
+	use AlphaFunction LESS
+	use AlphaFunction EQUAL
+	use AlphaFunction LEQUAL
+	use AlphaFunction GREATER
+	use AlphaFunction NOTEQUAL
+	use AlphaFunction GEQUAL
+	use AlphaFunction ALWAYS
+
+###############################################################################
+
+DrawBufferMode enum:
+	NONE						= 0
+	FRONT_LEFT					= 0x0400
+	FRONT_RIGHT					= 0x0401
+	BACK_LEFT					= 0x0402
+	BACK_RIGHT					= 0x0403
+	FRONT						= 0x0404
+	BACK						= 0x0405
+	LEFT						= 0x0406
+	RIGHT						= 0x0407
+	FRONT_AND_BACK					= 0x0408
+	AUX0						= 0x0409
+	AUX1						= 0x040A
+	AUX2						= 0x040B
+	AUX3						= 0x040C
+
+# Aliases DrawBufferMode enum above
+OES_framebuffer_object enum: (OpenGL ES only; additional; see below)
+#	NONE_OES					= 0
+
+###############################################################################
+
+EnableCap enum:
+	use GetPName FOG
+	use GetPName LIGHTING
+	use GetPName TEXTURE_1D
+	use GetPName TEXTURE_2D
+	use GetPName LINE_STIPPLE
+	use GetPName POLYGON_STIPPLE
+	use GetPName CULL_FACE
+	use GetPName ALPHA_TEST
+	use GetPName BLEND
+	use GetPName INDEX_LOGIC_OP
+	use GetPName COLOR_LOGIC_OP
+	use GetPName DITHER
+	use GetPName STENCIL_TEST
+	use GetPName DEPTH_TEST
+	use GetPName CLIP_PLANE0
+	use GetPName CLIP_PLANE1
+	use GetPName CLIP_PLANE2
+	use GetPName CLIP_PLANE3
+	use GetPName CLIP_PLANE4
+	use GetPName CLIP_PLANE5
+	use GetPName LIGHT0
+	use GetPName LIGHT1
+	use GetPName LIGHT2
+	use GetPName LIGHT3
+	use GetPName LIGHT4
+	use GetPName LIGHT5
+	use GetPName LIGHT6
+	use GetPName LIGHT7
+	use GetPName TEXTURE_GEN_S
+	use GetPName TEXTURE_GEN_T
+	use GetPName TEXTURE_GEN_R
+	use GetPName TEXTURE_GEN_Q
+	use GetPName MAP1_VERTEX_3
+	use GetPName MAP1_VERTEX_4
+	use GetPName MAP1_COLOR_4
+	use GetPName MAP1_INDEX
+	use GetPName MAP1_NORMAL
+	use GetPName MAP1_TEXTURE_COORD_1
+	use GetPName MAP1_TEXTURE_COORD_2
+	use GetPName MAP1_TEXTURE_COORD_3
+	use GetPName MAP1_TEXTURE_COORD_4
+	use GetPName MAP2_VERTEX_3
+	use GetPName MAP2_VERTEX_4
+	use GetPName MAP2_COLOR_4
+	use GetPName MAP2_INDEX
+	use GetPName MAP2_NORMAL
+	use GetPName MAP2_TEXTURE_COORD_1
+	use GetPName MAP2_TEXTURE_COORD_2
+	use GetPName MAP2_TEXTURE_COORD_3
+	use GetPName MAP2_TEXTURE_COORD_4
+	use GetPName POINT_SMOOTH
+	use GetPName LINE_SMOOTH
+	use GetPName POLYGON_SMOOTH
+	use GetPName SCISSOR_TEST
+	use GetPName COLOR_MATERIAL
+	use GetPName NORMALIZE
+	use GetPName AUTO_NORMAL
+	use GetPName POLYGON_OFFSET_POINT
+	use GetPName POLYGON_OFFSET_LINE
+	use GetPName POLYGON_OFFSET_FILL
+	use GetPName VERTEX_ARRAY
+	use GetPName NORMAL_ARRAY
+	use GetPName COLOR_ARRAY
+	use GetPName INDEX_ARRAY
+	use GetPName TEXTURE_COORD_ARRAY
+	use GetPName EDGE_FLAG_ARRAY
+	use EXT_convolution CONVOLUTION_1D_EXT
+	use EXT_convolution CONVOLUTION_2D_EXT
+	use EXT_convolution SEPARABLE_2D_EXT
+	use EXT_histogram HISTOGRAM_EXT
+	use EXT_histogram MINMAX_EXT
+	use EXT_rescale_normal RESCALE_NORMAL_EXT
+	use EXT_shared_texture_palette SHARED_TEXTURE_PALETTE_EXT
+	use EXT_texture3D TEXTURE_3D_EXT
+	use SGIS_multisample MULTISAMPLE_SGIS
+	use SGIS_multisample SAMPLE_ALPHA_TO_MASK_SGIS
+	use SGIS_multisample SAMPLE_ALPHA_TO_ONE_SGIS
+	use SGIS_multisample SAMPLE_MASK_SGIS
+	use SGIS_texture4D TEXTURE_4D_SGIS
+	use SGIX_async_histogram ASYNC_HISTOGRAM_SGIX
+	use SGIX_async_pixel ASYNC_TEX_IMAGE_SGIX
+	use SGIX_async_pixel ASYNC_DRAW_PIXELS_SGIX
+	use SGIX_async_pixel ASYNC_READ_PIXELS_SGIX
+	use SGIX_calligraphic_fragment CALLIGRAPHIC_FRAGMENT_SGIX
+	use SGIX_fog_offset FOG_OFFSET_SGIX
+	use SGIX_fragment_lighting FRAGMENT_LIGHTING_SGIX
+	use SGIX_fragment_lighting FRAGMENT_COLOR_MATERIAL_SGIX
+	use SGIX_fragment_lighting FRAGMENT_LIGHT0_SGIX
+	use SGIX_fragment_lighting FRAGMENT_LIGHT1_SGIX
+	use SGIX_fragment_lighting FRAGMENT_LIGHT2_SGIX
+	use SGIX_fragment_lighting FRAGMENT_LIGHT3_SGIX
+	use SGIX_fragment_lighting FRAGMENT_LIGHT4_SGIX
+	use SGIX_fragment_lighting FRAGMENT_LIGHT5_SGIX
+	use SGIX_fragment_lighting FRAGMENT_LIGHT6_SGIX
+	use SGIX_fragment_lighting FRAGMENT_LIGHT7_SGIX
+	use SGIX_framezoom FRAMEZOOM_SGIX
+	use SGIX_interlace INTERLACE_SGIX
+	use SGIX_ir_instrument1 IR_INSTRUMENT1_SGIX
+	use SGIX_pixel_texture PIXEL_TEX_GEN_SGIX
+	use SGIS_pixel_texture PIXEL_TEXTURE_SGIS
+	use SGIX_reference_plane REFERENCE_PLANE_SGIX
+	use SGIX_sprite SPRITE_SGIX
+	use SGI_color_table COLOR_TABLE_SGI
+	use SGI_color_table POST_CONVOLUTION_COLOR_TABLE_SGI
+	use SGI_color_table POST_COLOR_MATRIX_COLOR_TABLE_SGI
+	use SGI_texture_color_table TEXTURE_COLOR_TABLE_SGI
+
+###############################################################################
+
+ErrorCode enum:
+	NO_ERROR					= 0
+	INVALID_ENUM					= 0x0500
+	INVALID_VALUE					= 0x0501
+	INVALID_OPERATION				= 0x0502
+	STACK_OVERFLOW					= 0x0503
+	STACK_UNDERFLOW					= 0x0504
+	OUT_OF_MEMORY					= 0x0505
+	use EXT_histogram TABLE_TOO_LARGE_EXT
+	use EXT_texture TEXTURE_TOO_LARGE_EXT
+
+# Additional error codes
+
+VERSION_3_0 enum:
+#	use ARB_framebuffer_object	    INVALID_FRAMEBUFFER_OPERATION
+
+ARB_framebuffer_object enum: (note: no ARB suffixes)
+	INVALID_FRAMEBUFFER_OPERATION			= 0x0506    # VERSION_3_0 / ARB_fbo
+
+EXT_framebuffer_object enum:
+	INVALID_FRAMEBUFFER_OPERATION_EXT		= 0x0506
+
+# Aliases EXT_fbo enum above
+OES_framebuffer_object enum: (OpenGL ES only; additional; see below)
+	INVALID_FRAMEBUFFER_OPERATION_OES		= 0x0506
+
+###############################################################################
+
+FeedbackType enum:
+	2D						= 0x0600
+	3D						= 0x0601
+	3D_COLOR					= 0x0602
+	3D_COLOR_TEXTURE				= 0x0603
+	4D_COLOR_TEXTURE				= 0x0604
+
+###############################################################################
+
+FeedBackToken enum:
+	PASS_THROUGH_TOKEN				= 0x0700
+	POINT_TOKEN					= 0x0701
+	LINE_TOKEN					= 0x0702
+	POLYGON_TOKEN					= 0x0703
+	BITMAP_TOKEN					= 0x0704
+	DRAW_PIXEL_TOKEN				= 0x0705
+	COPY_PIXEL_TOKEN				= 0x0706
+	LINE_RESET_TOKEN				= 0x0707
+
+###############################################################################
+
+FfdMaskSGIX enum:
+	TEXTURE_DEFORMATION_BIT_SGIX			= 0x00000001
+	GEOMETRY_DEFORMATION_BIT_SGIX			= 0x00000002
+
+###############################################################################
+
+FfdTargetSGIX enum:
+	use SGIX_polynomial_ffd GEOMETRY_DEFORMATION_SGIX
+	use SGIX_polynomial_ffd TEXTURE_DEFORMATION_SGIX
+
+###############################################################################
+
+FogMode enum:
+	use TextureMagFilter LINEAR
+	EXP						= 0x0800
+	EXP2						= 0x0801
+	use SGIS_fog_function FOG_FUNC_SGIS
+
+###############################################################################
+
+FogParameter enum:
+	use GetPName FOG_COLOR
+	use GetPName FOG_DENSITY
+	use GetPName FOG_END
+	use GetPName FOG_INDEX
+	use GetPName FOG_MODE
+	use GetPName FOG_START
+	use SGIX_fog_offset FOG_OFFSET_VALUE_SGIX
+
+###############################################################################
+
+FragmentLightModelParameterSGIX enum:
+	use SGIX_fragment_lighting FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX
+	use SGIX_fragment_lighting FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX
+	use SGIX_fragment_lighting FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX
+	use SGIX_fragment_lighting FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX
+
+###############################################################################
+
+FrontFaceDirection enum:
+	CW						= 0x0900
+	CCW						= 0x0901
+
+###############################################################################
+
+GetColorTableParameterPNameSGI enum:
+	use SGI_color_table COLOR_TABLE_SCALE_SGI
+	use SGI_color_table COLOR_TABLE_BIAS_SGI
+	use SGI_color_table COLOR_TABLE_FORMAT_SGI
+	use SGI_color_table COLOR_TABLE_WIDTH_SGI
+	use SGI_color_table COLOR_TABLE_RED_SIZE_SGI
+	use SGI_color_table COLOR_TABLE_GREEN_SIZE_SGI
+	use SGI_color_table COLOR_TABLE_BLUE_SIZE_SGI
+	use SGI_color_table COLOR_TABLE_ALPHA_SIZE_SGI
+	use SGI_color_table COLOR_TABLE_LUMINANCE_SIZE_SGI
+	use SGI_color_table COLOR_TABLE_INTENSITY_SIZE_SGI
+
+###############################################################################
+
+GetConvolutionParameter enum:
+	use EXT_convolution CONVOLUTION_BORDER_MODE_EXT
+	use EXT_convolution CONVOLUTION_FILTER_SCALE_EXT
+	use EXT_convolution CONVOLUTION_FILTER_BIAS_EXT
+	use EXT_convolution CONVOLUTION_FORMAT_EXT
+	use EXT_convolution CONVOLUTION_WIDTH_EXT
+	use EXT_convolution CONVOLUTION_HEIGHT_EXT
+	use EXT_convolution MAX_CONVOLUTION_WIDTH_EXT
+	use EXT_convolution MAX_CONVOLUTION_HEIGHT_EXT
+
+###############################################################################
+
+GetHistogramParameterPNameEXT enum:
+	use EXT_histogram HISTOGRAM_WIDTH_EXT
+	use EXT_histogram HISTOGRAM_FORMAT_EXT
+	use EXT_histogram HISTOGRAM_RED_SIZE_EXT
+	use EXT_histogram HISTOGRAM_GREEN_SIZE_EXT
+	use EXT_histogram HISTOGRAM_BLUE_SIZE_EXT
+	use EXT_histogram HISTOGRAM_ALPHA_SIZE_EXT
+	use EXT_histogram HISTOGRAM_LUMINANCE_SIZE_EXT
+	use EXT_histogram HISTOGRAM_SINK_EXT
+
+###############################################################################
+
+GetMapQuery enum:
+	COEFF						= 0x0A00
+	ORDER						= 0x0A01
+	DOMAIN						= 0x0A02
+
+###############################################################################
+
+GetMinmaxParameterPNameEXT enum:
+	use EXT_histogram MINMAX_FORMAT_EXT
+	use EXT_histogram MINMAX_SINK_EXT
+
+###############################################################################
+
+GetPixelMap enum:
+	PIXEL_MAP_I_TO_I				= 0x0C70
+	PIXEL_MAP_S_TO_S				= 0x0C71
+	PIXEL_MAP_I_TO_R				= 0x0C72
+	PIXEL_MAP_I_TO_G				= 0x0C73
+	PIXEL_MAP_I_TO_B				= 0x0C74
+	PIXEL_MAP_I_TO_A				= 0x0C75
+	PIXEL_MAP_R_TO_R				= 0x0C76
+	PIXEL_MAP_G_TO_G				= 0x0C77
+	PIXEL_MAP_B_TO_B				= 0x0C78
+	PIXEL_MAP_A_TO_A				= 0x0C79
+
+###############################################################################
+
+GetPointervPName enum:
+	VERTEX_ARRAY_POINTER				= 0x808E
+	NORMAL_ARRAY_POINTER				= 0x808F
+	COLOR_ARRAY_POINTER				= 0x8090
+	INDEX_ARRAY_POINTER				= 0x8091
+	TEXTURE_COORD_ARRAY_POINTER			= 0x8092
+	EDGE_FLAG_ARRAY_POINTER				= 0x8093
+	FEEDBACK_BUFFER_POINTER				= 0x0DF0
+	SELECTION_BUFFER_POINTER			= 0x0DF3
+	use SGIX_instruments INSTRUMENT_BUFFER_POINTER_SGIX
+
+###############################################################################
+
+# the columns after the comment symbol (#) indicate: number of params, type
+# (F - float, D - double, I - integer) for the returned values
+GetPName enum:
+	CURRENT_COLOR					= 0x0B00 # 4 F
+	CURRENT_INDEX					= 0x0B01 # 1 F
+	CURRENT_NORMAL					= 0x0B02 # 3 F
+	CURRENT_TEXTURE_COORDS				= 0x0B03 # 4 F
+	CURRENT_RASTER_COLOR				= 0x0B04 # 4 F
+	CURRENT_RASTER_INDEX				= 0x0B05 # 1 F
+	CURRENT_RASTER_TEXTURE_COORDS			= 0x0B06 # 4 F
+	CURRENT_RASTER_POSITION				= 0x0B07 # 4 F
+	CURRENT_RASTER_POSITION_VALID			= 0x0B08 # 1 I
+	CURRENT_RASTER_DISTANCE				= 0x0B09 # 1 F
+
+	POINT_SMOOTH					= 0x0B10 # 1 I
+	POINT_SIZE					= 0x0B11 # 1 F
+	POINT_SIZE_RANGE				= 0x0B12 # 2 F
+	POINT_SIZE_GRANULARITY				= 0x0B13 # 1 F
+
+	LINE_SMOOTH					= 0x0B20 # 1 I
+	LINE_WIDTH					= 0x0B21 # 1 F
+	LINE_WIDTH_RANGE				= 0x0B22 # 2 F
+	LINE_WIDTH_GRANULARITY				= 0x0B23 # 1 F
+	LINE_STIPPLE					= 0x0B24 # 1 I
+	LINE_STIPPLE_PATTERN				= 0x0B25 # 1 I
+	LINE_STIPPLE_REPEAT				= 0x0B26 # 1 I
+	use VERSION_1_2 SMOOTH_POINT_SIZE_RANGE
+	use VERSION_1_2 SMOOTH_POINT_SIZE_GRANULARITY
+	use VERSION_1_2 SMOOTH_LINE_WIDTH_RANGE
+	use VERSION_1_2 SMOOTH_LINE_WIDTH_GRANULARITY
+	use VERSION_1_2 ALIASED_POINT_SIZE_RANGE
+	use VERSION_1_2 ALIASED_LINE_WIDTH_RANGE
+
+	LIST_MODE					= 0x0B30 # 1 I
+	MAX_LIST_NESTING				= 0x0B31 # 1 I
+	LIST_BASE					= 0x0B32 # 1 I
+	LIST_INDEX					= 0x0B33 # 1 I
+
+	POLYGON_MODE					= 0x0B40 # 2 I
+	POLYGON_SMOOTH					= 0x0B41 # 1 I
+	POLYGON_STIPPLE					= 0x0B42 # 1 I
+	EDGE_FLAG					= 0x0B43 # 1 I
+	CULL_FACE					= 0x0B44 # 1 I
+	CULL_FACE_MODE					= 0x0B45 # 1 I
+	FRONT_FACE					= 0x0B46 # 1 I
+
+	LIGHTING					= 0x0B50 # 1 I
+	LIGHT_MODEL_LOCAL_VIEWER			= 0x0B51 # 1 I
+	LIGHT_MODEL_TWO_SIDE				= 0x0B52 # 1 I
+	LIGHT_MODEL_AMBIENT				= 0x0B53 # 4 F
+	SHADE_MODEL					= 0x0B54 # 1 I
+	COLOR_MATERIAL_FACE				= 0x0B55 # 1 I
+	COLOR_MATERIAL_PARAMETER			= 0x0B56 # 1 I
+	COLOR_MATERIAL					= 0x0B57 # 1 I
+
+	FOG						= 0x0B60 # 1 I
+	FOG_INDEX					= 0x0B61 # 1 I
+	FOG_DENSITY					= 0x0B62 # 1 F
+	FOG_START					= 0x0B63 # 1 F
+	FOG_END						= 0x0B64 # 1 F
+	FOG_MODE					= 0x0B65 # 1 I
+	FOG_COLOR					= 0x0B66 # 4 F
+
+	DEPTH_RANGE					= 0x0B70 # 2 F
+	DEPTH_TEST					= 0x0B71 # 1 I
+	DEPTH_WRITEMASK					= 0x0B72 # 1 I
+	DEPTH_CLEAR_VALUE				= 0x0B73 # 1 F
+	DEPTH_FUNC					= 0x0B74 # 1 I
+
+	ACCUM_CLEAR_VALUE				= 0x0B80 # 4 F
+
+	STENCIL_TEST					= 0x0B90 # 1 I
+	STENCIL_CLEAR_VALUE				= 0x0B91 # 1 I
+	STENCIL_FUNC					= 0x0B92 # 1 I
+	STENCIL_VALUE_MASK				= 0x0B93 # 1 I
+	STENCIL_FAIL					= 0x0B94 # 1 I
+	STENCIL_PASS_DEPTH_FAIL				= 0x0B95 # 1 I
+	STENCIL_PASS_DEPTH_PASS				= 0x0B96 # 1 I
+	STENCIL_REF					= 0x0B97 # 1 I
+	STENCIL_WRITEMASK				= 0x0B98 # 1 I
+
+	MATRIX_MODE					= 0x0BA0 # 1 I
+	NORMALIZE					= 0x0BA1 # 1 I
+	VIEWPORT					= 0x0BA2 # 4 I
+	MODELVIEW_STACK_DEPTH				= 0x0BA3 # 1 I
+	PROJECTION_STACK_DEPTH				= 0x0BA4 # 1 I
+	TEXTURE_STACK_DEPTH				= 0x0BA5 # 1 I
+	MODELVIEW_MATRIX				= 0x0BA6 # 16 F
+	PROJECTION_MATRIX				= 0x0BA7 # 16 F
+	TEXTURE_MATRIX					= 0x0BA8 # 16 F
+
+	ATTRIB_STACK_DEPTH				= 0x0BB0 # 1 I
+	CLIENT_ATTRIB_STACK_DEPTH			= 0x0BB1 # 1 I
+
+	ALPHA_TEST					= 0x0BC0 # 1 I
+	ALPHA_TEST_FUNC					= 0x0BC1 # 1 I
+	ALPHA_TEST_REF					= 0x0BC2 # 1 F
+
+	DITHER						= 0x0BD0 # 1 I
+
+	BLEND_DST					= 0x0BE0 # 1 I
+	BLEND_SRC					= 0x0BE1 # 1 I
+	BLEND						= 0x0BE2 # 1 I
+
+	LOGIC_OP_MODE					= 0x0BF0 # 1 I
+	INDEX_LOGIC_OP					= 0x0BF1 # 1 I
+	LOGIC_OP					= 0x0BF1 # 1 I
+	COLOR_LOGIC_OP					= 0x0BF2 # 1 I
+
+	AUX_BUFFERS					= 0x0C00 # 1 I
+	DRAW_BUFFER					= 0x0C01 # 1 I
+	READ_BUFFER					= 0x0C02 # 1 I
+
+	SCISSOR_BOX					= 0x0C10 # 4 I
+	SCISSOR_TEST					= 0x0C11 # 1 I
+
+	INDEX_CLEAR_VALUE				= 0x0C20 # 1 I
+	INDEX_WRITEMASK					= 0x0C21 # 1 I
+	COLOR_CLEAR_VALUE				= 0x0C22 # 4 F
+	COLOR_WRITEMASK					= 0x0C23 # 4 I
+
+	INDEX_MODE					= 0x0C30 # 1 I
+	RGBA_MODE					= 0x0C31 # 1 I
+	DOUBLEBUFFER					= 0x0C32 # 1 I
+	STEREO						= 0x0C33 # 1 I
+
+	RENDER_MODE					= 0x0C40 # 1 I
+
+	PERSPECTIVE_CORRECTION_HINT			= 0x0C50 # 1 I
+	POINT_SMOOTH_HINT				= 0x0C51 # 1 I
+	LINE_SMOOTH_HINT				= 0x0C52 # 1 I
+	POLYGON_SMOOTH_HINT				= 0x0C53 # 1 I
+	FOG_HINT					= 0x0C54 # 1 I
+
+	TEXTURE_GEN_S					= 0x0C60 # 1 I
+	TEXTURE_GEN_T					= 0x0C61 # 1 I
+	TEXTURE_GEN_R					= 0x0C62 # 1 I
+	TEXTURE_GEN_Q					= 0x0C63 # 1 I
+
+	PIXEL_MAP_I_TO_I_SIZE				= 0x0CB0 # 1 I
+	PIXEL_MAP_S_TO_S_SIZE				= 0x0CB1 # 1 I
+	PIXEL_MAP_I_TO_R_SIZE				= 0x0CB2 # 1 I
+	PIXEL_MAP_I_TO_G_SIZE				= 0x0CB3 # 1 I
+	PIXEL_MAP_I_TO_B_SIZE				= 0x0CB4 # 1 I
+	PIXEL_MAP_I_TO_A_SIZE				= 0x0CB5 # 1 I
+	PIXEL_MAP_R_TO_R_SIZE				= 0x0CB6 # 1 I
+	PIXEL_MAP_G_TO_G_SIZE				= 0x0CB7 # 1 I
+	PIXEL_MAP_B_TO_B_SIZE				= 0x0CB8 # 1 I
+	PIXEL_MAP_A_TO_A_SIZE				= 0x0CB9 # 1 I
+
+	UNPACK_SWAP_BYTES				= 0x0CF0 # 1 I
+	UNPACK_LSB_FIRST				= 0x0CF1 # 1 I
+	UNPACK_ROW_LENGTH				= 0x0CF2 # 1 I
+	UNPACK_SKIP_ROWS				= 0x0CF3 # 1 I
+	UNPACK_SKIP_PIXELS				= 0x0CF4 # 1 I
+	UNPACK_ALIGNMENT				= 0x0CF5 # 1 I
+
+	PACK_SWAP_BYTES					= 0x0D00 # 1 I
+	PACK_LSB_FIRST					= 0x0D01 # 1 I
+	PACK_ROW_LENGTH					= 0x0D02 # 1 I
+	PACK_SKIP_ROWS					= 0x0D03 # 1 I
+	PACK_SKIP_PIXELS				= 0x0D04 # 1 I
+	PACK_ALIGNMENT					= 0x0D05 # 1 I
+
+	MAP_COLOR					= 0x0D10 # 1 I
+	MAP_STENCIL					= 0x0D11 # 1 I
+	INDEX_SHIFT					= 0x0D12 # 1 I
+	INDEX_OFFSET					= 0x0D13 # 1 I
+	RED_SCALE					= 0x0D14 # 1 F
+	RED_BIAS					= 0x0D15 # 1 F
+	ZOOM_X						= 0x0D16 # 1 F
+	ZOOM_Y						= 0x0D17 # 1 F
+	GREEN_SCALE					= 0x0D18 # 1 F
+	GREEN_BIAS					= 0x0D19 # 1 F
+	BLUE_SCALE					= 0x0D1A # 1 F
+	BLUE_BIAS					= 0x0D1B # 1 F
+	ALPHA_SCALE					= 0x0D1C # 1 F
+	ALPHA_BIAS					= 0x0D1D # 1 F
+	DEPTH_SCALE					= 0x0D1E # 1 F
+	DEPTH_BIAS					= 0x0D1F # 1 F
+
+	MAX_EVAL_ORDER					= 0x0D30 # 1 I
+	MAX_LIGHTS					= 0x0D31 # 1 I
+
+# VERSION_3_0 enum: (aliases)
+	MAX_CLIP_DISTANCES				= 0x0D32    # VERSION_3_0   # alias GL_MAX_CLIP_PLANES
+
+	MAX_CLIP_PLANES					= 0x0D32 # 1 I
+	MAX_TEXTURE_SIZE				= 0x0D33 # 1 I
+	MAX_PIXEL_MAP_TABLE				= 0x0D34 # 1 I
+	MAX_ATTRIB_STACK_DEPTH				= 0x0D35 # 1 I
+	MAX_MODELVIEW_STACK_DEPTH			= 0x0D36 # 1 I
+	MAX_NAME_STACK_DEPTH				= 0x0D37 # 1 I
+	MAX_PROJECTION_STACK_DEPTH			= 0x0D38 # 1 I
+	MAX_TEXTURE_STACK_DEPTH				= 0x0D39 # 1 I
+	MAX_VIEWPORT_DIMS				= 0x0D3A # 2 F
+	MAX_CLIENT_ATTRIB_STACK_DEPTH			= 0x0D3B # 1 I
+
+	SUBPIXEL_BITS					= 0x0D50 # 1 I
+	INDEX_BITS					= 0x0D51 # 1 I
+	RED_BITS					= 0x0D52 # 1 I
+	GREEN_BITS					= 0x0D53 # 1 I
+	BLUE_BITS					= 0x0D54 # 1 I
+	ALPHA_BITS					= 0x0D55 # 1 I
+	DEPTH_BITS					= 0x0D56 # 1 I
+	STENCIL_BITS					= 0x0D57 # 1 I
+	ACCUM_RED_BITS					= 0x0D58 # 1 I
+	ACCUM_GREEN_BITS				= 0x0D59 # 1 I
+	ACCUM_BLUE_BITS					= 0x0D5A # 1 I
+	ACCUM_ALPHA_BITS				= 0x0D5B # 1 I
+
+	NAME_STACK_DEPTH				= 0x0D70 # 1 I
+
+	AUTO_NORMAL					= 0x0D80 # 1 I
+
+	MAP1_COLOR_4					= 0x0D90 # 1 I
+	MAP1_INDEX					= 0x0D91 # 1 I
+	MAP1_NORMAL					= 0x0D92 # 1 I
+	MAP1_TEXTURE_COORD_1				= 0x0D93 # 1 I
+	MAP1_TEXTURE_COORD_2				= 0x0D94 # 1 I
+	MAP1_TEXTURE_COORD_3				= 0x0D95 # 1 I
+	MAP1_TEXTURE_COORD_4				= 0x0D96 # 1 I
+	MAP1_VERTEX_3					= 0x0D97 # 1 I
+	MAP1_VERTEX_4					= 0x0D98 # 1 I
+
+	MAP2_COLOR_4					= 0x0DB0 # 1 I
+	MAP2_INDEX					= 0x0DB1 # 1 I
+	MAP2_NORMAL					= 0x0DB2 # 1 I
+	MAP2_TEXTURE_COORD_1				= 0x0DB3 # 1 I
+	MAP2_TEXTURE_COORD_2				= 0x0DB4 # 1 I
+	MAP2_TEXTURE_COORD_3				= 0x0DB5 # 1 I
+	MAP2_TEXTURE_COORD_4				= 0x0DB6 # 1 I
+	MAP2_VERTEX_3					= 0x0DB7 # 1 I
+	MAP2_VERTEX_4					= 0x0DB8 # 1 I
+
+	MAP1_GRID_DOMAIN				= 0x0DD0 # 2 F
+	MAP1_GRID_SEGMENTS				= 0x0DD1 # 1 I
+	MAP2_GRID_DOMAIN				= 0x0DD2 # 4 F
+	MAP2_GRID_SEGMENTS				= 0x0DD3 # 2 I
+
+	TEXTURE_1D					= 0x0DE0 # 1 I
+	TEXTURE_2D					= 0x0DE1 # 1 I
+
+	FEEDBACK_BUFFER_SIZE				= 0x0DF1 # 1 I
+	FEEDBACK_BUFFER_TYPE				= 0x0DF2 # 1 I
+
+	SELECTION_BUFFER_SIZE				= 0x0DF4 # 1 I
+
+	POLYGON_OFFSET_UNITS				= 0x2A00 # 1 F
+	POLYGON_OFFSET_POINT				= 0x2A01 # 1 I
+	POLYGON_OFFSET_LINE				= 0x2A02 # 1 I
+	POLYGON_OFFSET_FILL				= 0x8037 # 1 I
+	POLYGON_OFFSET_FACTOR				= 0x8038 # 1 F
+
+	TEXTURE_BINDING_1D				= 0x8068 # 1 I
+	TEXTURE_BINDING_2D				= 0x8069 # 1 I
+	TEXTURE_BINDING_3D				= 0x806A # 1 I
+
+	VERTEX_ARRAY					= 0x8074 # 1 I
+	NORMAL_ARRAY					= 0x8075 # 1 I
+	COLOR_ARRAY					= 0x8076 # 1 I
+	INDEX_ARRAY					= 0x8077 # 1 I
+	TEXTURE_COORD_ARRAY				= 0x8078 # 1 I
+	EDGE_FLAG_ARRAY					= 0x8079 # 1 I
+
+	VERTEX_ARRAY_SIZE				= 0x807A # 1 I
+	VERTEX_ARRAY_TYPE				= 0x807B # 1 I
+	VERTEX_ARRAY_STRIDE				= 0x807C # 1 I
+
+	NORMAL_ARRAY_TYPE				= 0x807E # 1 I
+	NORMAL_ARRAY_STRIDE				= 0x807F # 1 I
+
+	COLOR_ARRAY_SIZE				= 0x8081 # 1 I
+	COLOR_ARRAY_TYPE				= 0x8082 # 1 I
+	COLOR_ARRAY_STRIDE				= 0x8083 # 1 I
+
+	INDEX_ARRAY_TYPE				= 0x8085 # 1 I
+	INDEX_ARRAY_STRIDE				= 0x8086 # 1 I
+
+	TEXTURE_COORD_ARRAY_SIZE			= 0x8088 # 1 I
+	TEXTURE_COORD_ARRAY_TYPE			= 0x8089 # 1 I
+	TEXTURE_COORD_ARRAY_STRIDE			= 0x808A # 1 I
+
+	EDGE_FLAG_ARRAY_STRIDE				= 0x808C # 1 I
+
+	use ClipPlaneName CLIP_PLANE0
+	use ClipPlaneName CLIP_PLANE1
+	use ClipPlaneName CLIP_PLANE2
+	use ClipPlaneName CLIP_PLANE3
+	use ClipPlaneName CLIP_PLANE4
+	use ClipPlaneName CLIP_PLANE5
+
+	use LightName LIGHT0
+	use LightName LIGHT1
+	use LightName LIGHT2
+	use LightName LIGHT3
+	use LightName LIGHT4
+	use LightName LIGHT5
+	use LightName LIGHT6
+	use LightName LIGHT7
+
+#	use ARB_transpose_matrix	    TRANSPOSE_MODELVIEW_MATRIX_ARB
+#	use ARB_transpose_matrix	    TRANSPOSE_PROJECTION_MATRIX_ARB
+#	use ARB_transpose_matrix	    TRANSPOSE_TEXTURE_MATRIX_ARB
+#	use ARB_transpose_matrix	    TRANSPOSE_COLOR_MATRIX_ARB
+
+	use VERSION_1_2 LIGHT_MODEL_COLOR_CONTROL
+
+	use EXT_blend_color BLEND_COLOR_EXT
+
+	use EXT_blend_minmax BLEND_EQUATION_EXT
+
+	use EXT_cmyka PACK_CMYK_HINT_EXT
+	use EXT_cmyka UNPACK_CMYK_HINT_EXT
+
+	use EXT_convolution CONVOLUTION_1D_EXT
+	use EXT_convolution CONVOLUTION_2D_EXT
+	use EXT_convolution SEPARABLE_2D_EXT
+	use EXT_convolution POST_CONVOLUTION_RED_SCALE_EXT
+	use EXT_convolution POST_CONVOLUTION_GREEN_SCALE_EXT
+	use EXT_convolution POST_CONVOLUTION_BLUE_SCALE_EXT
+	use EXT_convolution POST_CONVOLUTION_ALPHA_SCALE_EXT
+	use EXT_convolution POST_CONVOLUTION_RED_BIAS_EXT
+	use EXT_convolution POST_CONVOLUTION_GREEN_BIAS_EXT
+	use EXT_convolution POST_CONVOLUTION_BLUE_BIAS_EXT
+	use EXT_convolution POST_CONVOLUTION_ALPHA_BIAS_EXT
+
+	use EXT_histogram HISTOGRAM_EXT
+	use EXT_histogram MINMAX_EXT
+
+	use EXT_polygon_offset POLYGON_OFFSET_BIAS_EXT
+
+	use EXT_rescale_normal RESCALE_NORMAL_EXT
+
+	use EXT_shared_texture_palette SHARED_TEXTURE_PALETTE_EXT
+
+	use EXT_texture_object TEXTURE_3D_BINDING_EXT
+
+	use EXT_texture3D PACK_SKIP_IMAGES_EXT
+	use EXT_texture3D PACK_IMAGE_HEIGHT_EXT
+	use EXT_texture3D UNPACK_SKIP_IMAGES_EXT
+	use EXT_texture3D UNPACK_IMAGE_HEIGHT_EXT
+	use EXT_texture3D TEXTURE_3D_EXT
+	use EXT_texture3D MAX_3D_TEXTURE_SIZE_EXT
+
+	use EXT_vertex_array VERTEX_ARRAY_COUNT_EXT
+	use EXT_vertex_array NORMAL_ARRAY_COUNT_EXT
+	use EXT_vertex_array COLOR_ARRAY_COUNT_EXT
+	use EXT_vertex_array INDEX_ARRAY_COUNT_EXT
+	use EXT_vertex_array TEXTURE_COORD_ARRAY_COUNT_EXT
+	use EXT_vertex_array EDGE_FLAG_ARRAY_COUNT_EXT