Commits

Jason McKesson committed 230a463

Noload for C now.

Comments (0)

Files changed (9)

 	[[lua $<dir>LoadGen.lua -spec=gl -version=3.3 -profile=compatibility -style=pointer_c -stdext=gl_ubiquitous.txt $<dir>test/ptr_c_comp/test]],
 	[[lua $<dir>LoadGen.lua -spec=gl -version=3.3 -profile=compatibility -style=noload_cpp  -stdext=gl_ubiquitous.txt $<dir>test/noload_cpp/test]],
 	[[lua $<dir>LoadGen.lua -spec=gl -version=3.3 -profile=compatibility -style=noload_cpp $<dir>test/noload_cpp_noext/test]],
+	[[lua $<dir>LoadGen.lua -spec=gl -version=3.3 -profile=core -style=noload_c -stdext=gl_ubiquitous.txt $<dir>test/noload_c/test]],
+	[[lua $<dir>LoadGen.lua -spec=gl -version=2.1 -style=noload_c -stdext=gl_ubiquitous.txt $<dir>test/noload_c_old/test]],
 }
 
 local platTests =
 		[[lua $<dir>LoadGen.lua -spec=wgl -style=pointer_c -stdext=wgl_common.txt $<dir>test/ptr_c_comp/test]],
 		[[lua $<dir>LoadGen.lua -spec=wgl -style=noload_cpp  -stdext=wgl_common.txt $<dir>test/noload_cpp/test]],
 		[[lua $<dir>LoadGen.lua -spec=wgl -style=noload_cpp  -stdext=wgl_common.txt $<dir>test/noload_cpp_noext/test]],
+		[[lua $<dir>LoadGen.lua -spec=wgl -style=noload_c  -stdext=wgl_common.txt $<dir>test/noload_c/test]],
+		[[lua $<dir>LoadGen.lua -spec=wgl -style=noload_c  -stdext=wgl_common.txt $<dir>test/noload_c_old/test]],
 	},
 	
 	glX =
 		[[lua $<dir>LoadGen.lua -spec=glX -style=pointer_c -stdext=glx_common.txt $<dir>test/ptr_c_comp/test]],
 		[[lua $<dir>LoadGen.lua -spec=glX -style=noload_cpp -stdext=glx_common.txt $<dir>test/noload_cpp/test]],
 		[[lua $<dir>LoadGen.lua -spec=glX -style=noload_cpp -stdext=glx_common.txt $<dir>test/noload_cpp_noext/test]],
+		[[lua $<dir>LoadGen.lua -spec=glX -style=noload_c -stdext=glx_common.txt $<dir>test/noload_c/test]],
+		[[lua $<dir>LoadGen.lua -spec=glX -style=noload_c -stdext=glx_common.txt $<dir>test/noload_c_old/test]],
 	},
 }
 

modules/FuncCpp_Style.lua

 end
 
 	local function GenIncludeGuardName(hFile, spec, options)
-		local str = "POINTER_CPP_GENERATED_HEADER" ..
+		local str = "FUNCTION_CPP_GENERATED_HEADER" ..
 			spec.GetIncludeGuardString() .. "_HPP"
 
 		if(#options.prefix > 0) then
 end
 
 	local function GenExtLoaderFuncName(extName, spec, options)
-		return "_detail::Load_" .. extName;
+		return "Load_" .. extName;
 	end
 
 function my_style.source.WriteBlockBeginExtLoader(hFile, extName, spec, options)
 	hFile:fmt("table.reserve(%i);\n", #options.extensions)
 	for _, extName in ipairs(options.extensions) do
 		if(#specData.extdefs[extName].funcs > 0) then
-			hFile:fmt('table.push_back(MapEntry("%s", &exts::%s, %s));\n',
+			hFile:fmt('table.push_back(MapEntry("%s", &exts::%s, _detail::%s));\n',
 				spec.ExtNamePrefix() .. extName,
 				GenExtensionVarName(extName, spec, options),
 				GenExtLoaderFuncName(extName, spec, options))

modules/NoloadC_Struct.lua

+
+local struct = require "Structure"
+local common = require "CommonStruct"
+
+
+local sys_functions =
+{ type="block", name="System(hFile, spec, options)",
+	{type="write", name="SetupFunction(hFile, specData, spec, options)", },
+	{type="blank", cond="version-iter" },
+	{type="write", name="VersionFunctions(hFile, specData, spec, options)", cond="version-iter"},
+}
+
+local my_struct =
+{
+	{ type="file", style="hdr", name="GetFilename(basename, spec, options)",
+		{ type="write", name="FilePreamble", optional=true} ,
+		{ type="block", name="IncludeGuard",
+			{ type="blank"},
+			{ type="write", name="Guards(hFile, spec, options)",},
+			{ type="blank"},
+			{ type="write", name="Typedefs(hFile, specData, spec, options)",},
+			{ type="blank"},
+			
+			{ type="block", name="ExternC(hFile, spec, options)",
+				{ type="write", name="LargeHeader(hFile, value, options)", value="Extension Variables", },
+				{ type="blank"},
+				{ type="block", name="ExtVariables(hFile, spec, options)",
+					common.Extensions(),
+				},
+				{ type="blank"},
+				{ type="block", name="Enumerators(hFile, spec, options)",
+					common.Enumerators(),
+				},
+				{ type="blank"},
+				common.Functions(),
+				sys_functions,
+			},
+		},
+	},
+	
+	{ type="file", style="src", name="GetFilename(basename, spec, options)",
+		{ type="write", name="Includes(hFile, basename, spec, options)", },
+		{ type="blank"},
+		{ type="write", name="LoaderFunc(hFile, spec, options)", },
+		{ type="blank"},
+		{ type="block", name="ExtVariables(hFile, spec, options)",
+			common.Extensions(),
+		},
+		{ type="blank"},
+		{ type="group", style="typedefs",
+			common.Functions(),
+		},
+		{ type="blank"},
+		{ type="group", style="defs",
+			common.Functions(),
+		},
+		{ type="blank"},
+		{ type="group", style="switch",
+			common.Functions(),
+		},
+		{ type="blank"},
+		sys_functions,
+	},
+}
+
+my_struct = struct.BuildStructure(my_struct)
+return my_struct

modules/NoloadC_Style.lua

+local util = require "util"
+local struct = require "NoloadC_Struct"
+local common = require "CommonStyle"
+
+--------------------------------------
+-- Common functions.
+local function GetIncludeGuard(spec, options)
+	local temp = 
+		options.prefix .. spec.GetIncludeGuardString() .. "_NOLOAD_STYLE_H"
+	return temp:upper()
+end
+
+local function GetEnumName(enum, spec, options)
+	return options.prefix .. spec.EnumNamePrefix() .. enum.name
+end
+
+local function GetFuncPtrName(func, spec, options)
+	return options.prefix .. "_ptrc_".. spec.FuncNamePrefix() .. func.name
+end
+
+local function GetFuncName(func, spec, options)
+	return options.prefix .. spec.FuncNamePrefix() .. func.name
+end
+
+local function GetFuncPtrTypedefName(func, spec, options)
+	return "PFN" .. GetFuncPtrName(func, spec, options):upper() .. "PROC"
+end
+
+local function WriteFuncPtrTypedefStmt(hFile, func, typemap, spec, options)
+	hFile:fmt("typedef %s (%s *%s)(%s);\n",
+		common.GetFuncReturnType(func, typemap),
+		spec.GetCodegenPtrType(),
+		GetFuncPtrTypedefName(func, spec, options),
+		common.GetFuncParamList(func, typemap))
+end
+
+local function GetFuncPtrDefDirect(func, typemap, spec, options)
+	return string.format("%s (%s *%s)(%s)",
+		common.GetFuncReturnType(func, typemap),
+		spec.GetCodegenPtrType(),
+		GetFuncPtrName(func, spec, options),
+		common.GetFuncParamList(func, typemap, true))
+end
+
+local function GetFuncPtrDefTypedef(func, typemap, spec, options)
+	return string.format("%s %s",
+		GetFuncPtrTypedefName(func, spec, options),
+		GetFuncPtrName(func, spec, options))
+end
+
+--------------------------------------
+-- All style functions.
+local my_style = {}
+
+function my_style.WriteLargeHeader(hFile, value, options)
+	local len = #value
+	hFile:write("///", string.rep("/", len), "///\n")
+	hFile:write("// ", value, "\n")
+end
+
+function my_style.WriteSmallHeader(hFile, value, options)
+	hFile:write("// ", value, "\n")
+end
+
+function my_style.WriteBlockBeginExtVariables(hFile, spec, options)
+end
+
+function my_style.WriteBlockEndExtVariables(hFile, spec, options)
+end
+
+function my_style.WriteBlockBeginSystem(hFile, spec, options)
+end
+
+function my_style.WriteBlockEndSystem(hFile, spec, options)
+end
+
+
+---------------------------------------------
+-- Header functions.
+local hdr = {}
+my_style.hdr = hdr
+
+function hdr.GetFilename(basename, spec, options)
+	return basename .. ".h"
+end
+
+function hdr.WriteBlockBeginIncludeGuard(hFile, spec, options)
+	local guard = GetIncludeGuard(spec, options)
+	hFile:fmt("#ifndef %s\n", guard)
+	hFile:fmt("#define %s\n", guard)
+end
+
+function hdr.WriteBlockEndIncludeGuard(hFile, spec, options)
+	hFile:fmt("#endif //%s\n", GetIncludeGuard(spec, options))
+end
+
+function hdr.WriteGuards(hFile, spec, options)
+	hFile:rawwrite(spec.GetHeaderInit())
+end
+
+function hdr.WriteTypedefs(hFile, specData, spec, options)
+	local defArray = common.GetStdTypedefs()
+	
+	--Use include-guards for the typedefs, since they're common among
+	--headers in this style.
+	hFile:write("#ifndef GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS\n")
+	hFile:write("#define GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS\n")
+	hFile:write("\n")
+	hFile:inc()
+	
+	for _, def in ipairs(defArray) do
+		hFile:write(def)
+	end
+	
+	hFile:dec()
+	hFile:write("\n")
+	hFile:write("#endif /*GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS*/\n")
+	hFile:write("\n")
+
+	common.WritePassthruData(hFile, specData.funcData.passthru)
+end
+
+function hdr.WriteExtension(hFile, extName, spec, options)
+	hFile:fmt("extern int %s%sext_%s;\n", options.prefix, spec.DeclPrefix(), extName)
+end
+
+function hdr.WriteBlockBeginEnumerators(hFile, spec, options)
+end
+
+function hdr.WriteBlockEndEnumerators(hFile, spec, options)
+end
+
+function hdr.WriteEnumerator(hFile, enum, enumTable, spec, options, enumSeen)
+	local name = GetEnumName(enum, spec, options)
+	if(enumSeen[enum.name]) then
+		hFile:fmt("//%s seen in %s\n", name, enumSeen[enum.name])
+	else
+		hFile:fmt("#define %s%s%s\n",
+			name,
+			common.GetNameLengthPadding(name, 33),
+			common.ResolveEnumValue(enum, enumTable))
+	end
+end
+
+function hdr.WriteBlockBeginExternC(hFile, spec, options)
+	common.WriteExternCStart(hFile)
+end
+
+function hdr.WriteBlockEndExternC(hFile, spec, options)
+	common.WriteExternCEnd(hFile)
+end
+
+function hdr.WriteFunction(hFile, func, typemap, spec, options, funcSeen)
+	if(funcSeen[func.name]) then return end
+	
+	hFile:write("extern ", GetFuncPtrDefDirect(func, typemap, spec, options), ";\n")
+	hFile:fmt("#define %s %s\n", GetFuncName(func, spec, options),
+		GetFuncPtrName(func, spec, options))
+end
+
+function hdr.WriteSetupFunction(hFile, specData, spec, options)
+	hFile:fmt("void %sCheckExtensions(%s);\n", spec.DeclPrefix(), spec.GetLoaderParams())
+end
+
+function hdr.WriteVersionFunctions(hFile, specData, spec, options)
+end
+
+
+----------------------------------------
+-- Source file.
+local src = {}
+my_style.src = src
+
+function src.GetFilename(basename, spec, options)
+	return basename .. ".c"
+end
+
+function src.WriteIncludes(hFile, basename, spec, options)
+	hFile:writeblock([[
+#include <stdlib.h>
+#include <string.h>
+#include <stddef.h>
+]])
+
+	local base = util.ParsePath(hdr.GetFilename(basename, spec, options))
+	hFile:fmt('#include "%s"\n', base)
+
+end
+
+function src.WriteLoaderFunc(hFile, spec, options)
+	hFile:writeblock(spec.GetLoaderFunc())
+end
+
+function src.WriteExtension(hFile, extName, spec, options)
+	hFile:fmt("int %s%sext_%s = 0;\n", options.prefix, spec.DeclPrefix(), extName)
+end
+
+function src.WriteSetupFunction(hFile, specData, spec, options)
+	hFile:write "static void ClearExtensionVariables()\n"
+	hFile:write "{\n"
+	hFile:inc()
+	
+	for _, extName in ipairs(options.extensions) do
+		hFile:fmt("%s%sext_%s = 0;\n", options.prefix, spec.DeclPrefix(), extName)
+	end
+	
+	hFile:dec()
+	hFile:write "}\n"
+	hFile:write "\n"
+	
+	local mapTableName = options.prefix .. spec.DeclPrefix() .. "MapTable"
+	
+	hFile:writeblock([[
+typedef struct ]] .. mapTableName .. [[_s
+{
+	char *extName;
+	int *extVariable;
+}]] .. mapTableName .. [[;
+
+]])
+
+	local arrayLength = #options.extensions
+	if(arrayLength == 0) then arrayLength = 1 end
+
+	hFile:fmt("static %s g_mappingTable[%i] =\n", mapTableName, arrayLength)
+	hFile:write "{\n"
+	hFile:inc()
+	for _, extName in ipairs(options.extensions) do
+		hFile:fmt('{"%s%s", &%s%sext_%s},\n',
+			spec.ExtNamePrefix(),
+			extName,
+			options.prefix,
+			spec.DeclPrefix(),
+			extName)
+	end
+	hFile:dec()
+	hFile:write "};\n"
+	
+	hFile:write "\n"
+	hFile:fmtblock([[
+static void LoadExtByName(const char *extensionName)
+{
+	%s *tableEnd = &g_mappingTable[%i];
+	%s *entry = &g_mappingTable[0];
+	for(; entry != tableEnd; ++entry)
+	{
+		if(strcmp(entry->extName, extensionName) == 0)
+			break;
+	}
+	
+	if(entry != tableEnd)
+		*(entry->extVariable) = 1;
+}
+]], mapTableName, #options.extensions, mapTableName)
+
+	hFile:write "\n"
+	
+	local indexed = spec.GetIndexedExtStringFunc(options);
+	if(indexed) then
+		indexed[1] = specData.functable[indexed[1]]
+		indexed[3] = specData.functable[indexed[3]]
+		for _, enum in ipairs(specData.enumerations) do
+			if(indexed[2] == enum.name) then
+				indexed[2] = enum
+			end
+			if(indexed[4] == enum.name) then
+				indexed[4] = enum
+			end
+		end
+
+		hFile:writeblock([[
+void ProcExtsFromExtList()
+{
+	GLint iLoop;
+	GLint iNumExtensions = 0;
+	]] .. GetFuncPtrName(indexed[1], spec, options)
+	.. [[(]] .. GetEnumName(indexed[2], spec, options)
+	.. [[, &iNumExtensions);
+
+	for(iLoop = 0; iLoop < iNumExtensions; iLoop++)
+	{
+		const char *strExtensionName = (const char *)]] ..
+		GetFuncPtrName(indexed[3], spec, options) ..
+		[[(]] .. GetEnumName(indexed[4], spec, options) .. [[, iLoop);
+		LoadExtByName(strExtensionName);
+	}
+}
+]])
+	else
+		hFile:writeblock(
+			common.GetProcessExtsFromStringFunc("LoadExtByName(%s)"))
+	end
+
+	hFile:write "\n"
+	hFile:fmt("void %sCheckExtensions(%s)\n", spec.DeclPrefix(), spec.GetLoaderParams())
+	hFile:write "{\n"
+	hFile:inc()
+	hFile:write "ClearExtensionVariables();\n"
+	hFile:write "\n"
+	if(indexed) then
+		hFile:write("ProcExtsFromExtList();\n")
+	else
+		--First, check if the GetExtStringFuncName is in the specData.
+		hFile:write "{\n"
+		hFile:inc()
+		
+		local funcName = spec.GetExtStringFuncName()
+		if(specData.functable[funcName]) then
+			--Create a function pointer and load it.
+			local func = specData.functable[funcName]
+			local typemap = specData.typemap
+			funcName = "InternalGetExtensionString"
+
+				hFile:fmt("typedef %s (%s *MYGETEXTSTRINGPROC)(%s);\n",
+					common.GetFuncReturnType(func, typemap),
+					spec.GetCodegenPtrType(),
+					common.GetFuncParamList(func, typemap))
+				hFile:fmt('MYGETEXTSTRINGPROC %s = (MYGETEXTSTRINGPROC)%s("%s%s");\n',
+					funcName,
+					spec.GetPtrLoaderFuncName(),
+					spec.FuncNamePrefix(),
+					func.name)
+				hFile:fmt("if(!%s) return;\n", funcName)
+		end
+		
+		hFile:fmt("ProcExtsFromExtString((const char *)%s(%s));\n",
+			funcName,
+			spec.GetExtStringParamList(
+				function (name) return options.prefix .. spec.EnumNamePrefix() .. name end))
+		hFile:dec()
+		hFile:write "}\n"
+	end
+	hFile:dec()
+	hFile:write "}\n"
+end
+
+function src.WriteVersionFunctions(hFile, specData, spec, options)
+end
+
+local typedefs = {}
+src.typedefs = typedefs
+
+function typedefs.WriteFunction(hFile, func, typemap, spec, options, funcSeen)
+	WriteFuncPtrTypedefStmt(hFile, func, typemap, spec, options)
+	hFile:fmt("static %s %s Switch_%s(%s);\n",
+		common.GetFuncReturnType(func, typemap),
+		spec.GetCodegenPtrType(),
+		func.name,
+		common.GetFuncParamList(func, typemap, true))
+end
+
+local defs = {}
+src.defs = defs
+
+function defs.WriteFunction(hFile, func, typemap, spec, options, funcSeen)
+	hFile:fmt("%s = Switch_%s;\n",
+		GetFuncPtrDefTypedef(func, typemap, spec, options),
+		func.name)
+end
+
+local switch = {}
+src.switch = switch
+
+function switch.WriteFunction(hFile, func, typemap, spec, options, funcSeen)
+	hFile:fmt("static %s %s Switch_%s(%s)\n",
+		common.GetFuncReturnType(func, typemap),
+		spec.GetCodegenPtrType(),
+		func.name,
+		common.GetFuncParamList(func, typemap, true))
+	hFile:write "{\n"
+	hFile:inc()
+	hFile:fmt('%s = (%s)%s("%s%s");\n',
+		GetFuncPtrName(func, spec, options),
+		GetFuncPtrTypedefName(func, spec, options),
+		spec.GetPtrLoaderFuncName(),
+		spec.FuncNamePrefix(),
+		func.name)
+		
+	if(common.DoesFuncReturnSomething(func, typemap)) then
+		hFile:fmt('%s(%s);\n',
+			GetFuncPtrName(func, spec, options),
+			common.GetFuncParamCallList(func, typemap))
+	else
+		hFile:fmt('return %s(%s);\n',
+			GetFuncPtrName(func, spec, options),
+			common.GetFuncParamCallList(func, typemap))
+	end
+	hFile:dec()
+	hFile:write "}\n\n"
+end
+
+function switch.WriteGetExtString(hFile, specData, spec, options, funcSeen)
+	if(funcSeen[spec.GetExtStringFuncName()]) then
+		return
+	end
+
+	local func = specData.funcdefs[spec.GetExtStringFuncName()]
+	if(func) then
+		hFile:write "\n"
+		hFile:fmt("static %s %s(%s)\n",
+			common.GetFuncReturnType(func, typemap),
+			func.name,
+			common.GetFuncParamList(func, specData.funcData.typemap, true))
+		hFile:write "{\n"
+		hFile:inc()
+		hFile:fmt('%s = (%s)%s("%s%s");\n',
+			GetFuncPtrName(func, spec, options),
+			GetFuncPtrTypedefName(func, spec, options),
+			spec.GetPtrLoaderFuncName(),
+			spec.FuncNamePrefix(),
+			func.name)
+			
+		if(common.DoesFuncReturnSomething(func, typemap)) then
+			hFile:fmt('%s(%s);\n',
+				GetFuncPtrName(func, spec, options),
+				common.GetFuncParamCallList(func, typemap))
+		else
+			hFile:fmt('return %s(%s);\n',
+				GetFuncPtrName(func, spec, options),
+				common.GetFuncParamCallList(func, typemap))
+		end
+		hFile:dec()
+		hFile:write "}\n\n"
+	end
+end
+
+local init = {}
+src.init = init
+
+function init.WriteBlockBeginStruct(hFile, spec, options)
+	hFile:write("struct InitializeVariables\n")
+	hFile:write "{\n"
+	hFile:inc()
+
+	hFile:write("InitializeVariables()\n")
+	hFile:write "{\n"
+	hFile:inc()
+end
+
+function init.WriteBlockEndStruct(hFile, spec, options)
+	hFile:dec()
+	hFile:write "}\n"
+	hFile:dec()
+	hFile:write "};\n\n"
+	hFile:write("InitializeVariables g_initVariables;\n")
+end
+
+function init.WriteFunction(hFile, func, typemap, spec, options, funcSeen)
+	hFile:fmt("%s = Switch_%s;\n", func.name, func.name)
+end
+
+
+local function Create()
+	return util.DeepCopyTable(my_style), struct
+end
+
+return { Create = Create }
+

modules/Styles.lua

 	pointer_cpp = require("PointerCPP_Style"),
 	func_cpp = require("FuncCpp_Style"),
 	noload_cpp = require("NoloadCpp_Style"),
+	noload_c = require("NoloadC_Style"),
 }
 
 local default_style = "pointer_c"

test/func_cpp_comp/test.cpp

 	unsigned int displayMode = GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH | GLUT_STENCIL;
 
 	glutInitDisplayMode(displayMode);
-	glutInitContextVersion (3, 3);
-	glutInitContextProfile(GLUT_COMPATIBILITY_PROFILE);
+	glutInitContextVersion (2, 1);
 	glutInitWindowSize (width, height); 
 	glutInitWindowPosition (300, 200);
 	glutCreateWindow (argv[0]);

test/noload_c/test.cpp

+#include <string>
+#include <exception>
+#include <stdexcept>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "gl_test.h"
+#ifdef _WIN32
+#include "wgl_test.h"
+#else
+#include "glx_test.h"
+#endif
+#include <GL/freeglut.h>
+
+GLuint positionBufferObject;
+GLuint program;
+GLuint vao;
+
+GLuint BuildShader(GLenum eShaderType, const std::string &shaderText)
+{
+	GLuint shader = glCreateShader(eShaderType);
+	const char *strFileData = shaderText.c_str();
+	glShaderSource(shader, 1, &strFileData, NULL);
+
+	glCompileShader(shader);
+
+	GLint status;
+	glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
+	if (status == GL_FALSE)
+	{
+		GLint infoLogLength;
+		glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
+
+		GLchar *strInfoLog = new GLchar[infoLogLength + 1];
+		glGetShaderInfoLog(shader, infoLogLength, NULL, strInfoLog);
+
+		const char *strShaderType = NULL;
+		switch(eShaderType)
+		{
+		case GL_VERTEX_SHADER: strShaderType = "vertex"; break;
+//		case GL_GEOMETRY_SHADER: strShaderType = "geometry"; break;
+		case GL_FRAGMENT_SHADER: strShaderType = "fragment"; break;
+		}
+
+		fprintf(stderr, "Compile failure in %s shader:\n%s\n", strShaderType, strInfoLog);
+		delete[] strInfoLog;
+
+		throw std::runtime_error("Compile failure in shader.");
+	}
+
+	return shader;
+}
+
+
+void init()
+{
+	glGenVertexArrays(1, &vao);
+	glBindVertexArray(vao);
+
+	const float vertexPositions[] = {
+		0.75f, 0.75f, 0.0f, 1.0f,
+		0.75f, -0.75f, 0.0f, 1.0f,
+		-0.75f, -0.75f, 0.0f, 1.0f,
+	};
+
+	glGenBuffers(1, &positionBufferObject);
+	glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
+	glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
+	glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+	const std::string vertexShader(
+		"#version 330\n"
+		"layout(location = 0) in vec4 position;\n"
+		"void main()\n"
+		"{\n"
+		"   gl_Position = position;\n"
+		"}\n"
+		);
+
+	const std::string fragmentShader(
+		"#version 330\n"
+		"out vec4 outputColor;\n"
+		"void main()\n"
+		"{\n"
+		"   outputColor = vec4(0.0f, 0.0f, 0.0f, 1.0f);\n"
+		"}\n"
+		);
+
+	GLuint vertShader = BuildShader(GL_VERTEX_SHADER, vertexShader);
+	GLuint fragShader = BuildShader(GL_FRAGMENT_SHADER, fragmentShader);
+
+	program = glCreateProgram();
+	glAttachShader(program, vertShader);
+	glAttachShader(program, fragShader);	
+	glLinkProgram(program);
+
+	GLint status;
+	glGetProgramiv (program, GL_LINK_STATUS, &status);
+	if (status == GL_FALSE)
+	{
+		GLint infoLogLength;
+		glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
+
+		GLchar *strInfoLog = new GLchar[infoLogLength + 1];
+		glGetProgramInfoLog(program, infoLogLength, NULL, strInfoLog);
+		fprintf(stderr, "Linker failure: %s\n", strInfoLog);
+		delete[] strInfoLog;
+
+		throw std::runtime_error("Shader could not be linked.");
+	}
+}
+
+//Called to update the display.
+//You should call glutSwapBuffers after all of your rendering to display what you rendered.
+//If you need continuous updates of the screen, call glutPostRedisplay() at the end of the function.
+void display()
+{
+	glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+	glClear(GL_COLOR_BUFFER_BIT);
+
+	glUseProgram(program);
+
+	glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
+	glEnableVertexAttribArray(0);
+	glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
+
+	glDrawArrays(GL_TRIANGLES, 0, 3);
+
+	glDisableVertexAttribArray(0);
+	glUseProgram(0);
+
+	glutSwapBuffers();
+}
+
+//Called whenever the window is resized. The new window size is given, in pixels.
+//This is an opportunity to call glViewport or GL_Scissor to keep up with the change in size.
+void reshape (int w, int h)
+{
+	glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+}
+
+//Called whenever a key on the keyboard was pressed.
+//The key is given by the ''key'' parameter, which is in ASCII.
+//It's often a good idea to have the escape key (ASCII value 27) call glutLeaveMainLoop() to 
+//exit the program.
+void keyboard(unsigned char key, int x, int y)
+{
+	switch (key)
+	{
+	case 27:
+		glutLeaveMainLoop();
+		break;
+	}
+}
+
+
+int main(int argc, char** argv)
+{
+	glutInit(&argc, argv);
+
+	int width = 500;
+	int height = 500;
+	unsigned int displayMode = GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH | GLUT_STENCIL;
+
+	glutInitDisplayMode(displayMode);
+	glutInitContextVersion (3, 3);
+	glutInitContextProfile(GLUT_CORE_PROFILE);
+	glutInitWindowSize (width, height); 
+	glutInitWindowPosition (300, 200);
+	glutCreateWindow (argv[0]);
+
+	glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
+
+	ogl_CheckExtensions();
+#ifdef _WIN32
+	wgl_CheckExtensions(wglGetCurrentDC());
+#endif
+
+	if(ogl_ext_EXT_texture_compression_s3tc)
+		printf("Yay!\n");
+	else
+		printf("Fooey.\n");
+	init();
+
+
+	glutDisplayFunc(display); 
+	glutReshapeFunc(reshape);
+	glutKeyboardFunc(keyboard);
+	glutMainLoop();
+	return 0;
+}

test/noload_c_old/test.cpp

+#include <string>
+#include <exception>
+#include <stdexcept>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "gl_test.h"
+#ifdef _WIN32
+#include "wgl_test.h"
+#else
+#include "glx_test.h"
+#endif
+#include <GL/freeglut.h>
+
+GLuint positionBufferObject;
+GLuint program;
+GLuint vao;
+
+GLuint BuildShader(GLenum eShaderType, const std::string &shaderText)
+{
+	GLuint shader = glCreateShader(eShaderType);
+	const char *strFileData = shaderText.c_str();
+	glShaderSource(shader, 1, &strFileData, NULL);
+
+	glCompileShader(shader);
+
+	GLint status;
+	glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
+	if (status == GL_FALSE)
+	{
+		GLint infoLogLength;
+		glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
+
+		GLchar *strInfoLog = new GLchar[infoLogLength + 1];
+		glGetShaderInfoLog(shader, infoLogLength, NULL, strInfoLog);
+
+		const char *strShaderType = NULL;
+		switch(eShaderType)
+		{
+		case GL_VERTEX_SHADER: strShaderType = "vertex"; break;
+//		case GL_GEOMETRY_SHADER: strShaderType = "geometry"; break;
+		case GL_FRAGMENT_SHADER: strShaderType = "fragment"; break;
+		}
+
+		fprintf(stderr, "Compile failure in %s shader:\n%s\n", strShaderType, strInfoLog);
+		delete[] strInfoLog;
+
+		throw std::runtime_error("Compile failure in shader.");
+	}
+
+	return shader;
+}
+
+
+void init()
+{
+	const float vertexPositions[] = {
+		0.75f, 0.75f, 0.0f, 1.0f,
+		0.75f, -0.75f, 0.0f, 1.0f,
+		-0.75f, -0.75f, 0.0f, 1.0f,
+	};
+
+	glGenBuffers(1, &positionBufferObject);
+	glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
+	glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
+	glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+	const std::string vertexShader(
+		"#version 330\n"
+		"layout(location = 0) in vec4 position;\n"
+		"void main()\n"
+		"{\n"
+		"   gl_Position = position;\n"
+		"}\n"
+		);
+
+	const std::string fragmentShader(
+		"#version 330\n"
+		"out vec4 outputColor;\n"
+		"void main()\n"
+		"{\n"
+		"   outputColor = vec4(0.0f, 0.0f, 0.0f, 1.0f);\n"
+		"}\n"
+		);
+
+	GLuint vertShader = BuildShader(GL_VERTEX_SHADER, vertexShader);
+	GLuint fragShader = BuildShader(GL_FRAGMENT_SHADER, fragmentShader);
+
+	program = glCreateProgram();
+	glAttachShader(program, vertShader);
+	glAttachShader(program, fragShader);	
+	glLinkProgram(program);
+
+	GLint status;
+	glGetProgramiv (program, GL_LINK_STATUS, &status);
+	if (status == GL_FALSE)
+	{
+		GLint infoLogLength;
+		glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
+
+		GLchar *strInfoLog = new GLchar[infoLogLength + 1];
+		glGetProgramInfoLog(program, infoLogLength, NULL, strInfoLog);
+		fprintf(stderr, "Linker failure: %s\n", strInfoLog);
+		delete[] strInfoLog;
+
+		throw std::runtime_error("Shader could not be linked.");
+	}
+}
+
+//Called to update the display.
+//You should call glutSwapBuffers after all of your rendering to display what you rendered.
+//If you need continuous updates of the screen, call glutPostRedisplay() at the end of the function.
+void display()
+{
+	glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+	glClear(GL_COLOR_BUFFER_BIT);
+
+	glUseProgram(program);
+
+	glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
+	glEnableVertexAttribArray(0);
+	glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
+
+	glDrawArrays(GL_TRIANGLES, 0, 3);
+
+	glDisableVertexAttribArray(0);
+	glUseProgram(0);
+
+	glutSwapBuffers();
+}
+
+//Called whenever the window is resized. The new window size is given, in pixels.
+//This is an opportunity to call glViewport or GL_Scissor to keep up with the change in size.
+void reshape (int w, int h)
+{
+	glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+}
+
+//Called whenever a key on the keyboard was pressed.
+//The key is given by the ''key'' parameter, which is in ASCII.
+//It's often a good idea to have the escape key (ASCII value 27) call glutLeaveMainLoop() to 
+//exit the program.
+void keyboard(unsigned char key, int x, int y)
+{
+	switch (key)
+	{
+	case 27:
+		glutLeaveMainLoop();
+		break;
+	}
+}
+
+
+int main(int argc, char** argv)
+{
+	glutInit(&argc, argv);
+
+	int width = 500;
+	int height = 500;
+	unsigned int displayMode = GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH | GLUT_STENCIL;
+
+	glutInitDisplayMode(displayMode);
+	glutInitContextVersion (2, 1);
+	glutInitWindowSize (width, height); 
+	glutInitWindowPosition (300, 200);
+	glutCreateWindow (argv[0]);
+
+	glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
+
+	ogl_CheckExtensions();
+#ifdef _WIN32
+	wgl_CheckExtensions(wglGetCurrentDC());
+#endif
+
+	if(ogl_ext_EXT_texture_compression_s3tc)
+		printf("Yay!\n");
+	else
+		printf("Fooey.\n");
+	init();
+
+
+	glutDisplayFunc(display); 
+	glutReshapeFunc(reshape);
+	glutKeyboardFunc(keyboard);
+	glutMainLoop();
+	return 0;
+}

test/premake4.lua

 	{name = "func_cpp_comp"},
 	{name = "noload_cpp"},
 	{name = "noload_cpp_noext"},
+	{name = "noload_c"},
+	{name = "noload_c_old"},
 }
 
 local oldDir = os.getcwd()