Removed tools used to generate the GL headers/implementations as we never use them to build
parent
001f0b10a4
commit
469f217e6b
|
@ -1,79 +0,0 @@
|
|||
|
||||
local prelims =
|
||||
{
|
||||
[[lua $<dir>MakeAllExts.lua -spec=gl $<dir>allgl.txt]],
|
||||
[[lua $<dir>MakeAllExts.lua -spec=wgl $<dir>allwgl.txt]],
|
||||
[[lua $<dir>MakeAllExts.lua -spec=glX $<dir>allglx.txt]],
|
||||
}
|
||||
|
||||
local tests =
|
||||
{
|
||||
[[lua $<dir>LoadGen.lua -spec=gl -version=4.4 -profile=core -style=pointer_cpp -stdext=gl_ubiquitous.txt $<dir>test/ptr_cpp/test]],
|
||||
[[lua $<dir>LoadGen.lua -spec=gl -version=3.3 -profile=core -style=pointer_c -stdext=gl_ubiquitous.txt $<dir>test/ptr_c/test]],
|
||||
[[lua $<dir>LoadGen.lua -spec=gl -version=3.3 -profile=core -style=func_cpp -stdext=gl_ubiquitous.txt $<dir>test/func_cpp/test]],
|
||||
[[lua $<dir>LoadGen.lua -spec=gl -version=3.3 -profile=compatibility -style=pointer_cpp -stdext=gl_ubiquitous.txt $<dir>test/ptr_cpp_comp/test]],
|
||||
[[lua $<dir>LoadGen.lua -spec=gl -version=2.1 -style=func_cpp -stdext=gl_ubiquitous.txt $<dir>test/func_cpp_comp/test]],
|
||||
[[lua $<dir>LoadGen.lua -spec=gl -version=4.4 -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]],
|
||||
[[lua $<dir>LoadGen.lua -spec=gl -version=3.3 -profile=compatibility -style=noload_c $<dir>test/noload_c_noext/test]],
|
||||
}
|
||||
|
||||
local platTests =
|
||||
{
|
||||
wgl =
|
||||
{
|
||||
[[lua $<dir>LoadGen.lua -spec=wgl -style=pointer_cpp -stdext=wgl_common.txt $<dir>test/ptr_cpp/test]],
|
||||
[[lua $<dir>LoadGen.lua -spec=wgl -style=pointer_c -stdext=wgl_common.txt $<dir>test/ptr_c/test]],
|
||||
[[lua $<dir>LoadGen.lua -spec=wgl -style=func_cpp -stdext=wgl_common.txt $<dir>test/func_cpp/test]],
|
||||
[[lua $<dir>LoadGen.lua -spec=wgl -style=pointer_cpp -stdext=wgl_common.txt $<dir>test/ptr_cpp_comp/test]],
|
||||
[[lua $<dir>LoadGen.lua -spec=wgl -style=func_cpp -stdext=wgl_common.txt $<dir>test/func_cpp_comp/test]],
|
||||
[[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]],
|
||||
[[lua $<dir>LoadGen.lua -spec=wgl -style=noload_c $<dir>test/noload_c_noext/test]],
|
||||
},
|
||||
|
||||
glX =
|
||||
{
|
||||
[[lua $<dir>LoadGen.lua -spec=glX -style=pointer_cpp -stdext=glx_common.txt $<dir>test/ptr_cpp/test]],
|
||||
[[lua $<dir>LoadGen.lua -spec=glX -style=pointer_c -stdext=glx_common.txt $<dir>test/ptr_c/test]],
|
||||
[[lua $<dir>LoadGen.lua -spec=glX -style=func_cpp -stdext=glx_common.txt $<dir>test/func_cpp/test]],
|
||||
[[lua $<dir>LoadGen.lua -spec=glX -style=pointer_cpp -stdext=glx_common.txt $<dir>test/ptr_cpp_comp/test]],
|
||||
[[lua $<dir>LoadGen.lua -spec=glX -style=func_cpp -stdext=glx_common.txt $<dir>test/func_cpp_comp/test]],
|
||||
[[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]],
|
||||
[[lua $<dir>LoadGen.lua -spec=glX -style=noload_c $<dir>test/noload_c_noext/test]],
|
||||
},
|
||||
}
|
||||
|
||||
local glXTests = {}
|
||||
|
||||
local baseDir = arg[0]:match("^(.*[\\/])")
|
||||
baseDir = baseDir or "./"
|
||||
|
||||
local function ExecTests(testList)
|
||||
for _, test in ipairs(testList) do
|
||||
test = test:gsub("%$<dir>", baseDir)
|
||||
print(test)
|
||||
os.execute(test)
|
||||
end
|
||||
end
|
||||
|
||||
if(arg[1]) then
|
||||
assert(platTests[arg[1]], "Invalid platform " .. arg[1])
|
||||
end
|
||||
|
||||
ExecTests(prelims)
|
||||
ExecTests(tests)
|
||||
if(arg[1]) then
|
||||
ExecTests(platTests[arg[1]])
|
||||
end
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
|
||||
Copyright (C) 2011-2013 by Jason L. McKesson
|
||||
|
||||
The source code in this distribution is licensed under the terms of the MIT license, as stated below. The source code generated by this tool is yours to do with as you will.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
|
@ -1,65 +0,0 @@
|
|||
assert(arg and arg[0], "You ran this script incorrectly.")
|
||||
|
||||
--Get the location of our modules relative to here.
|
||||
local baseDir = arg[0]:match("^(.*[\\/])")
|
||||
baseDir = baseDir or "./"
|
||||
assert(baseDir, arg[0] .. " No directory")
|
||||
|
||||
--Fixup the package path to be relative to this directory.
|
||||
package.path = baseDir .. "modules/?.lua;" .. package.path
|
||||
|
||||
--Make a function to get the correct directory name.
|
||||
function SysRelPath(relativePath)
|
||||
return baseDir .. relativePath
|
||||
end
|
||||
FixupPath = SysRelPath --Older name.
|
||||
|
||||
local opts = require "GetOptions"
|
||||
local Specs = require "Specs"
|
||||
local Styles = require "Styles"
|
||||
local LoadSpec = require "LoadLuaSpec"
|
||||
local util = require "util"
|
||||
|
||||
--Get the options.
|
||||
local status, options = pcall(opts.GetOptions, arg)
|
||||
|
||||
if(not status) then
|
||||
io.stdout:write(options, "\n")
|
||||
return
|
||||
end
|
||||
|
||||
--Load the spec data.
|
||||
local spec = Specs.GetSpec(options.spec)
|
||||
local specData = spec.LoadSpec()
|
||||
|
||||
--Verify that every extension in `options.extensions` is a real extension.
|
||||
local badExts = {}
|
||||
for _, extName in ipairs(options.extensions) do
|
||||
if(not specData.extdefs[extName]) then
|
||||
badExts[#badExts + 1] = extName
|
||||
end
|
||||
end
|
||||
|
||||
if(#badExts > 0) then
|
||||
io.stdout:write("The following extensions are not in the spec ", options.spec, ":\n")
|
||||
for _, extName in ipairs(badExts) do
|
||||
io.stdout:write("\t", extName, "\n")
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
--Extract the path and base-filename from the filename.
|
||||
local simplename, dir = util.ParsePath(options.outname)
|
||||
dir = dir or "./"
|
||||
|
||||
assert(simplename,
|
||||
"There is no filename in the path '" .. options.outname .. "'")
|
||||
|
||||
local style, structure = Styles.GetStyle(options.style)
|
||||
|
||||
--Compute the filename, minus style-specific suffix.
|
||||
local basename = dir .. spec:FilePrefix() .. simplename
|
||||
|
||||
structure.Proc(basename, style, specData, spec, options)
|
||||
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
assert(arg and arg[0], "You ran this script incorrectly.")
|
||||
|
||||
--Get the location of our modules relative to here.
|
||||
local baseDir = arg[0]:match("^(.*[\\/])")
|
||||
baseDir = baseDir or "./"
|
||||
|
||||
--Fixup the package path to be relative to this directory.
|
||||
package.path = baseDir .. "modules/?.lua;" .. package.path
|
||||
|
||||
--Make a function to get the correct directory name.
|
||||
function SysRelPath(relativePath)
|
||||
return baseDir .. relativePath
|
||||
end
|
||||
FixupPath = SysRelPath --Older name.
|
||||
|
||||
local cmd = require "CmdLineOptions"
|
||||
local Specs = require "Specs"
|
||||
|
||||
local parseOpts = cmd.CreateOptionGroup()
|
||||
parseOpts:enum(
|
||||
"spec",
|
||||
"spec",
|
||||
"Specification to use.",
|
||||
{"gl", "glX", "wgl"})
|
||||
parseOpts:pos_opt(
|
||||
1,
|
||||
"outname",
|
||||
"Output filename to generate.",
|
||||
"outname")
|
||||
|
||||
local options, pos_args = parseOpts:ProcessCmdLine(arg)
|
||||
|
||||
local dups = {}
|
||||
local exts = {}
|
||||
|
||||
local spec = Specs.GetSpec(options.spec)
|
||||
local specData = spec.LoadSpec()
|
||||
|
||||
local coreExts = spec.GetCoreExts()
|
||||
|
||||
for _, version in ipairs(specData.versions or {}) do
|
||||
if(coreExts[version]) then
|
||||
for _, extName in ipairs(coreExts[version]) do
|
||||
if(not dups[extName]) then
|
||||
exts[#exts + 1] = extName
|
||||
dups[extName] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local sortExts = {}
|
||||
|
||||
for _, extName in ipairs(specData.extensions) do
|
||||
if(not dups[extName]) then
|
||||
sortExts[#sortExts + 1] = extName
|
||||
dups[extName] = true
|
||||
end
|
||||
end
|
||||
|
||||
table.sort(sortExts)
|
||||
|
||||
local hFile = io.open(options.outname, "w")
|
||||
for _, extName in ipairs(exts) do
|
||||
hFile:write(extName, "\n")
|
||||
end
|
||||
for _, extName in ipairs(sortExts) do
|
||||
hFile:write(extName, "\n")
|
||||
end
|
||||
hFile:close()
|
||||
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
glLoadGenerator, version 1.0
|
||||
|
||||
|
||||
Please see the documentation available on the web at https://bitbucket.org/alfonse/glloadgen/wiki/Home for detailed information on how to use this software.
|
||||
|
||||
The license for this distribution is available in the `License.txt` file.
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
This loader generation system is used to create OpenGL headers and loading code for your specific needs. Rather than getting every extension and core enumerator/function all in one massive header, you get only what you actually want and ask for.
|
||||
|
||||
The scripts in this package are licensed under the terms of the MIT License. You will need to have Lua installed for this to work.
|
||||
|
||||
To use the code generator, with Lua in your path (assuming that "lua" is the name of your Lua executable), type this:
|
||||
|
||||
lua LoadGen.lua -style=pointer_c -spec=gl -version=3.3 -profile=core core_3_3
|
||||
|
||||
This tells the system to generate a header/source pair for OpenGL ("-spec=gl", as opposed to WGL or GLX), for version 3.3, the core profile. It will generate it in the "pointer_c" style, which means that it will use function pointer-style, with C linkage and source files. Such code is usable from C and C++, or other languages that can interface with C.
|
||||
|
||||
The option "core_3_3" is the basic component of the filename that will be used for the generation. Since it is generating OpenGL loaders (again, as opposed to WGL or GLX), it will generate files named "gl_core_3_3.*", where * is the extension used by the particular style.
|
||||
|
||||
The above command line will generate "gl_core_3_3.h" and "gl_core_3_3.c" files. Simply include them in your project; there is no library to build, no unresolved extenals to filter through. They just work.
|
||||
|
||||
Changes
|
||||
-------
|
||||
|
||||
Version 1.0:
|
||||
* New Noload loader. Works like GLee.
|
||||
* -stdext now works relative to the extfiles directory, not just LoadGen. So no need to do -stdext=extfiles/gl_name_of_standard_file.txt.
|
||||
* A test suite.
|
||||
* Lua Filesystem is now in use; if it's not available, then you must create the destination directory yourself.
|
||||
|
||||
Version 0.3:
|
||||
* Replaced the old generation system with a flexible structure system.
|
||||
* Migrated the styles to the structure system.
|
|
@ -1,21 +0,0 @@
|
|||
|
||||
require("ex")
|
||||
require "ufs"
|
||||
|
||||
function FindFileInPath(filename)
|
||||
local path = ex.getenv("PATH");
|
||||
|
||||
for pathname in path:gmatch("([^%;%\"]+)%;?") do
|
||||
pathname = ufs.path(pathname);
|
||||
|
||||
local testName = pathname / filename;
|
||||
|
||||
if(ufs.exists(testName)) then
|
||||
return tostring(testName);
|
||||
end
|
||||
end
|
||||
|
||||
return nil;
|
||||
end
|
||||
|
||||
|
|
@ -1,116 +0,0 @@
|
|||
--[[ This function returns a table of core extensions and the versions they were made core in.
|
||||
|
||||
The table is indexed by version number (as a string). In each version is an array of extension names.
|
||||
|
||||
This list must be manually updated, as there is no equivalent in the spec files. Just add to the list. When a new version comes out with new core extensions, add a new list and add the local variable name to the master table as shown below.
|
||||
]]
|
||||
|
||||
local coreExts1_2 = {
|
||||
"ARB_imaging",
|
||||
};
|
||||
|
||||
local coreExts3_0 = {
|
||||
"ARB_vertex_array_object",
|
||||
"ARB_texture_rg",
|
||||
"ARB_texture_compression_rgtc",
|
||||
"ARB_map_buffer_range",
|
||||
"ARB_half_float_vertex",
|
||||
"ARB_framebuffer_sRGB",
|
||||
"ARB_framebuffer_object",
|
||||
"ARB_depth_buffer_float",
|
||||
};
|
||||
|
||||
local coreExts3_1 = {
|
||||
"ARB_uniform_buffer_object",
|
||||
"ARB_copy_buffer",
|
||||
};
|
||||
|
||||
local coreExts3_2 = {
|
||||
"ARB_depth_clamp",
|
||||
"ARB_draw_elements_base_vertex",
|
||||
"ARB_fragment_coord_conventions",
|
||||
"ARB_provoking_vertex",
|
||||
"ARB_seamless_cube_map",
|
||||
"ARB_sync",
|
||||
"ARB_texture_multisample",
|
||||
"ARB_vertex_array_bgra",
|
||||
};
|
||||
|
||||
local coreExts3_3 = {
|
||||
"ARB_texture_rgb10_a2ui",
|
||||
"ARB_texture_swizzle",
|
||||
"ARB_timer_query",
|
||||
"ARB_vertex_type_2_10_10_10_rev",
|
||||
"ARB_blend_func_extended",
|
||||
"ARB_occlusion_query2",
|
||||
"ARB_sampler_objects",
|
||||
};
|
||||
|
||||
local coreExts4_0 = {
|
||||
"ARB_draw_indirect",
|
||||
"ARB_gpu_shader5",
|
||||
"ARB_gpu_shader_fp64",
|
||||
"ARB_shader_subroutine",
|
||||
"ARB_tessellation_shader",
|
||||
"ARB_transform_feedback2",
|
||||
"ARB_transform_feedback3",
|
||||
};
|
||||
|
||||
local coreExts4_1 = {
|
||||
"ARB_ES2_compatibility",
|
||||
"ARB_get_program_binary",
|
||||
"ARB_separate_shader_objects",
|
||||
"ARB_vertex_attrib_64bit",
|
||||
"ARB_viewport_array",
|
||||
};
|
||||
|
||||
local coreExts4_2 = {
|
||||
"ARB_base_instance",
|
||||
"ARB_shading_language_420pack",
|
||||
"ARB_transform_feedback_instanced",
|
||||
"ARB_compressed_texture_pixel_storage",
|
||||
"ARB_conservative_depth",
|
||||
"ARB_internalformat_query",
|
||||
"ARB_map_buffer_alignment",
|
||||
"ARB_shader_atomic_counters",
|
||||
"ARB_shader_image_load_store",
|
||||
"ARB_shading_language_packing",
|
||||
"ARB_texture_storage",
|
||||
};
|
||||
|
||||
local coreExts4_3 = {
|
||||
"KHR_debug",
|
||||
"ARB_arrays_of_arrays",
|
||||
"ARB_clear_buffer_object",
|
||||
"ARB_compute_shader",
|
||||
"ARB_copy_image",
|
||||
"ARB_ES3_compatibility",
|
||||
"ARB_explicit_uniform_location",
|
||||
"ARB_fragment_layer_viewport",
|
||||
"ARB_framebuffer_no_attachments",
|
||||
"ARB_internalformat_query2",
|
||||
"ARB_invalidate_subdata",
|
||||
"ARB_multi_draw_indirect",
|
||||
"ARB_program_interface_query",
|
||||
"ARB_shader_image_size",
|
||||
"ARB_shader_storage_buffer_object",
|
||||
"ARB_stencil_texturing",
|
||||
"ARB_texture_buffer_range",
|
||||
"ARB_texture_query_levels",
|
||||
"ARB_texture_storage_multisample",
|
||||
"ARB_texture_view",
|
||||
"ARB_vertex_attrib_binding",
|
||||
};
|
||||
|
||||
return {
|
||||
["1.2"] = coreExts1_2,
|
||||
["3.0"] = coreExts3_0,
|
||||
["3.1"] = coreExts3_1,
|
||||
["3.2"] = coreExts3_2,
|
||||
["3.3"] = coreExts3_3,
|
||||
["4.0"] = coreExts4_0,
|
||||
["4.1"] = coreExts4_1,
|
||||
["4.2"] = coreExts4_2,
|
||||
["4.3"] = coreExts4_3,
|
||||
};
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
return {
|
||||
"1.0",
|
||||
"1.1",
|
||||
"1.2",
|
||||
"1.3",
|
||||
"1.4",
|
||||
"1.5",
|
||||
"2.0",
|
||||
"2.1",
|
||||
"3.0",
|
||||
"3.1",
|
||||
"3.2",
|
||||
"3.3",
|
||||
"4.0",
|
||||
"4.1",
|
||||
"4.2",
|
||||
"4.3",
|
||||
"4.4",
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
--Initialization text for the 'gl' spec header.
|
||||
|
||||
return [[
|
||||
#if defined(__glew_h__) || defined(__GLEW_H__)
|
||||
#error Attempt to include auto-generated header after including glew.h
|
||||
#endif
|
||||
#if defined(__gl_h_) || defined(__GL_H__)
|
||||
#error Attempt to include auto-generated header after including gl.h
|
||||
#endif
|
||||
#if defined(__glext_h_) || defined(__GLEXT_H_)
|
||||
#error Attempt to include auto-generated header after including glext.h
|
||||
#endif
|
||||
#if defined(__gltypes_h_)
|
||||
#error Attempt to include auto-generated header after gltypes.h
|
||||
#endif
|
||||
#if defined(__gl_ATI_h_)
|
||||
#error Attempt to include auto-generated header after including glATI.h
|
||||
#endif
|
||||
|
||||
#define __glew_h__
|
||||
#define __GLEW_H__
|
||||
#define __gl_h_
|
||||
#define __GL_H__
|
||||
#define __glext_h_
|
||||
#define __GLEXT_H_
|
||||
#define __gltypes_h_
|
||||
#define __gl_ATI_h_
|
||||
|
||||
#ifndef APIENTRY
|
||||
#if defined(__MINGW32__)
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#elif (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) || defined(__BORLANDC__)
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#else
|
||||
#define APIENTRY
|
||||
#endif
|
||||
#endif /*APIENTRY*/
|
||||
|
||||
#ifndef CODEGEN_FUNCPTR
|
||||
#define CODEGEN_REMOVE_FUNCPTR
|
||||
#if defined(_WIN32)
|
||||
#define CODEGEN_FUNCPTR APIENTRY
|
||||
#else
|
||||
#define CODEGEN_FUNCPTR
|
||||
#endif
|
||||
#endif /*CODEGEN_FUNCPTR*/
|
||||
|
||||
#ifndef GLAPI
|
||||
#define GLAPI extern
|
||||
#endif
|
||||
|
||||
]]
|
|
@ -1,96 +0,0 @@
|
|||
--[[ The function pointer loading function takes a string and returns either NULL or a valid pointer. It is the responsibility of the loader to take care of any platform-specific oddities in pointer fetching.
|
||||
]]
|
||||
|
||||
return [====[
|
||||
#if defined(__APPLE__)
|
||||
#include <mach-o/dyld.h>
|
||||
|
||||
static void* AppleGLGetProcAddress (const GLubyte *name)
|
||||
{
|
||||
static const struct mach_header* image = NULL;
|
||||
NSSymbol symbol;
|
||||
char* symbolName;
|
||||
if (NULL == image)
|
||||
{
|
||||
image = NSAddImage("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", NSADDIMAGE_OPTION_RETURN_ON_ERROR);
|
||||
}
|
||||
/* prepend a '_' for the Unix C symbol mangling convention */
|
||||
symbolName = malloc(strlen((const char*)name) + 2);
|
||||
strcpy(symbolName+1, (const char*)name);
|
||||
symbolName[0] = '_';
|
||||
symbol = NULL;
|
||||
/* if (NSIsSymbolNameDefined(symbolName))
|
||||
symbol = NSLookupAndBindSymbol(symbolName); */
|
||||
symbol = image ? NSLookupSymbolInImage(image, symbolName, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR) : NULL;
|
||||
free(symbolName);
|
||||
return symbol ? NSAddressOfSymbol(symbol) : NULL;
|
||||
}
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
#if defined(__sgi) || defined (__sun)
|
||||
#include <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static void* SunGetProcAddress (const GLubyte* name)
|
||||
{
|
||||
static void* h = NULL;
|
||||
static void* gpa;
|
||||
|
||||
if (h == NULL)
|
||||
{
|
||||
if ((h = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL)) == NULL) return NULL;
|
||||
gpa = dlsym(h, "glXGetProcAddress");
|
||||
}
|
||||
|
||||
if (gpa != NULL)
|
||||
return ((void*(*)(const GLubyte*))gpa)(name);
|
||||
else
|
||||
return dlsym(h, (const char*)name);
|
||||
}
|
||||
#endif /* __sgi || __sun */
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable: 4055)
|
||||
#pragma warning(disable: 4054)
|
||||
#endif
|
||||
|
||||
static int TestPointer(const PROC pTest)
|
||||
{
|
||||
ptrdiff_t iTest;
|
||||
if(!pTest) return 0;
|
||||
iTest = (ptrdiff_t)pTest;
|
||||
|
||||
if(iTest == 1 || iTest == 2 || iTest == 3 || iTest == -1) return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static PROC WinGetProcAddress(const char *name)
|
||||
{
|
||||
HMODULE glMod = NULL;
|
||||
PROC pFunc = wglGetProcAddress((LPCSTR)name);
|
||||
if(TestPointer(pFunc))
|
||||
{
|
||||
return pFunc;
|
||||
}
|
||||
glMod = GetModuleHandleA("OpenGL32.dll");
|
||||
return (PROC)GetProcAddress(glMod, (LPCSTR)name);
|
||||
}
|
||||
|
||||
#define IntGetProcAddress(name) WinGetProcAddress(name)
|
||||
#else
|
||||
#if defined(__APPLE__)
|
||||
#define IntGetProcAddress(name) AppleGLGetProcAddress(name)
|
||||
#else
|
||||
#if defined(__sgi) || defined(__sun)
|
||||
#define IntGetProcAddress(name) SunGetProcAddress(name)
|
||||
#else /* GLX */
|
||||
#include <GL/glx.h>
|
||||
|
||||
#define IntGetProcAddress(name) (*glXGetProcAddressARB)((const GLubyte*)name)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
]====]
|
|
@ -1,17 +0,0 @@
|
|||
return {
|
||||
"1.1",
|
||||
"1.2",
|
||||
"1.3",
|
||||
"1.4",
|
||||
"1.5",
|
||||
"2.0",
|
||||
"2.1",
|
||||
"3.0",
|
||||
"3.1",
|
||||
"3.2",
|
||||
"3.3",
|
||||
"4.0",
|
||||
"4.1",
|
||||
"4.2",
|
||||
"4.3",
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
return {}
|
|
@ -1 +0,0 @@
|
|||
return {}
|
|
@ -1,39 +0,0 @@
|
|||
--Initialization text for the 'glX' spec header.
|
||||
|
||||
return [[
|
||||
#ifdef __glxext_h_
|
||||
#error Attempt to include glx_exts after including glxext.h
|
||||
#endif
|
||||
|
||||
#define __glxext_h_
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <GL/glx.h>
|
||||
#ifdef CODEGEN_FUNCPTR
|
||||
#undef CODEGEN_FUNCPTR
|
||||
#endif /*CODEGEN_FUNCPTR*/
|
||||
#define CODEGEN_FUNCPTR
|
||||
|
||||
#ifndef GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS
|
||||
#define GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS
|
||||
|
||||
typedef unsigned int GLenum;
|
||||
typedef unsigned char GLboolean;
|
||||
typedef unsigned int GLbitfield;
|
||||
typedef signed char GLbyte;
|
||||
typedef short GLshort;
|
||||
typedef int GLint;
|
||||
typedef int GLsizei;
|
||||
typedef unsigned char GLubyte;
|
||||
typedef unsigned short GLushort;
|
||||
typedef unsigned int GLuint;
|
||||
typedef float GLfloat;
|
||||
typedef float GLclampf;
|
||||
typedef double GLdouble;
|
||||
typedef double GLclampd;
|
||||
#define GLvoid void
|
||||
|
||||
#endif /*GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS*/
|
||||
|
||||
]]
|
|
@ -1,2 +0,0 @@
|
|||
return assert(dofile("data/gl_specloaderfunc.lua"))
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
--Initialization text for the 'glX' spec header.
|
||||
|
||||
return {}
|
|
@ -1,21 +0,0 @@
|
|||
-- Returns an array of strings, for proper indenting and such.
|
||||
|
||||
return {
|
||||
--[[
|
||||
"typedef unsigned int GLenum;\n",
|
||||
"typedef unsigned char GLboolean;\n",
|
||||
"typedef unsigned int GLbitfield;\n",
|
||||
"typedef signed char GLbyte;\n",
|
||||
"typedef short GLshort;\n",
|
||||
"typedef int GLint;\n",
|
||||
"typedef int GLsizei;\n",
|
||||
"typedef unsigned char GLubyte;\n",
|
||||
"typedef unsigned short GLushort;\n",
|
||||
"typedef unsigned int GLuint;\n",
|
||||
"typedef float GLfloat;\n",
|
||||
"typedef float GLclampf;\n",
|
||||
"typedef double GLdouble;\n",
|
||||
"typedef double GLclampd;\n",
|
||||
"#define GLvoid void\n",
|
||||
]]
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
return {}
|
|
@ -1 +0,0 @@
|
|||
return {}
|
|
@ -1,44 +0,0 @@
|
|||
--Initialization text for the 'wgl' spec header.
|
||||
|
||||
return [[
|
||||
#ifdef __wglext_h_
|
||||
#error Attempt to include auto-generated WGL header after wglext.h
|
||||
#endif
|
||||
|
||||
#define __wglext_h_
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef CODEGEN_FUNCPTR
|
||||
#undef CODEGEN_FUNCPTR
|
||||
#endif /*CODEGEN_FUNCPTR*/
|
||||
#define CODEGEN_FUNCPTR WINAPI
|
||||
|
||||
#ifndef GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS
|
||||
#define GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS
|
||||
|
||||
typedef unsigned int GLenum;
|
||||
typedef unsigned char GLboolean;
|
||||
typedef unsigned int GLbitfield;
|
||||
typedef signed char GLbyte;
|
||||
typedef short GLshort;
|
||||
typedef int GLint;
|
||||
typedef int GLsizei;
|
||||
typedef unsigned char GLubyte;
|
||||
typedef unsigned short GLushort;
|
||||
typedef unsigned int GLuint;
|
||||
typedef float GLfloat;
|
||||
typedef float GLclampf;
|
||||
typedef double GLdouble;
|
||||
typedef double GLclampd;
|
||||
#define GLvoid void
|
||||
|
||||
#endif /*GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS*/
|
||||
|
||||
]]
|
|
@ -1 +0,0 @@
|
|||
return assert(dofile("data/gl_specloaderfunc.lua"))
|
|
@ -1,2 +0,0 @@
|
|||
|
||||
return {}
|
|
@ -1,7 +0,0 @@
|
|||
--ARB extensions implemented on 3.3 hardware by AMD.
|
||||
|
||||
ARB_transform_feedback2
|
||||
ARB_transform_feedback3
|
||||
ARB_texture_buffer_object_rgb32
|
||||
ARB_shader_precision
|
||||
ARB_draw_buffers_blend
|
|
@ -1,37 +0,0 @@
|
|||
--Core extensions frequently provided for 3.3-class hardware, yet aren't part of core 3.3.
|
||||
--The extensions were added after 3.3 and there was no 3.4 to drop them into.
|
||||
|
||||
ARB_compressed_texture_pixel_storage
|
||||
ARB_conservative_depth
|
||||
ARB_ES2_compatibility
|
||||
ARB_get_program_binary
|
||||
ARB_explicit_uniform_location
|
||||
ARB_internalformat_query
|
||||
ARB_internalformat_query2
|
||||
ARB_map_buffer_alignment
|
||||
ARB_program_interface_query
|
||||
ARB_separate_shader_objects
|
||||
ARB_shading_language_420pack
|
||||
ARB_shading_language_packing
|
||||
ARB_texture_buffer_range
|
||||
ARB_texture_storage
|
||||
ARB_texture_view
|
||||
ARB_vertex_attrib_binding
|
||||
ARB_viewport_array
|
||||
ARB_arrays_of_arrays
|
||||
ARB_clear_buffer_object
|
||||
ARB_copy_image
|
||||
ARB_ES3_compatibility
|
||||
ARB_explicit_uniform_location
|
||||
ARB_fragment_layer_viewport
|
||||
ARB_framebuffer_no_attachments
|
||||
ARB_invalidate_subdata
|
||||
ARB_program_interface_query
|
||||
ARB_robust_buffer_access_behavior
|
||||
ARB_stencil_texturing
|
||||
ARB_texture_buffer_range
|
||||
ARB_texture_query_levels
|
||||
ARB_texture_storage_multisample
|
||||
ARB_texture_view
|
||||
ARB_vertex_attrib_binding
|
||||
KHR_debug
|
|
@ -1,18 +0,0 @@
|
|||
-- All of the extensions supported by core 3.2 in MacOSX.
|
||||
|
||||
ARB_instanced_arrays
|
||||
ARB_occlusion_query2
|
||||
ARB_shader_bit_encoding
|
||||
ARB_timer_query
|
||||
EXT_depth_bounds_test
|
||||
EXT_framebuffer_multisample_blit_scaled
|
||||
EXT_texture_compression_s3tc
|
||||
EXT_texture_filter_anisotropic
|
||||
EXT_texture_mirror_clamp
|
||||
EXT_texture_sRGB_decode
|
||||
APPLE_client_storage
|
||||
--APPLE_container_object_shareable
|
||||
APPLE_object_purgeable
|
||||
APPLE_rgb_422
|
||||
APPLE_row_bytes
|
||||
APPLE_texture_range
|
|
@ -1,7 +0,0 @@
|
|||
ARB_framebuffer_object
|
||||
ARB_seamless_cube_map
|
||||
ARB_separate_shader_objects
|
||||
ARB_debug_output
|
||||
ARB_copy_image
|
||||
NV_copy_image
|
||||
EXT_texture_mirror_clamp
|
|
@ -1,5 +0,0 @@
|
|||
-- Platform-specific non-core extensions that provide access to hardware features.
|
||||
-- These extensions are fairly widely implemented.
|
||||
|
||||
NV_texture_barrier
|
||||
NV_copy_image
|
|
@ -1,6 +0,0 @@
|
|||
--Extensions that are *widely* available and vital for basic functionality.
|
||||
--IE: things that should be core, but aren't.
|
||||
|
||||
EXT_texture_compression_s3tc
|
||||
EXT_texture_sRGB
|
||||
EXT_texture_filter_anisotropic
|
|
@ -1,13 +0,0 @@
|
|||
ARB_create_context
|
||||
ARB_create_context_profile
|
||||
ARB_create_context_robustness
|
||||
ARB_fbconfig_float
|
||||
ARB_framebuffer_sRGB
|
||||
ARB_multisample
|
||||
EXT_create_context_es2_profile
|
||||
EXT_fbconfig_packed_float
|
||||
EXT_framebuffer_sRGB
|
||||
EXT_import_context
|
||||
EXT_swap_control
|
||||
EXT_swap_control_tear
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
AMD_gpu_association
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
NV_present_video
|
||||
NV_video_output
|
||||
NV_gpu_affinity
|
||||
NV_video_capture
|
||||
NV_copy_image
|
||||
NV_multisample_coverage
|
||||
NV_DX_interop
|
||||
NV_DX_interop2
|
|
@ -1,13 +0,0 @@
|
|||
ARB_multisample
|
||||
ARB_extensions_string
|
||||
ARB_pixel_format
|
||||
ARB_pixel_format_float
|
||||
ARB_framebuffer_sRGB
|
||||
ARB_create_context
|
||||
ARB_create_context_profile
|
||||
ARB_create_context_robustness
|
||||
EXT_swap_control
|
||||
EXT_pixel_format_packed_float
|
||||
EXT_create_context_es2_profile
|
||||
EXT_swap_control_tear
|
||||
NV_swap_group
|
|
@ -4,27 +4,16 @@
|
|||
#include "gl_obs.h"
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <mach-o/dyld.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
static void* AppleGLGetProcAddress (const GLubyte *name)
|
||||
static void* AppleGLGetProcAddress (const char *name)
|
||||
{
|
||||
static const struct mach_header* image = NULL;
|
||||
NSSymbol symbol;
|
||||
char* symbolName;
|
||||
if (NULL == image)
|
||||
{
|
||||
image = NSAddImage("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", NSADDIMAGE_OPTION_RETURN_ON_ERROR);
|
||||
}
|
||||
/* prepend a '_' for the Unix C symbol mangling convention */
|
||||
symbolName = malloc(strlen((const char*)name) + 2);
|
||||
strcpy(symbolName+1, (const char*)name);
|
||||
symbolName[0] = '_';
|
||||
symbol = NULL;
|
||||
/* if (NSIsSymbolNameDefined(symbolName))
|
||||
symbol = NSLookupAndBindSymbol(symbolName); */
|
||||
symbol = image ? NSLookupSymbolInImage(image, symbolName, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR) : NULL;
|
||||
free(symbolName);
|
||||
return symbol ? NSAddressOfSymbol(symbol) : NULL;
|
||||
static void* image = NULL;
|
||||
|
||||
if (image == NULL)
|
||||
image = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
|
||||
|
||||
return (image ? dlsym(image, name) : NULL);
|
||||
}
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -4,27 +4,16 @@
|
|||
#include "glx_obs.h"
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <mach-o/dyld.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
static void* AppleGLGetProcAddress (const GLubyte *name)
|
||||
static void* AppleGLGetProcAddress (const char *name)
|
||||
{
|
||||
static const struct mach_header* image = NULL;
|
||||
NSSymbol symbol;
|
||||
char* symbolName;
|
||||
if (NULL == image)
|
||||
{
|
||||
image = NSAddImage("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", NSADDIMAGE_OPTION_RETURN_ON_ERROR);
|
||||
}
|
||||
/* prepend a '_' for the Unix C symbol mangling convention */
|
||||
symbolName = malloc(strlen((const char*)name) + 2);
|
||||
strcpy(symbolName+1, (const char*)name);
|
||||
symbolName[0] = '_';
|
||||
symbol = NULL;
|
||||
/* if (NSIsSymbolNameDefined(symbolName))
|
||||
symbol = NSLookupAndBindSymbol(symbolName); */
|
||||
symbol = image ? NSLookupSymbolInImage(image, symbolName, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR) : NULL;
|
||||
free(symbolName);
|
||||
return symbol ? NSAddressOfSymbol(symbol) : NULL;
|
||||
static void* image = NULL;
|
||||
|
||||
if (image == NULL)
|
||||
image = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
|
||||
|
||||
return (image ? dlsym(image, name) : NULL);
|
||||
}
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
|
|
|
@ -1,80 +0,0 @@
|
|||
--[[
|
||||
Will automatically generate all files from the current sources.
|
||||
Takes three parameters:
|
||||
- The destination directory, as a relative directory. This will create that directory and put the distro in that directory
|
||||
- The Mercurial revision number to archive to the destination directory.
|
||||
- The version number of the loader.
|
||||
]]--
|
||||
|
||||
require "lfs"
|
||||
require "ufs"
|
||||
require "_FindFileInPath"
|
||||
|
||||
local baseDir, hgChangelist, versionNum = ...
|
||||
|
||||
if(#({...}) ~= 3) then
|
||||
print("Not enough commandline parameters. You provided: " .. #({...}));
|
||||
print("Paramters:")
|
||||
print("\tDestination dir, relative to this path.")
|
||||
print("\tMercurial revision to archive.")
|
||||
print("\tVersion number of the SDK.")
|
||||
return
|
||||
end
|
||||
|
||||
local buildDirname = "glLoadGen_" .. versionNum:gsub("%.", "_")
|
||||
|
||||
lfs.mkdir(baseDir);
|
||||
local pathDestDir = ufs.path(baseDir) / buildDirname;
|
||||
local destDir = tostring(pathDestDir);
|
||||
lfs.mkdir(destDir);
|
||||
|
||||
local pathCurrent = ufs.current_path()
|
||||
local pathDest = pathCurrent / destDir;
|
||||
local pathBase = pathCurrent / baseDir;
|
||||
|
||||
-----------------------------------------------------------
|
||||
-- Step 1: Copy the Mercurial repo number to the location.
|
||||
|
||||
local clone = [[hg archive -r "%s" "%s"]];
|
||||
clone = clone:format(hgChangelist, destDir);
|
||||
|
||||
print(clone);
|
||||
os.execute(clone);
|
||||
|
||||
------------------------------------------------------------
|
||||
-- Step 2: Delete select files from the destination location.
|
||||
local toDelete =
|
||||
{
|
||||
--files
|
||||
"make_distro.lua", ".hgignore", ".hgtags",
|
||||
"_FindFileInPath.lua", ".hg_archival.txt",
|
||||
--directories
|
||||
}
|
||||
|
||||
|
||||
for i, filename in ipairs(toDelete) do
|
||||
local pathFile = pathDest / filename;
|
||||
print("deleting:", pathFile);
|
||||
ufs.remove_all(pathFile);
|
||||
end
|
||||
|
||||
------------------------------------------------------------
|
||||
-- Step 3: Create Zip archive of the distro.
|
||||
local szFilename = "7z.exe"
|
||||
local archiveName = buildDirname .. ".7z"
|
||||
local pathSZ = ufs.path(FindFileInPath(szFilename))
|
||||
|
||||
if(pathSZ:empty()) then
|
||||
print("Could not find 7zip.");
|
||||
return;
|
||||
end
|
||||
|
||||
ufs.current_path(pathBase);
|
||||
|
||||
local depProc = ex.spawn(tostring(pathSZ),
|
||||
{args={"a", "-r", archiveName, buildDirname}});
|
||||
depProc:wait(depProc);
|
||||
|
||||
------------------------------------------------------------
|
||||
-- Step 4: Destroy the directory.
|
||||
ufs.remove_all(pathDest);
|
|
@ -1,387 +0,0 @@
|
|||
--[[ The function CmdLineOptions takes the command-line options and processes them according to a series of functions it is given. It can handle any options of the standard forms, such as:
|
||||
|
||||
- "-optName param"
|
||||
- "--optName option1 option2 option3"
|
||||
- "-optName=param"
|
||||
|
||||
It takes the following parameters:
|
||||
- An array of command-line options as strings.
|
||||
- A table of functions, where the key name matches the options. Note that the match will be case-sensitive.
|
||||
- A value to be passed to the functions. This allows them to be a bit more independent without having to use upvalue tricks.
|
||||
|
||||
The return value is a list of any positional arguments, in order.
|
||||
|
||||
The option processor functions take the following parameters:
|
||||
- The value to be passed to the processor. A candidate for a `self` parameter.
|
||||
- The first parameter string of the option, if any.
|
||||
- A nullary iterator function to iterate over all of the options associated with the command. It can have 0 iterations. It is OK to iterate multiple times. The iterator returns two values: the parameter and the parameter's 1-base index.
|
||||
|
||||
The return value from the processing function is the number of options processed. If `nil` is returned, then it is assumed that *all* available options were processed.
|
||||
|
||||
The processor functions are called within a `pcall`, so any errors will be assumed to be processing errors related to that option. Appropriate error messages will be emitted mentioning the option name, so it doesn't need to keep its own name. It is up to each processor to decide if it has enough or too many parameters and error out if it does. Processing of command line options will error if there is a failure.
|
||||
|
||||
The processor assumes that strings that begin with a `-` character is an option. If a parameter is specified with the `-option=param` syntax, then it is assumed to have exactly one parameter. Thus the next value is assumed to be an option. For all other option formats, the number of processed arguments is decided upon by the processing function. If it returns `nil`, then it assumes all arguments were processed.
|
||||
|
||||
Any "options" that do not conform to option syntax are assumed to be positional arguments. They are stored in an array and returned by the function.
|
||||
]]
|
||||
|
||||
local util = require "util"
|
||||
|
||||
--Returns nil if not an option. Otherwise returns the option and a possible
|
||||
--parameter name if it is of the form "--option=foo".
|
||||
local function GetOptionName(option)
|
||||
local option, param = string.match(option, "^%-%-?([^%-%=][^%=]*)%=?(.*)")
|
||||
if(param and #param == 0) then
|
||||
param = nil
|
||||
end
|
||||
|
||||
return option, param
|
||||
end
|
||||
|
||||
--Returns a nullary function that iterates over a single parameter. Namely, this one.
|
||||
local function GetParamIterator(param)
|
||||
return function()
|
||||
return function(s, var)
|
||||
if(var) then
|
||||
return nil, nil
|
||||
else
|
||||
return param, 1
|
||||
end
|
||||
end, nil, nil
|
||||
end
|
||||
end
|
||||
|
||||
--Returns a nullary function that iterates over all parameters from the given
|
||||
--index to the next option.
|
||||
local function GetParamListIterator(params, startIx)
|
||||
return function()
|
||||
local state = {startIx}
|
||||
return function(state, var)
|
||||
--Stop if out of parameters
|
||||
if(state[1] > #params) then
|
||||
return nil
|
||||
end
|
||||
|
||||
--Stop if the parameter is an option name.
|
||||
if(GetOptionName(params[state[1]])) then
|
||||
return nil
|
||||
end
|
||||
|
||||
state[1] = state[1] + 1
|
||||
return params[state[1] - 1], state[1] - startIx
|
||||
end, state, nil
|
||||
end
|
||||
end
|
||||
|
||||
local function CountNumOptions(iter)
|
||||
local numOpts = 0
|
||||
for _ in iter() do
|
||||
numOpts = numOpts + 1
|
||||
end
|
||||
return numOpts
|
||||
end
|
||||
|
||||
local function CallProcessor(func, option, value, param, iter)
|
||||
local status, nargs = pcall(func, value, param, iter)
|
||||
if(not status) then
|
||||
error("The option '" .. option .. "' had an error:\n" .. nargs)
|
||||
end
|
||||
|
||||
return nargs or CountNumOptions(iter)
|
||||
end
|
||||
|
||||
local modTbl = {}
|
||||
|
||||
function modTbl.CmdLineOptions(cmd_line, processors, value)
|
||||
local posArgs = {}
|
||||
local optIx = 1
|
||||
local numOpts = #cmd_line
|
||||
while(optIx <= numOpts) do
|
||||
local option, param = GetOptionName(cmd_line[optIx])
|
||||
|
||||
if(not option) then
|
||||
posArgs[#posArgs + 1] = cmd_line[optIx]
|
||||
optIx = optIx + 1
|
||||
else
|
||||
assert(processors[option], "The option '" .. option .. "' is not a valid option for this program.")
|
||||
|
||||
if(param) then
|
||||
CallProcessor(processors[option], option, value,
|
||||
param, GetParamIterator(param))
|
||||
else
|
||||
local paramIter = GetParamListIterator(cmd_line, optIx + 1)
|
||||
local numOpts = CountNumOptions(paramIter)
|
||||
if(numOpts > 0) then
|
||||
param = cmd_line[optIx + 1]
|
||||
end
|
||||
local nargs = CallProcessor(processors[option], option, value,
|
||||
param, paramIter)
|
||||
|
||||
optIx = optIx + nargs
|
||||
|
||||
end
|
||||
optIx = optIx + 1
|
||||
end
|
||||
end
|
||||
|
||||
return posArgs
|
||||
end
|
||||
|
||||
|
||||
--------------------------------------------------
|
||||
-- Option group logic.
|
||||
local group = {}
|
||||
|
||||
local function ExtractDescArray(desc)
|
||||
if(type(desc) == "table") then
|
||||
local descArray = {}
|
||||
for i, val in ipairs(desc) do
|
||||
descArray[#descArray + 1] = val
|
||||
end
|
||||
return descArray
|
||||
else
|
||||
return { desc }
|
||||
end
|
||||
end
|
||||
|
||||
function group:value(optName, tblName, desc, default, optional)
|
||||
table.insert(self._doc_order, optName)
|
||||
self._procs[optName] = {
|
||||
desc = desc,
|
||||
tableName = tblName,
|
||||
default = default,
|
||||
optional = optional,
|
||||
--self is the destination table, where the data goes
|
||||
proc = function(self, param, iter)
|
||||
assert(param, "This option needs a single parameter")
|
||||
assert(not self[tblName], "Cannot specify the option twice")
|
||||
self[tblName] = param
|
||||
return 1
|
||||
end,
|
||||
|
||||
document = function(self)
|
||||
local docs = ExtractDescArray(self.desc)
|
||||
if(self.default) then
|
||||
docs[#docs + 1] = "Default value: " .. self.default
|
||||
else
|
||||
if(self.optional) then
|
||||
docs[#docs + 1] = "This option is not required."
|
||||
end
|
||||
end
|
||||
|
||||
return docs
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
function group:enum(optName, tblName, desc, values, defaultIx, optional)
|
||||
table.insert(self._doc_order, optName)
|
||||
local valuesInv = util.InvertTable(values)
|
||||
self._procs[optName] = {
|
||||
desc = desc,
|
||||
tableName = tblName,
|
||||
values = values,
|
||||
valuesInv = valuesInv,
|
||||
optional = optional,
|
||||
proc = function(self, param, iter)
|
||||
assert(param, "This option needs a parameter")
|
||||
assert(valuesInv[param], param .. " is not a valid value.")
|
||||
assert(not self[tblName], "Cannot specify this option twice.");
|
||||
self[tblName] = param
|
||||
return 1
|
||||
end,
|
||||
|
||||
document = function(self)
|
||||
local docs = ExtractDescArray(self.desc)
|
||||
docs[#docs + 1] = "Allowed values:"
|
||||
docs[#docs + 1] = table.concat(self.values, ", ")
|
||||
if(self.default) then
|
||||
docs[#docs + 1] = "Default value: " .. self.default
|
||||
else
|
||||
if(self.optional) then
|
||||
docs[#docs + 1] = "This option is not required."
|
||||
end
|
||||
end
|
||||
|
||||
return docs
|
||||
end,
|
||||
}
|
||||
|
||||
if(defaultIx) then
|
||||
self._procs[optName].default = values[defaultIx]
|
||||
end
|
||||
end
|
||||
|
||||
function group:array(optName, tblName, desc, modifier, optional)
|
||||
table.insert(self._doc_order, optName)
|
||||
self._procs[optName] = {
|
||||
desc = desc,
|
||||
tableName = tblName,
|
||||
optional = optional,
|
||||
proc = function(self, param, iter)
|
||||
self[tblName] = self[tblName] or {}
|
||||
|
||||
local bFound = false
|
||||
for ext in iter() do
|
||||
if(modifier) then
|
||||
ext = modifier(ext)
|
||||
end
|
||||
table.insert(self[tblName], ext)
|
||||
bFound = true
|
||||
end
|
||||
|
||||
assert(bFound, "Must provide at least one value.");
|
||||
end,
|
||||
|
||||
document = function(self)
|
||||
local docs = ExtractDescArray(self.desc)
|
||||
return docs
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
--Stores its data in an array, but it only takes one parameter.
|
||||
function group:array_single(optName, tblName, desc, modifier, optional)
|
||||
table.insert(self._doc_order, optName)
|
||||
self._procs[optName] = {
|
||||
desc = desc,
|
||||
tableName = tblName,
|
||||
optional = optional,
|
||||
proc = function(self, param, iter)
|
||||
assert(param, "This option needs a single parameter")
|
||||
self[tblName] = self[tblName] or {}
|
||||
|
||||
if(modifier) then
|
||||
param = modifier(param)
|
||||
end
|
||||
table.insert(self[tblName], param)
|
||||
return 1
|
||||
end,
|
||||
|
||||
document = function(self)
|
||||
local docs = ExtractDescArray(self.desc)
|
||||
docs[#docs + 1] = "Can be used multiple times."
|
||||
return docs
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
function group:pos_opt(index, tblName, desc, optName, default, optional)
|
||||
assert(not self._pos_opts[index],
|
||||
"Positional argument " .. index .. " is already in use")
|
||||
|
||||
self._pos_opts[index] = {
|
||||
desc = desc,
|
||||
tableName = tblName,
|
||||
optName = optName,
|
||||
default = default,
|
||||
optional = optional,
|
||||
}
|
||||
end
|
||||
|
||||
function group:AssertParse(test, msg)
|
||||
if(not test) then
|
||||
io.stdout:write(msg, "\n")
|
||||
self:DisplayHelp()
|
||||
error("", 0)
|
||||
end
|
||||
end
|
||||
|
||||
function group:ProcessCmdLine(cmd_line)
|
||||
local procs = {}
|
||||
|
||||
for option, data in pairs(self._procs) do
|
||||
procs[option] = data.proc
|
||||
end
|
||||
|
||||
local options = {}
|
||||
|
||||
local status, posOpts =
|
||||
pcall(modTbl.CmdLineOptions, cmd_line, procs, options)
|
||||
|
||||
self:AssertParse(status, posOpts)
|
||||
|
||||
--Apply positional arguments.
|
||||
for ix, pos_arg in pairs(self._pos_opts) do
|
||||
if(posOpts[ix]) then
|
||||
options[pos_arg.tableName] = posOpts[ix]
|
||||
elseif(pos_arg.default) then
|
||||
options[pos_arg.tableName] = default
|
||||
else
|
||||
self:AssertParse(pos_arg.optional,
|
||||
"Missing positional argument " .. pos_arg.optName)
|
||||
end
|
||||
end
|
||||
|
||||
--Apply defaults.
|
||||
for option, data in pairs(self._procs) do
|
||||
if(not options[data.tableName]) then
|
||||
if(data.default) then
|
||||
options[data.tableName] = data.default
|
||||
else
|
||||
self:AssertParse(data.optional,
|
||||
"Option " .. option .. " was not specified.")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return options, posOpts
|
||||
end
|
||||
|
||||
function group:DisplayHelp()
|
||||
local hFile = io.stdout
|
||||
|
||||
local function MaxVal(tbl)
|
||||
local maxval = 0
|
||||
for ix, val in pairs(tbl) do
|
||||
if(ix > maxval) then
|
||||
maxval = ix
|
||||
end
|
||||
end
|
||||
|
||||
return maxval
|
||||
end
|
||||
|
||||
--Write the command-line, including positional arguments.
|
||||
hFile:write("Command Line:")
|
||||
local maxPosArg = MaxVal(self._pos_opts)
|
||||
|
||||
for i = 1, maxPosArg do
|
||||
if(self._pos_opts[i]) then
|
||||
hFile:write(" <", self._pos_opts[i].optName, ">")
|
||||
else
|
||||
hFile:write(" <something>")
|
||||
end
|
||||
end
|
||||
|
||||
hFile:write(" <options>\n")
|
||||
|
||||
--Write each option.
|
||||
hFile:write("Options:\n")
|
||||
for _, option in ipairs(self._doc_order) do
|
||||
local data = self._procs[option]
|
||||
hFile:write("-", option, ":\n")
|
||||
|
||||
local docs = data:document()
|
||||
|
||||
for _, str in ipairs(docs) do
|
||||
hFile:write("\t", str, "\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function modTbl.CreateOptionGroup()
|
||||
local optGroup = {}
|
||||
|
||||
for key, func in pairs(group) do
|
||||
optGroup[key] = func
|
||||
end
|
||||
|
||||
optGroup._procs = {}
|
||||
optGroup._pos_opts = {}
|
||||
optGroup._doc_order = {}
|
||||
|
||||
return optGroup
|
||||
end
|
||||
|
||||
return modTbl
|
|
@ -1,75 +0,0 @@
|
|||
|
||||
local common = {}
|
||||
|
||||
--Iterates over all requested extensions
|
||||
--Calls Extension(hFile, extName, spec, options)
|
||||
local extensions =
|
||||
{ type="group",
|
||||
{ type="ext-iter",
|
||||
{ type="write", name="Extension(hFile, extName, spec, options)", },
|
||||
},
|
||||
}
|
||||
|
||||
function common.Extensions() return extensions end
|
||||
|
||||
--Iterates over every enumerator, in order:
|
||||
-- Requested extension enums.
|
||||
-- For each version:
|
||||
-- Core extension enumerators from version X
|
||||
-- Core enumerators from version X
|
||||
-- Calls Enumerator(hFile, enum, enumTable, spec, options, enumSeen)
|
||||
-- Optional small headers
|
||||
local enumerators =
|
||||
{ type="group",
|
||||
{ type="enum-seen",
|
||||
{ type="ext-iter",
|
||||
{type="enum-iter",
|
||||
{ type="write", name="SmallHeader(hFile, value, options)", value="Extension: %extName", first=true, optional=true},
|
||||
{ type="write", name="Enumerator(hFile, enum, enumTable, spec, options, enumSeen)", },
|
||||
{ type="blank", last=true },
|
||||
},
|
||||
},
|
||||
{ type="version-iter",
|
||||
{type="enum-iter",
|
||||
{ type="write", name="SmallHeader(hFile, value, options)", value="Version: %version", first=true, optional=true},
|
||||
{ type="write", name="Enumerator(hFile, enum, enumTable, spec, options, enumSeen)", },
|
||||
{ type="blank", last=true },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
function common.Enumerators() return enumerators end
|
||||
|
||||
--Iterates over each function, in order:
|
||||
-- Requested extension functions.
|
||||
-- For each version:
|
||||
-- Core extensions from for version X
|
||||
-- Core functions from version X
|
||||
-- Calls Function(hFile, func, spec, options, funcSeen)
|
||||
-- Optional small headers.
|
||||
-- Can provide an optional ending table, that will be placed within
|
||||
-- the "func-seen" block.
|
||||
function common.Functions(ending)
|
||||
ending = ending or { type="group" }
|
||||
return
|
||||
{ type="func-seen",
|
||||
{ type="ext-iter",
|
||||
{type="func-iter",
|
||||
{ type="write", name="SmallHeader(hFile, value, options)", value="Extension: %extName", first=true, optional=true},
|
||||
{ type="write", name="Function(hFile, func, spec, options, funcSeen)", },
|
||||
{ type="blank", last=true },
|
||||
},
|
||||
},
|
||||
{ type="version-iter",
|
||||
{type="func-iter",
|
||||
{ type="write", name="SmallHeader(hFile, value, options)", value="Extension: %version", first=true, optional=true},
|
||||
{ type="write", name="Function(hFile, func, spec, options, funcSeen)", },
|
||||
{ type="blank", last=true },
|
||||
},
|
||||
},
|
||||
ending,
|
||||
}
|
||||
end
|
||||
|
||||
return common
|
|
@ -1,557 +0,0 @@
|
|||
--[[Useful style utility functions. This file will contain commonly useful strings and functions that generate useful data.]]
|
||||
|
||||
local util = require "util"
|
||||
local struct = require "Structure"
|
||||
|
||||
local common = {}
|
||||
|
||||
--Creates a tabbed file.
|
||||
function common.CreateFile(filename, indent)
|
||||
return util.CreateFile(filename, indent)
|
||||
end
|
||||
|
||||
--Retrieves the common typedefs used by OpenGL 1.1.
|
||||
function common.GetStdTypedefs()
|
||||
return dofile(util.GetDataFilePath() .. "style_commontypedefs.lua")
|
||||
end
|
||||
|
||||
--Writes passthru data from the specData, with proper indentation.
|
||||
function common.WritePassthruData(hFile, strArray)
|
||||
for _, str in ipairs(strArray) do
|
||||
--unindent after #endif
|
||||
if(str:match("^#endif") or str:match("^#elif")) then
|
||||
hFile:dec()
|
||||
end
|
||||
|
||||
hFile:write(str, "\n")
|
||||
|
||||
--Indent after #if.
|
||||
if(str:match("^#if") or str:match("^#elif")) then
|
||||
hFile:inc()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function common.WriteExternCStart(hFile)
|
||||
hFile:write("#ifdef __cplusplus\n")
|
||||
hFile:write('extern "C" {\n')
|
||||
hFile:write("#endif /*__cplusplus*/\n")
|
||||
hFile:write("\n")
|
||||
end
|
||||
|
||||
function common.WriteExternCEnd(hFile)
|
||||
hFile:write("#ifdef __cplusplus\n")
|
||||
hFile:write('}\n')
|
||||
hFile:write("#endif /*__cplusplus*/\n")
|
||||
hFile:write("\n")
|
||||
end
|
||||
|
||||
--Determines the value of the enumeration.
|
||||
local function ResolveEnumValue(enum, enumTable)
|
||||
if(enum.copy) then
|
||||
return common.ResolveEnumValue(enumTable[enum.value], enumTable),
|
||||
enum.value;
|
||||
else
|
||||
return enum.value;
|
||||
end
|
||||
end
|
||||
common.ResolveEnumValue = ResolveEnumValue
|
||||
|
||||
function common.GetCppEnumName(enum)
|
||||
--Note: some enumerators start with characters C++ forbids as initial
|
||||
--identifiers. If we detect such an enum, prefix it with `_`.
|
||||
local enumName = enum.name
|
||||
if(not enumName:match("^[a-zA-Z_]")) then
|
||||
enumName = "_" .. enumName
|
||||
end
|
||||
|
||||
--Also, certain identifiers can need it because they conflict.
|
||||
local badIdent = {"TRUE", "FALSE", "NO_ERROR", "WAIT_FAILED", "DOMAIN"}
|
||||
for _, ident in ipairs(badIdent) do
|
||||
if(enumName == ident) then
|
||||
enumName = enumName .. "_"
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
return enumName
|
||||
end
|
||||
|
||||
function common.GetNameLengthPadding(name, length)
|
||||
local numSpaces = length - #name
|
||||
if(numSpaces < 1) then
|
||||
numSpaces = 1
|
||||
end
|
||||
|
||||
return string.rep(" ", numSpaces)
|
||||
end
|
||||
|
||||
--Gets the return type for a function.
|
||||
function common.GetFuncReturnType(func)
|
||||
return func["return_ctype"]
|
||||
end
|
||||
|
||||
function common.DoesFuncReturnSomething(func)
|
||||
local returnType = func["return_ctype"]
|
||||
return (returnType == "void") or (returnType == "GLvoid")
|
||||
end
|
||||
|
||||
local bIsKindPtr ={
|
||||
value = false,
|
||||
array = true,
|
||||
reference = true,
|
||||
};
|
||||
|
||||
--Important due to name conflicts. Some names have to re-mapped to others.
|
||||
--Won't really affect things.
|
||||
local paramNameRemap = {
|
||||
near = "ren_near",
|
||||
far = "ren_far",
|
||||
array = "ren_array",
|
||||
};
|
||||
|
||||
--Returns the parameter list as a string.
|
||||
--Parameter list does not include parenthesis.
|
||||
function common.GetFuncParamList(func, bWriteVarNames)
|
||||
local paramList = {}
|
||||
for i, param in ipairs(func.parameters) do
|
||||
local paramType = param.ctype;
|
||||
if(bWriteVarNames) then
|
||||
local paramName = param.name
|
||||
if(paramNameRemap[paramName]) then paramName = paramNameRemap[paramName]end
|
||||
paramList[#paramList + 1] = string.format("%s %s", paramType, paramName)
|
||||
else
|
||||
paramList[#paramList + 1] = paramType
|
||||
end
|
||||
end
|
||||
|
||||
return table.concat(paramList, ", ");
|
||||
end
|
||||
|
||||
--Get the list of parameter names, as a string ready to be put into ().
|
||||
function common.GetFuncParamCallList(func)
|
||||
local paramList = {}
|
||||
for i, param in ipairs(func.parameters) do
|
||||
local paramName = param.name
|
||||
if(paramNameRemap[paramName]) then
|
||||
paramName = paramNameRemap[paramName]
|
||||
end
|
||||
|
||||
paramList[#paramList + 1] = paramName
|
||||
end
|
||||
|
||||
return table.concat(paramList, ", ");
|
||||
end
|
||||
|
||||
--Retrieves the name of the function according to OpenGL.
|
||||
function common.GetOpenGLFuncName(func, spec)
|
||||
return spec.FuncNamePrefix() .. func.name
|
||||
end
|
||||
|
||||
function common.GetProcAddressName(spec)
|
||||
return spec.GetPtrLoaderFuncName()
|
||||
end
|
||||
|
||||
function common.FixupIndexedList(specData, indexed)
|
||||
assert(indexed)
|
||||
for _, func in ipairs(specData.funcData.functions) do
|
||||
if(indexed[1] == func.name) then
|
||||
indexed[1] = func
|
||||
end
|
||||
if(indexed[3] == func.name) then
|
||||
indexed[3] = func
|
||||
end
|
||||
end
|
||||
for _, enum in ipairs(specData.enumerators) do
|
||||
if(indexed[2] == enum.name) then
|
||||
indexed[2] = enum
|
||||
end
|
||||
if(indexed[4] == enum.name) then
|
||||
indexed[4] = enum
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function common.GetProcExtsFromExtListFunc(hFile, specData, spec, options,
|
||||
indexed, GetFuncPtrName, GetEnumName)
|
||||
return [[
|
||||
static 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);
|
||||
}
|
||||
}
|
||||
]]
|
||||
end
|
||||
|
||||
--You give it a function that takes a const char*.
|
||||
function common.GetProcessExtsFromStringFunc(funcFormat, arguments)
|
||||
return [[
|
||||
static void ProcExtsFromExtString(const char *strExtList]] .. (arguments or "") .. [[)
|
||||
{
|
||||
size_t iExtListLen = strlen(strExtList);
|
||||
const char *strExtListEnd = strExtList + iExtListLen;
|
||||
const char *strCurrPos = strExtList;
|
||||
char strWorkBuff[256];
|
||||
|
||||
while(*strCurrPos)
|
||||
{
|
||||
/*Get the extension at our position.*/
|
||||
int iStrLen = 0;
|
||||
const char *strEndStr = strchr(strCurrPos, ' ');
|
||||
int iStop = 0;
|
||||
if(strEndStr == NULL)
|
||||
{
|
||||
strEndStr = strExtListEnd;
|
||||
iStop = 1;
|
||||
}
|
||||
|
||||
iStrLen = (int)((ptrdiff_t)strEndStr - (ptrdiff_t)strCurrPos);
|
||||
|
||||
if(iStrLen > 255)
|
||||
return;
|
||||
|
||||
strncpy(strWorkBuff, strCurrPos, iStrLen);
|
||||
strWorkBuff[iStrLen] = '\0';
|
||||
|
||||
]] .. funcFormat:format("strWorkBuff") ..[[;
|
||||
|
||||
strCurrPos = strEndStr + 1;
|
||||
if(iStop) break;
|
||||
}
|
||||
}
|
||||
]]
|
||||
end
|
||||
|
||||
function common.WriteProcessExtsFromStringFunc(hFile, ...)
|
||||
hFile:writeblock(common.GetProcessExtsFromStringFunc(...))
|
||||
end
|
||||
|
||||
function common.GetParseVersionFromString()
|
||||
return [[
|
||||
static void ParseVersionFromString(int *pOutMajor, int *pOutMinor, const char *strVersion)
|
||||
{
|
||||
const char *strDotPos = NULL;
|
||||
int iLength = 0;
|
||||
char strWorkBuff[10];
|
||||
*pOutMinor = 0;
|
||||
*pOutMajor = 0;
|
||||
|
||||
strDotPos = strchr(strVersion, '.');
|
||||
if(!strDotPos)
|
||||
return;
|
||||
|
||||
iLength = (int)((ptrdiff_t)strDotPos - (ptrdiff_t)strVersion);
|
||||
strncpy(strWorkBuff, strVersion, iLength);
|
||||
strWorkBuff[iLength] = '\0';
|
||||
|
||||
*pOutMajor = atoi(strWorkBuff);
|
||||
strDotPos = strchr(strVersion + iLength + 1, ' ');
|
||||
if(!strDotPos)
|
||||
{
|
||||
/*No extra data. Take the whole rest of the string.*/
|
||||
strcpy(strWorkBuff, strVersion + iLength + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*Copy only up until the space.*/
|
||||
int iLengthMinor = (int)((ptrdiff_t)strDotPos - (ptrdiff_t)strVersion);
|
||||
iLengthMinor = iLengthMinor - (iLength + 1);
|
||||
strncpy(strWorkBuff, strVersion + iLength + 1, iLengthMinor);
|
||||
strWorkBuff[iLengthMinor] = '\0';
|
||||
}
|
||||
|
||||
*pOutMinor = atoi(strWorkBuff);
|
||||
}
|
||||
]]
|
||||
end
|
||||
|
||||
local function DeepCopyTable(tbl)
|
||||
local ret = {}
|
||||
for key, value in pairs(tbl) do
|
||||
if(type(value) == "table") then
|
||||
ret[key] = DeepCopyTable(value)
|
||||
else
|
||||
ret[key] = value
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
function common.WriteCMappingTable(hFile, specData, spec,
|
||||
options, structName, varName, GetExtVariableName, GetExtLoaderFuncName)
|
||||
--Write the struct for the mapping table.
|
||||
hFile:write("typedef int (*PFN_LOADFUNCPOINTERS)();\n")
|
||||
hFile:fmt("typedef struct %s%sStrToExtMap_s\n",
|
||||
options.prefix, spec.DeclPrefix())
|
||||
hFile:write("{\n")
|
||||
hFile:inc()
|
||||
hFile:write("char *extensionName;\n")
|
||||
hFile:write("int *extensionVariable;\n")
|
||||
hFile:write("PFN_LOADFUNCPOINTERS LoadExtension;\n")
|
||||
hFile:dec()
|
||||
hFile:fmt("} %s;\n", structName)
|
||||
hFile:write "\n"
|
||||
|
||||
--Write the mapping table itself.
|
||||
local arrayLength = #options.extensions
|
||||
if(arrayLength == 0) then arrayLength = 1 end
|
||||
hFile:fmt("static %s %s[%i] = {\n",
|
||||
structName,
|
||||
varName,
|
||||
arrayLength)
|
||||
hFile:inc()
|
||||
for _, extName in ipairs(options.extensions) do
|
||||
if(#specData.extdefs[extName].funcs > 0) then
|
||||
hFile:fmt('{"%s", &%s, %s},\n',
|
||||
spec.ExtNamePrefix() .. extName,
|
||||
GetExtVariableName(extName, spec, options),
|
||||
GetExtLoaderFuncName(extName, spec, options))
|
||||
else
|
||||
hFile:fmt('{"%s", &%s, NULL},\n',
|
||||
spec.ExtNamePrefix() .. extName,
|
||||
GetExtVariableName(extName, spec, options))
|
||||
end
|
||||
end
|
||||
--Because C is stupid, write bogus entry.
|
||||
if(#options.extensions == 0) then
|
||||
hFile:fmt('{"", NULL, NULL},\n')
|
||||
end
|
||||
hFile:dec()
|
||||
hFile:write("};\n")
|
||||
|
||||
hFile:write "\n"
|
||||
hFile:fmt("static int g_extensionMapSize = %i;\n", #options.extensions);
|
||||
end
|
||||
|
||||
function common.WriteCFindExtEntryFunc(hFile, specData, spec,
|
||||
options, structName, varName, sizeName)
|
||||
hFile:fmt("static %s *FindExtEntry(const char *extensionName)\n",
|
||||
structName)
|
||||
hFile:write("{\n")
|
||||
hFile:inc()
|
||||
hFile:write("int loop;\n")
|
||||
hFile:fmt("%s *currLoc = %s;\n",
|
||||
structName,
|
||||
varName)
|
||||
hFile:writeblock([[
|
||||
for(loop = 0; loop < g_extensionMapSize; ++loop, ++currLoc)
|
||||
{
|
||||
if(strcmp(extensionName, currLoc->extensionName) == 0)
|
||||
return currLoc;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
]])
|
||||
hFile:dec()
|
||||
hFile:write("}\n")
|
||||
end
|
||||
|
||||
function common.WriteCClearExtensionVarsFunc(hFile, specData, spec,
|
||||
options, GetExtVariableName, clearValue)
|
||||
hFile:fmt("static void ClearExtensionVars()\n")
|
||||
hFile:write("{\n")
|
||||
hFile:inc()
|
||||
for _, extName in ipairs(options.extensions) do
|
||||
hFile:fmt('%s = %s;\n',
|
||||
GetExtVariableName(extName, spec, options),
|
||||
clearValue)
|
||||
end
|
||||
hFile:dec()
|
||||
hFile:write("}\n")
|
||||
hFile:write "\n"
|
||||
end
|
||||
|
||||
--Write a function that loads an extension by name. It is called when
|
||||
--processing, so it should also set the extension variable based on the load.
|
||||
function common.WriteCLoadExtByNameFunc(hFile, specData, spec,
|
||||
options, structName, successValue)
|
||||
hFile:writeblock([[
|
||||
static void LoadExtByName(const char *extensionName)
|
||||
{
|
||||
]] .. structName .. [[ *entry = NULL;
|
||||
entry = FindExtEntry(extensionName);
|
||||
if(entry)
|
||||
{
|
||||
if(entry->LoadExtension)
|
||||
{
|
||||
int numFailed = entry->LoadExtension();
|
||||
if(numFailed == 0)
|
||||
{
|
||||
*(entry->extensionVariable) = ]] ..
|
||||
successValue ..
|
||||
[[;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(entry->extensionVariable) = ]] ..
|
||||
successValue ..
|
||||
[[ + numFailed;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*(entry->extensionVariable) = ]] ..
|
||||
successValue ..
|
||||
[[;
|
||||
}
|
||||
}
|
||||
}
|
||||
]])
|
||||
end
|
||||
|
||||
function common.WriteNamespaceBegin(hFile, namespace)
|
||||
hFile:fmt("namespace %s\n", namespace)
|
||||
hFile:write("{\n")
|
||||
hFile:inc()
|
||||
end
|
||||
|
||||
function common.WriteNamespaceEnd(hFile)
|
||||
hFile:dec()
|
||||
hFile:write("}\n")
|
||||
end
|
||||
|
||||
|
||||
common.DeepCopyTable = DeepCopyTable
|
||||
|
||||
local my_struct =
|
||||
{
|
||||
{ type="file", style="header", name="GetFilename",
|
||||
{ type="write", name="FilePreamble", optional=true} ,
|
||||
{ type="block", name="IncludeGuard(hFile, spec, options)",
|
||||
{ type="blank"},
|
||||
{ type="write", name="Init(hFile, spec, options)", },
|
||||
{ type="blank"},
|
||||
{ type="write", name="StdTypedefs(hFile, specData, options)",},
|
||||
{ type="blank"},
|
||||
{ type="write", name="SpecTypedefs(hFile, specData, options)",},
|
||||
{ type="blank"},
|
||||
{ type="block", name="Decl(hFile, spec, options)",
|
||||
{ type="block", name="ExtVarDecl(hFile, spec, options)",
|
||||
{ type="ext-iter",
|
||||
{ type="write", name="ExtVariableDecl(hFile, extName, specData, spec, options)" },
|
||||
{ type="blank", last=true },
|
||||
},
|
||||
},
|
||||
{ type="block", name="EnumDecl(hFile, spec, options)",
|
||||
{ type="enum-seen",
|
||||
{ type="ext-iter",
|
||||
{type="enum-iter",
|
||||
{ type="write", name="EnumDecl(hFile, enum, enumTable, spec, options, enumSeen)", },
|
||||
{ type="blank", last=true },
|
||||
},
|
||||
},
|
||||
{ type="version-iter",
|
||||
{type="enum-iter",
|
||||
{ type="write", name="EnumDecl(hFile, enum, enumTable, spec, options, enumSeen)", },
|
||||
{ type="blank", last=true },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{ type="block", name="FuncDecl(hFile, spec, options)",
|
||||
{ type="func-seen",
|
||||
{ type="ext-iter",
|
||||
{ type="block", name="ExtFuncDecl(hFile, extName, spec, options)", cond="func-iter",
|
||||
{type="func-iter",
|
||||
{ type="write", name="FuncDecl(hFile, func, spec, options, funcSeen)", },
|
||||
},
|
||||
},
|
||||
{ type="blank"},
|
||||
},
|
||||
{ type="version-iter",
|
||||
{type="func-iter",
|
||||
{ type="write", name="FuncDecl(hFile, func, spec, options, funcSeen)", },
|
||||
{ type="blank", last=true },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{ type="block", name="SysDecl(hFile, spec, options)",
|
||||
{ type="write", name="UtilityDecls(hFile, spec, options)",},
|
||||
{ type="blank" },
|
||||
{ type="write", name="MainLoaderFuncDecl(hFile, spec, options)",},
|
||||
{ type="blank" },
|
||||
{ type="write", name="VersioningFuncDecls(hFile, spec, options)",},
|
||||
{ type="blank" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{ type="file", style="source", name="GetFilename",
|
||||
{ type="write", name="FilePreamble", optional=true} ,
|
||||
{ type="write", name="Includes(hFile, basename, spec, options)",},
|
||||
{ type="blank"},
|
||||
{ type="write", name="LoaderData(hFile, spec, options)",},
|
||||
{ type="blank"},
|
||||
{ type="block", name="Def(hFile, spec, options)",
|
||||
{ type="block", name="ExtVarDef(hFile, spec, options)",
|
||||
{ type="ext-iter",
|
||||
{ type="write", name="ExtVariableDef(hFile, extName, specData, spec, options)",},
|
||||
{ type="blank", last=true},
|
||||
},
|
||||
},
|
||||
{ type="func-seen",
|
||||
{ type="ext-iter",
|
||||
{ type="block", name="ExtFuncDef(hFile, extName, spec, options)", cond="func-iter",
|
||||
{ type="func-iter",
|
||||
{ type="write", name="FuncDef(hFile, func, spec, options, funcSeen)", },
|
||||
},
|
||||
{ type="blank"},
|
||||
{ type="block", name="ExtLoader(hFile, extName, spec, options)",
|
||||
{ type="func-iter",
|
||||
{ type="write", name="ExtFuncLoader(hFile, func, spec, options)", }
|
||||
}
|
||||
},
|
||||
{ type="blank"},
|
||||
},
|
||||
},
|
||||
{ type="block", name="CoreFuncDef(hFile, spec, options)",
|
||||
cond="core-funcs",
|
||||
{ type="version-iter",
|
||||
{type="func-iter",
|
||||
{ type="write", name="FuncDef(hFile, func, spec, options, funcSeen)", },
|
||||
{ type="blank", last=true },
|
||||
},
|
||||
},
|
||||
{ type="block", name="CoreLoader(hFile, spec, options)",
|
||||
{ type="version-iter",
|
||||
{type="func-iter",
|
||||
{ type="write", name="CoreFuncLoader(hFile, func, spec, options)", },
|
||||
},
|
||||
},
|
||||
},
|
||||
{ type="blank"},
|
||||
},
|
||||
{ type="write", name="ExtStringFuncDef(hFile, specData, spec, options, funcSeen)"},
|
||||
},
|
||||
{ type="block", name="SysDef(hFile, spec, options)",
|
||||
{ type="write", name="UtilityDefs(hFile, specData, spec, options)",},
|
||||
{ type="blank" },
|
||||
{ type="write", name="MainLoaderFunc(hFile, specData, spec, options)",},
|
||||
{ type="blank" },
|
||||
{ type="write", name="VersioningFuncs(hFile, specData, spec, options)", cond="version-iter"},
|
||||
{ type="blank", cond="version-iter" },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
my_struct = struct.BuildStructure(my_struct)
|
||||
|
||||
function common.GetStandardStructure()
|
||||
return my_struct
|
||||
end
|
||||
|
||||
return common
|
|
@ -1,154 +0,0 @@
|
|||
|
||||
local struct = require "Structure"
|
||||
local common = require "CommonStruct"
|
||||
|
||||
local my_struct =
|
||||
{
|
||||
{ type="file", style="header", name="GetFilename",
|
||||
{ type="write", name="FilePreamble", optional=true} ,
|
||||
{ type="block", name="IncludeGuard(hFile, spec, options)",
|
||||
{ type="blank"},
|
||||
{ type="write", name="Init(hFile, spec, options)", },
|
||||
{ type="blank"},
|
||||
{ type="write", name="StdTypedefs(hFile, specData, options)",},
|
||||
{ type="blank"},
|
||||
{ type="write", name="SpecTypedefs(hFile, specData, options)",},
|
||||
{ type="blank"},
|
||||
{ type="block", name="Decl(hFile, spec, options)",
|
||||
{ type="block", name="ExtVarDecl(hFile, spec, options)",
|
||||
{ type="ext-iter",
|
||||
{ type="write", name="ExtVariableDecl(hFile, extName, specData, spec, options)" },
|
||||
{ type="blank", last=true },
|
||||
},
|
||||
},
|
||||
{ type="block", name="EnumDecl(hFile, spec, options)",
|
||||
{ type="enum-seen",
|
||||
{ type="ext-iter",
|
||||
{type="enum-iter",
|
||||
{ type="write", name="EnumDecl(hFile, enum, enumTable, spec, options, enumSeen)", },
|
||||
{ type="blank", last=true },
|
||||
},
|
||||
},
|
||||
{ type="version-iter",
|
||||
{type="enum-iter",
|
||||
{ type="write", name="EnumDecl(hFile, enum, enumTable, spec, options, enumSeen)", },
|
||||
{ type="blank", last=true },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{ type="blank"},
|
||||
{ type="block", name="FuncPtrDecl(hFile, spec, options)",
|
||||
{ type="func-seen",
|
||||
{ type="ext-iter",
|
||||
{ type="block", name="ExtFuncPtrDecl(hFile, extName, spec, options)", cond="func-iter",
|
||||
{type="func-iter",
|
||||
{ type="write", name="FuncPtrDecl(hFile, func, spec, options, funcSeen)", },
|
||||
},
|
||||
},
|
||||
{ type="blank"},
|
||||
},
|
||||
{ type="version-iter",
|
||||
{type="func-iter",
|
||||
{ type="write", name="FuncPtrDecl(hFile, func, spec, options, funcSeen)", },
|
||||
{ type="blank", last=true },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{ type="blank"},
|
||||
{ type="block", name="FuncDecl(hFile, spec, options)",
|
||||
{ type="func-seen",
|
||||
{ type="ext-iter",
|
||||
{ type="block", name="ExtFuncDecl(hFile, extName, spec, options)", cond="func-iter",
|
||||
{type="func-iter",
|
||||
{ type="write", name="FuncDecl(hFile, func, spec, options, funcSeen)", },
|
||||
},
|
||||
},
|
||||
{ type="blank"},
|
||||
},
|
||||
{ type="version-iter",
|
||||
{type="func-iter",
|
||||
{ type="write", name="FuncDecl(hFile, func, spec, options, funcSeen)", },
|
||||
{ type="blank", last=true },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{ type="blank"},
|
||||
{ type="block", name="SysDecl(hFile, spec, options)",
|
||||
{ type="write", name="UtilityDecls(hFile, spec, options)",},
|
||||
{ type="blank" },
|
||||
{ type="write", name="MainLoaderFuncDecl(hFile, spec, options)",},
|
||||
{ type="blank" },
|
||||
{ type="write", name="VersioningFuncDecls(hFile, spec, options)",},
|
||||
{ type="blank" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{ type="file", style="source", name="GetFilename",
|
||||
{ type="write", name="FilePreamble", optional=true} ,
|
||||
{ type="write", name="Includes(hFile, basename, spec, options)",},
|
||||
{ type="blank"},
|
||||
{ type="write", name="LoaderData(hFile, spec, options)",},
|
||||
{ type="blank"},
|
||||
{ type="block", name="Def(hFile, spec, options)",
|
||||
{ type="block", name="ExtVarDef(hFile, spec, options)",
|
||||
{ type="ext-iter",
|
||||
{ type="write", name="ExtVariableDef(hFile, extName, specData, spec, options)",},
|
||||
{ type="blank", last=true},
|
||||
},
|
||||
},
|
||||
{ type="blank"},
|
||||
{ type="block", name="PtrDefs(hFile, spec, options)",
|
||||
{ type="func-seen",
|
||||
{ type="ext-iter",
|
||||
{ type="block", name="ExtFuncPtrDef(hFile, extName, spec, options)", cond="func-iter",
|
||||
{ type="func-iter",
|
||||
{ type="write", name="FuncPtrDef(hFile, func, spec, options, funcSeen)", },
|
||||
},
|
||||
{ type="blank"},
|
||||
{ type="block", name="ExtLoader(hFile, extName, spec, options)",
|
||||
{ type="func-iter",
|
||||
{ type="write", name="ExtFuncLoader(hFile, func, spec, options)", }
|
||||
}
|
||||
},
|
||||
{ type="blank"},
|
||||
},
|
||||
},
|
||||
{ type="block", name="CoreFuncPtrDef(hFile, spec, options)",
|
||||
cond="core-funcs",
|
||||
{ type="version-iter",
|
||||
{type="func-iter",
|
||||
{ type="write", name="FuncPtrDef(hFile, func, spec, options, funcSeen)", },
|
||||
{ type="blank", last=true },
|
||||
},
|
||||
},
|
||||
{ type="block", name="CoreLoader(hFile, spec, options)",
|
||||
{ type="version-iter",
|
||||
{type="func-iter",
|
||||
{ type="write", name="CoreFuncLoader(hFile, func, spec, options)", },
|
||||
},
|
||||
},
|
||||
},
|
||||
{ type="blank"},
|
||||
},
|
||||
{ type="write", name="ExtStringFuncDef(hFile, specData, spec, options, funcSeen)"},
|
||||
},
|
||||
},
|
||||
{ type="blank"},
|
||||
{ type="block", name="SysDef(hFile, spec, options)",
|
||||
{ type="write", name="UtilityDefs(hFile, specData, spec, options)",},
|
||||
{ type="blank" },
|
||||
{ type="write", name="MainLoaderFunc(hFile, specData, spec, options)",},
|
||||
{ type="blank" },
|
||||
{ type="write", name="VersioningFuncs(hFile, specData, spec, options)", cond="version-iter"},
|
||||
{ type="blank", cond="version-iter" },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
my_struct = struct.BuildStructure(my_struct)
|
||||
return my_struct
|
|
@ -1,765 +0,0 @@
|
|||
|
||||
local common = require "CommonStyle"
|
||||
local struct = require "FuncCpp_Struct"
|
||||
local util = require "util"
|
||||
|
||||
local my_style = {}
|
||||
my_style.header = {}
|
||||
my_style.source = {}
|
||||
|
||||
----------------------------------------------------
|
||||
-- Global styling functions.
|
||||
function my_style.WriteLargeHeading(hFile, headingName)
|
||||
hFile:write(string.rep("/", 6 + #headingName), "\n")
|
||||
hFile:write("// ", headingName, "\n")
|
||||
hFile:write(string.rep("/", 6 + #headingName), "\n")
|
||||
end
|
||||
|
||||
function my_style.WriteSmallHeading(hFile, headingName)
|
||||
hFile:write("// ", headingName, "\n")
|
||||
end
|
||||
|
||||
------------------------------------------------------
|
||||
-- Header styling functions
|
||||
|
||||
function my_style.header.GetFilename(basename, options)
|
||||
return basename .. ".hpp"
|
||||
end
|
||||
|
||||
local function GenIncludeGuardName(hFile, spec, options)
|
||||
local str = "FUNCTION_CPP_GENERATED_HEADER" ..
|
||||
spec.GetIncludeGuardString() .. "_HPP"
|
||||
|
||||
if(#options.prefix > 0) then
|
||||
return options.prefix:upper() .. "_" .. str
|
||||
end
|
||||
|
||||
return str
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockBeginIncludeGuard(hFile, spec, options)
|
||||
local inclGuard = GenIncludeGuardName(hFile, spec, options)
|
||||
|
||||
hFile:fmt("#ifndef %s\n", inclGuard)
|
||||
hFile:fmt("#define %s\n", inclGuard)
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockEndIncludeGuard(hFile, spec, options)
|
||||
hFile:fmt("#endif //%s\n", GenIncludeGuardName(hFile, spec, options))
|
||||
end
|
||||
|
||||
function my_style.header.WriteInit(hFile, spec, options)
|
||||
hFile:rawwrite(spec.GetHeaderInit())
|
||||
end
|
||||
|
||||
function my_style.header.WriteStdTypedefs(hFile, specData, spec, options)
|
||||
local defArray = common.GetStdTypedefs()
|
||||
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")
|
||||
end
|
||||
|
||||
function my_style.header.WriteSpecTypedefs(hFile, specData, spec, options)
|
||||
hFile:push()
|
||||
common.WritePassthruData(hFile, specData.funcData.passthru)
|
||||
hFile:pop()
|
||||
end
|
||||
|
||||
local function StartNamespace(hFile, namespaceName)
|
||||
hFile:fmt("namespace %s\n", namespaceName or "")
|
||||
hFile:write("{\n")
|
||||
hFile:inc()
|
||||
end
|
||||
|
||||
local function EndNamespace(hFile, namespaceName)
|
||||
hFile:dec()
|
||||
hFile:fmt("} //namespace %s\n", namespaceName or "")
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockBeginDecl(hFile, spec, options)
|
||||
if(#options.prefix > 0) then
|
||||
StartNamespace(hFile, options.prefix)
|
||||
end
|
||||
StartNamespace(hFile, spec.FuncNamePrefix())
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockEndDecl(hFile, spec, options)
|
||||
EndNamespace(hFile, spec.FuncNamePrefix())
|
||||
if(#options.prefix > 0) then
|
||||
EndNamespace(hFile, options.prefix)
|
||||
end
|
||||
end
|
||||
|
||||
local extBlockNamespace = "exts"
|
||||
local extVariableTypeDefinition = [[
|
||||
class LoadTest
|
||||
{
|
||||
private:
|
||||
//Safe bool idiom. Joy!
|
||||
typedef void (LoadTest::*bool_type)() const;
|
||||
void big_long_name_that_really_doesnt_matter() const {}
|
||||
|
||||
public:
|
||||
operator bool_type() const
|
||||
{
|
||||
return m_isLoaded ? &LoadTest::big_long_name_that_really_doesnt_matter : 0;
|
||||
}
|
||||
|
||||
int GetNumMissing() const {return m_numMissing;}
|
||||
|
||||
LoadTest() : m_isLoaded(false), m_numMissing(0) {}
|
||||
LoadTest(bool isLoaded, int numMissing) : m_isLoaded(isLoaded), m_numMissing(numMissing) {}
|
||||
private:
|
||||
bool m_isLoaded;
|
||||
int m_numMissing;
|
||||
};
|
||||
]]
|
||||
|
||||
function my_style.header.WriteBlockBeginExtVarDecl(hFile, spec, options)
|
||||
StartNamespace(hFile, extBlockNamespace)
|
||||
hFile:writeblock(extVariableTypeDefinition)
|
||||
hFile:write("\n")
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockEndExtVarDecl(hFile, spec, options)
|
||||
EndNamespace(hFile, extBlockNamespace)
|
||||
end
|
||||
|
||||
local function GenExtensionVarName(extName, spec, options)
|
||||
return "var_" .. extName;
|
||||
end
|
||||
|
||||
function my_style.header.WriteExtVariableDecl(hFile, extName,
|
||||
specData, spec, options)
|
||||
hFile:fmt("extern LoadTest %s;\n",
|
||||
GenExtensionVarName(extName, spec, options));
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockBeginEnumDecl(hFile, spec, options)
|
||||
hFile:write("enum\n")
|
||||
hFile:write("{\n")
|
||||
hFile:inc()
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockEndEnumDecl(hFile, spec, options)
|
||||
hFile:dec()
|
||||
hFile:write("};\n")
|
||||
end
|
||||
|
||||
local function GenEnumName(enum)
|
||||
return common.GetCppEnumName(enum)
|
||||
end
|
||||
|
||||
function my_style.header.WriteEnumDecl(hFile, enum, enumTable, spec, options,
|
||||
enumSeen)
|
||||
if(enumSeen[enum.name]) then
|
||||
hFile:fmt("//%s taken from ext: %s\n", enum.name, enumSeen[enum.name])
|
||||
else
|
||||
|
||||
local enumName = GenEnumName(enum)
|
||||
local lenEnum = #enumName
|
||||
local numIndent = 33
|
||||
|
||||
local numSpaces = numIndent - lenEnum
|
||||
if(numSpaces < 1) then
|
||||
numSpaces = 1
|
||||
end
|
||||
|
||||
hFile:fmt("%s%s= %s,\n",
|
||||
enumName,
|
||||
string.rep(" ", numSpaces),
|
||||
common.ResolveEnumValue(enum, enumTable))
|
||||
end
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockBeginFuncPtrDecl(hFile, spec, options)
|
||||
StartNamespace(hFile, "_detail")
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockEndFuncPtrDecl(hFile, spec, options)
|
||||
EndNamespace(hFile, "_detail")
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockBeginExtFuncPtrDecl(hFile, extName, spec, options)
|
||||
--Block containing all spec function declarations for a particular extension.
|
||||
--Useful for include-guards around extension function pointers.
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockEndExtFuncPtrDecl(hFile, extName, spec, options)
|
||||
--Block containing all spec function declarations for a particular extension.
|
||||
end
|
||||
|
||||
local function GenFuncPtrName(func, spec, options)
|
||||
return func.name
|
||||
end
|
||||
|
||||
local function GenFuncName(func, spec, options)
|
||||
return func.name
|
||||
end
|
||||
|
||||
local function GenFuncPtrTypedefName(func, spec, options)
|
||||
return "PFN" .. GenFuncPtrName(func, spec, options):upper()
|
||||
end
|
||||
|
||||
local function WriteFuncPtrTypedefStmt(hFile, func, spec, options)
|
||||
hFile:fmt("typedef %s (%s *%s)(%s);\n",
|
||||
common.GetFuncReturnType(func),
|
||||
spec.GetCodegenPtrType(),
|
||||
GenFuncPtrTypedefName(func, spec, options),
|
||||
common.GetFuncParamList(func))
|
||||
end
|
||||
|
||||
local function GenFuncPtrDefDirect(func, spec, options)
|
||||
return string.format("%s (%s *%s)(%s)",
|
||||
common.GetFuncReturnType(func),
|
||||
spec.GetCodegenPtrType(),
|
||||
GenFuncPtrName(func, spec, options),
|
||||
common.GetFuncParamList(func, true))
|
||||
end
|
||||
|
||||
local function GenFuncPtrDefTypedef(func, spec, options)
|
||||
return string.format("%s %s",
|
||||
GenFuncPtrTypedefName(func, spec, options),
|
||||
GenFuncPtrName(func, spec, options))
|
||||
end
|
||||
|
||||
function my_style.header.WriteFuncPtrDecl(hFile, func, spec, options)
|
||||
hFile:write("extern ",
|
||||
GenFuncPtrDefDirect(func, spec, options),
|
||||
";\n")
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockBeginFuncDecl(hFile, spec, options)
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockEndFuncDecl(hFile, spec, options)
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockBeginExtFuncDecl(hFile, extName, spec, options)
|
||||
--Block containing all spec function declarations for a particular extension.
|
||||
--Useful for include-guards around extension function pointers.
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockEndExtFuncDecl(hFile, extName, spec, options)
|
||||
--Block containing all spec function declarations for a particular extension.
|
||||
end
|
||||
|
||||
function my_style.header.WriteFuncDecl(hFile, func, spec, options)
|
||||
hFile:fmt("inline %s %s(%s){",
|
||||
common.GetFuncReturnType(func),
|
||||
GenFuncName(func, spec, options),
|
||||
common.GetFuncParamList(func, true))
|
||||
|
||||
if(common.DoesFuncReturnSomething(func)) then
|
||||
hFile:rawfmt('_detail::%s(%s);',
|
||||
GenFuncPtrName(func, spec, options),
|
||||
common.GetFuncParamCallList(func))
|
||||
else
|
||||
hFile:rawfmt('return _detail::%s(%s);',
|
||||
GenFuncPtrName(func, spec, options),
|
||||
common.GetFuncParamCallList(func))
|
||||
end
|
||||
|
||||
|
||||
hFile:rawwrite("}\n")
|
||||
end
|
||||
|
||||
|
||||
|
||||
function my_style.header.WriteBlockBeginSysDecl(hFile, spec, options)
|
||||
StartNamespace(hFile, "sys")
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockEndSysDecl(hFile, spec, options)
|
||||
EndNamespace(hFile, "sys")
|
||||
end
|
||||
|
||||
function my_style.header.WriteUtilityDecls(hFile, spec, options)
|
||||
--Write declarations for public utility stuff. Enums for return values, etc.
|
||||
end
|
||||
|
||||
function my_style.header.WriteMainLoaderFuncDecl(hFile, spec, options)
|
||||
hFile:fmt("%s::LoadTest LoadFunctions(%s);\n", extBlockNamespace, spec.GetLoaderParams())
|
||||
end
|
||||
|
||||
function my_style.header.WriteVersioningFuncDecls(hFile, spec, options)
|
||||
hFile:writeblock([[
|
||||
int GetMinorVersion();
|
||||
int GetMajorVersion();
|
||||
bool IsVersionGEQ(int majorVersion, int minorVersion);
|
||||
]])
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
-- Source code styling functions.
|
||||
function my_style.source.GetFilename(basename, options)
|
||||
return basename .. ".cpp"
|
||||
end
|
||||
|
||||
function my_style.source.WriteIncludes(hFile, basename, spec, options)
|
||||
hFile:writeblock([[
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
]])
|
||||
|
||||
local base = util.ParsePath(my_style.header.GetFilename(basename, options))
|
||||
hFile:fmt('#include "%s"\n', base)
|
||||
end
|
||||
|
||||
function my_style.source.WriteLoaderData(hFile, spec, options)
|
||||
hFile:writeblock(spec.GetLoaderFunc())
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockBeginDef(hFile, spec, options)
|
||||
if(#options.prefix > 0) then
|
||||
StartNamespace(hFile, options.prefix)
|
||||
end
|
||||
StartNamespace(hFile, spec.FuncNamePrefix())
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockEndDef(hFile, spec, options)
|
||||
EndNamespace(hFile, spec.FuncNamePrefix())
|
||||
if(#options.prefix > 0) then
|
||||
EndNamespace(hFile, options.prefix)
|
||||
end
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockBeginExtVarDef(hFile, spec, options)
|
||||
StartNamespace(hFile, extBlockNamespace)
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockEndExtVarDef(hFile, spec, options)
|
||||
EndNamespace(hFile, extBlockNamespace)
|
||||
end
|
||||
|
||||
function my_style.source.WriteExtVariableDef(hFile, extName,
|
||||
specData, spec, options)
|
||||
hFile:fmt("LoadTest %s;\n",
|
||||
GenExtensionVarName(extName, spec, options));
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockBeginPtrDefs(hFile, spec, options)
|
||||
StartNamespace(hFile, "_detail")
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockEndPtrDefs(hFile, spec, options)
|
||||
EndNamespace(hFile, "_detail")
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockBeginExtFuncPtrDef(hFile, extName, spec, options)
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockEndExtFuncPtrDef(hFile, extName, spec, options)
|
||||
end
|
||||
|
||||
function my_style.source.WriteFuncPtrDef(hFile, func, spec, options)
|
||||
WriteFuncPtrTypedefStmt(hFile, func, spec, options)
|
||||
hFile:write(GenFuncPtrDefTypedef(func, spec, options),
|
||||
" = 0;\n")
|
||||
end
|
||||
|
||||
local function GenExtLoaderFuncName(extName, spec, options)
|
||||
return "Load_" .. extName;
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockBeginExtLoader(hFile, extName, spec, options)
|
||||
hFile:fmt("static int %s()\n", GenExtLoaderFuncName(extName, spec, options))
|
||||
hFile:write("{\n")
|
||||
hFile:inc()
|
||||
hFile:write("int numFailed = 0;\n")
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockEndExtLoader(hFile, extName, spec, options)
|
||||
hFile:write "return numFailed;\n"
|
||||
hFile:dec()
|
||||
hFile:write("}\n")
|
||||
end
|
||||
|
||||
function my_style.source.WriteExtFuncLoader(hFile, func, spec, options)
|
||||
hFile:fmt('%s = reinterpret_cast<%s>(%s("%s%s"));\n',
|
||||
GenFuncPtrName(func, spec, options),
|
||||
GenFuncPtrTypedefName(func, spec, options),
|
||||
common.GetProcAddressName(spec),
|
||||
spec.FuncNamePrefix(), func.name)
|
||||
hFile:fmt('if(!%s) ++numFailed;\n', GenFuncPtrName(func, spec, options))
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockBeginCoreFuncPtrDef(hFile, version, spec, options)
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockEndCoreFuncPtrDef(hFile, version, spec, options)
|
||||
end
|
||||
|
||||
local function GenCoreLoaderFuncName(version, spec, options)
|
||||
return "LoadCoreFunctions"
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockBeginCoreLoader(hFile, version, spec, options)
|
||||
hFile:fmt("static int %s()\n", GenCoreLoaderFuncName(version, spec, options))
|
||||
hFile:write("{\n")
|
||||
hFile:inc()
|
||||
hFile:write("int numFailed = 0;\n")
|
||||
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockEndCoreLoader(hFile, version, spec, options)
|
||||
hFile:write "return numFailed;\n"
|
||||
hFile:dec()
|
||||
hFile:write("}\n")
|
||||
end
|
||||
|
||||
function my_style.source.WriteCoreFuncLoader(hFile, func, spec, options)
|
||||
hFile:fmt('%s = reinterpret_cast<%s>(%s("%s%s"));\n',
|
||||
GenFuncPtrName(func, spec, options),
|
||||
GenFuncPtrTypedefName(func, spec, options),
|
||||
common.GetProcAddressName(spec),
|
||||
spec.FuncNamePrefix(), func.name)
|
||||
|
||||
--Special hack for DSA_EXT functions in core functions.
|
||||
--They do not count against the loaded count.
|
||||
if(func.name:match("EXT$")) then
|
||||
hFile:write("//An EXT_direct_state_access-based function. Don't count it if it fails to load.\n")
|
||||
else
|
||||
hFile:fmt('if(!%s) ++numFailed;\n', GenFuncPtrName(func, spec, options))
|
||||
end
|
||||
end
|
||||
|
||||
function my_style.source.WriteExtStringFuncDef(hFile, specData, spec, options, funcSeen)
|
||||
if(funcSeen[spec.GetExtStringFuncName()]) then
|
||||
return
|
||||
end
|
||||
|
||||
--Check to see if its something we have to load.
|
||||
local function FindFuncName(funcName)
|
||||
for _, func in ipairs(specData.funcData.functions) do
|
||||
if(func.name == funcName) then
|
||||
return func
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
local extStringFunc = FindFuncName(spec.GetExtStringFuncName())
|
||||
|
||||
if(extStringFunc) then
|
||||
hFile:write("\n")
|
||||
WriteFuncPtrTypedefStmt(hFile, extStringFunc, spec, options)
|
||||
hFile:write("static ", GenFuncPtrDefTypedef(extStringFunc, spec, options),
|
||||
" = 0;\n")
|
||||
hFile:write("\n")
|
||||
end
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockBeginSysDef(hFile, spec, options)
|
||||
StartNamespace(hFile, "sys")
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockEndSysDef(hFile, spec, options)
|
||||
EndNamespace(hFile, "sys")
|
||||
end
|
||||
|
||||
function my_style.source.WriteUtilityDefs(hFile, specData, spec, options)
|
||||
--Write our mapping table definitions.
|
||||
StartNamespace(hFile)
|
||||
hFile:writeblock[[
|
||||
typedef int (*PFN_LOADEXTENSION)();
|
||||
struct MapEntry
|
||||
{
|
||||
MapEntry(const char *_extName, exts::LoadTest *_extVariable)
|
||||
: extName(_extName)
|
||||
, extVariable(_extVariable)
|
||||
, loaderFunc(0)
|
||||
{}
|
||||
|
||||
MapEntry(const char *_extName, exts::LoadTest *_extVariable, PFN_LOADEXTENSION _loaderFunc)
|
||||
: extName(_extName)
|
||||
, extVariable(_extVariable)
|
||||
, loaderFunc(_loaderFunc)
|
||||
{}
|
||||
|
||||
const char *extName;
|
||||
exts::LoadTest *extVariable;
|
||||
PFN_LOADEXTENSION loaderFunc;
|
||||
};
|
||||
|
||||
struct MapCompare
|
||||
{
|
||||
MapCompare(const char *test_) : test(test_) {}
|
||||
bool operator()(const MapEntry &other) { return strcmp(test, other.extName) == 0; }
|
||||
const char *test;
|
||||
};
|
||||
|
||||
]]
|
||||
|
||||
--Write the table initialization function.
|
||||
hFile:write "void InitializeMappingTable(std::vector<MapEntry> &table)\n"
|
||||
hFile:write "{\n"
|
||||
hFile:inc()
|
||||
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, _detail::%s));\n',
|
||||
spec.ExtNamePrefix() .. extName,
|
||||
GenExtensionVarName(extName, spec, options),
|
||||
GenExtLoaderFuncName(extName, spec, options))
|
||||
else
|
||||
hFile:fmt('table.push_back(MapEntry("%s", &exts::%s));\n',
|
||||
spec.ExtNamePrefix() .. extName,
|
||||
GenExtensionVarName(extName, spec, options))
|
||||
end
|
||||
end
|
||||
hFile:dec()
|
||||
hFile:write "}\n"
|
||||
hFile:write "\n"
|
||||
|
||||
--Write the function to clear the extension variables.
|
||||
hFile:fmt("void ClearExtensionVars()\n")
|
||||
hFile:write("{\n")
|
||||
hFile:inc()
|
||||
for _, extName in ipairs(options.extensions) do
|
||||
hFile:fmt('exts::%s = exts::LoadTest();\n',
|
||||
GenExtensionVarName(extName, spec, options))
|
||||
end
|
||||
hFile:dec()
|
||||
hFile:write("}\n")
|
||||
hFile:write "\n"
|
||||
|
||||
--Write a function that loads an extension by name. It is called when
|
||||
--processing, so it should also set the extension variable based on the load.
|
||||
hFile:writeblock([[
|
||||
void LoadExtByName(std::vector<MapEntry> &table, const char *extensionName)
|
||||
{
|
||||
std::vector<MapEntry>::iterator entry = std::find_if(table.begin(), table.end(), MapCompare(extensionName));
|
||||
|
||||
if(entry != table.end())
|
||||
{
|
||||
if(entry->loaderFunc)
|
||||
(*entry->extVariable) = exts::LoadTest(true, entry->loaderFunc());
|
||||
else
|
||||
(*entry->extVariable) = exts::LoadTest(true, 0);
|
||||
}
|
||||
}
|
||||
]])
|
||||
EndNamespace(hFile)
|
||||
hFile:write "\n"
|
||||
end
|
||||
|
||||
local function GenQualifier(spec, options)
|
||||
local ret = ""
|
||||
if(#options.prefix > 0) then
|
||||
ret = options.prefix .. "::"
|
||||
end
|
||||
ret = ret .. spec.FuncNamePrefix() .. "::"
|
||||
return ret
|
||||
end
|
||||
|
||||
local function GenQualifiedEnumName(enum, spec, options)
|
||||
return GenQualifier(spec, options) .. GenEnumName(enum, spec, options)
|
||||
end
|
||||
|
||||
local function GenQualifiedFuncPtrName(func, spec, options)
|
||||
return GenQualifier(spec, options) .. "_detail::"
|
||||
.. GenFuncPtrName(func, spec, options)
|
||||
end
|
||||
|
||||
local function WriteAncillaryFuncs(hFile, specData, spec, options)
|
||||
local indexed = spec.GetIndexedExtStringFunc(options);
|
||||
if(indexed) then
|
||||
for _, func in ipairs(specData.funcData.functions) do
|
||||
if(indexed[1] == func.name) then
|
||||
indexed[1] = func
|
||||
end
|
||||
if(indexed[3] == func.name) then
|
||||
indexed[3] = func
|
||||
end
|
||||
end
|
||||
for _, enum in ipairs(specData.enumerators) do
|
||||
if(indexed[2] == enum.name) then
|
||||
indexed[2] = enum
|
||||
end
|
||||
if(indexed[4] == enum.name) then
|
||||
indexed[4] = enum
|
||||
end
|
||||
end
|
||||
|
||||
hFile:writeblock([[
|
||||
static void ProcExtsFromExtList(std::vector<MapEntry> &table)
|
||||
{
|
||||
GLint iLoop;
|
||||
GLint iNumExtensions = 0;
|
||||
]] .. GenQualifiedFuncPtrName(indexed[1], spec, options)
|
||||
.. [[(]] .. GenQualifiedEnumName(indexed[2], spec, options)
|
||||
.. [[, &iNumExtensions);
|
||||
|
||||
for(iLoop = 0; iLoop < iNumExtensions; iLoop++)
|
||||
{
|
||||
const char *strExtensionName = (const char *)]] ..
|
||||
GenQualifiedFuncPtrName(indexed[3], spec, options) ..
|
||||
[[(]] .. GenQualifiedEnumName(indexed[4], spec, options) .. [[, iLoop);
|
||||
LoadExtByName(table, strExtensionName);
|
||||
}
|
||||
}
|
||||
]])
|
||||
else
|
||||
hFile:writeblock(common.GetProcessExtsFromStringFunc(
|
||||
"LoadExtByName(table, %s)", ", std::vector<MapEntry> &table"))
|
||||
end
|
||||
|
||||
hFile:write "\n"
|
||||
|
||||
return indexed
|
||||
end
|
||||
|
||||
|
||||
local function WriteInMainFuncLoader(hFile, func, spec, options)
|
||||
hFile:fmt('_detail::%s = reinterpret_cast<_detail::%s>(%s("%s%s"));\n',
|
||||
GenFuncPtrName(func, spec, options),
|
||||
GenFuncPtrTypedefName(func, spec, options),
|
||||
common.GetProcAddressName(spec),
|
||||
spec.FuncNamePrefix(), func.name)
|
||||
hFile:fmt('if(!_detail::%s) return exts::LoadTest();\n',
|
||||
GenFuncPtrName(func, spec, options))
|
||||
end
|
||||
|
||||
function my_style.source.WriteMainLoaderFunc(hFile, specData, spec, options)
|
||||
StartNamespace(hFile)
|
||||
local indexed = WriteAncillaryFuncs(hFile, specData, spec, options)
|
||||
EndNamespace(hFile)
|
||||
|
||||
hFile:write "\n"
|
||||
|
||||
hFile:fmt("exts::LoadTest LoadFunctions(%s)\n", spec.GetLoaderParams())
|
||||
hFile:write("{\n")
|
||||
hFile:inc()
|
||||
hFile:writeblock[[
|
||||
ClearExtensionVars();
|
||||
std::vector<MapEntry> table;
|
||||
InitializeMappingTable(table);
|
||||
]]
|
||||
hFile:write("\n")
|
||||
|
||||
if(indexed) then
|
||||
WriteInMainFuncLoader(hFile, indexed[1], spec, options)
|
||||
WriteInMainFuncLoader(hFile, indexed[3], spec, options)
|
||||
hFile:write("\n")
|
||||
hFile:write("ProcExtsFromExtList(table);\n")
|
||||
else
|
||||
local extListName, needLoad = spec.GetExtStringFuncName()
|
||||
if(needLoad) then
|
||||
for _, func in ipairs(specData.funcData.functions) do
|
||||
if(extListName == func.name) then
|
||||
extListName = func
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
WriteInMainFuncLoader(hFile, extListName, spec, options)
|
||||
|
||||
extListName = GenQualifiedFuncPtrName(extListName, spec, options);
|
||||
end
|
||||
|
||||
local function EnumResolve(enumName)
|
||||
return GenQualifiedEnumName(specData.enumtable[enumName], spec, options)
|
||||
end
|
||||
|
||||
hFile:write "\n"
|
||||
hFile:fmt("ProcExtsFromExtString((const char *)%s(%s), table);\n",
|
||||
extListName,
|
||||
spec.GetExtStringParamList(EnumResolve))
|
||||
end
|
||||
|
||||
if(options.version) then
|
||||
hFile:write "\n"
|
||||
hFile:fmt("int numFailed = _detail::%s();\n",
|
||||
GenCoreLoaderFuncName(options.version, spec, options))
|
||||
|
||||
hFile:write("return exts::LoadTest(true, numFailed);\n")
|
||||
else
|
||||
hFile:fmt("return exts::LoadTest(true, 0);\n")
|
||||
end
|
||||
|
||||
|
||||
hFile:dec()
|
||||
hFile:write("}\n")
|
||||
end
|
||||
|
||||
function my_style.source.WriteVersioningFuncs(hFile, specData, spec, options)
|
||||
hFile:fmt("static int g_major_version = 0;\n")
|
||||
hFile:fmt("static int g_minor_version = 0;\n")
|
||||
hFile:write "\n"
|
||||
|
||||
if(tonumber(options.version) >= 3.0) then
|
||||
hFile:writeblock([[
|
||||
static void GetGLVersion()
|
||||
{
|
||||
_detail::GetIntegerv(MAJOR_VERSION, &g_major_version);
|
||||
_detail::GetIntegerv(MINOR_VERSION, &g_minor_version);
|
||||
}
|
||||
]])
|
||||
else
|
||||
hFile:writeblock(common.GetParseVersionFromString())
|
||||
hFile:write "\n"
|
||||
|
||||
hFile:writeblock([[
|
||||
static void GetGLVersion()
|
||||
{
|
||||
ParseVersionFromString(&g_major_version, &g_minor_version, (const char *)_detail::GetString(VERSION));
|
||||
}
|
||||
]])
|
||||
end
|
||||
|
||||
hFile:write "\n"
|
||||
hFile:writeblock([[
|
||||
int GetMajorVersion()
|
||||
{
|
||||
if(g_major_version == 0)
|
||||
GetGLVersion();
|
||||
return g_major_version;
|
||||
}
|
||||
]])
|
||||
hFile:write "\n"
|
||||
|
||||
hFile:writeblock([[
|
||||
int GetMinorVersion()
|
||||
{
|
||||
if(g_major_version == 0) //Yes, check the major version to get the minor one.
|
||||
GetGLVersion();
|
||||
return g_minor_version;
|
||||
}
|
||||
]])
|
||||
hFile:write "\n"
|
||||
|
||||
hFile:writeblock([[
|
||||
bool IsVersionGEQ(int majorVersion, int minorVersion)
|
||||
{
|
||||
if(g_major_version == 0)
|
||||
GetGLVersion();
|
||||
|
||||
if(majorVersion > g_major_version) return true;
|
||||
if(majorVersion < g_major_version) return false;
|
||||
if(minorVersion >= g_minor_version) return true;
|
||||
return false;
|
||||
}
|
||||
]])
|
||||
|
||||
end
|
||||
|
||||
|
||||
--------------------------------------------------
|
||||
-- Style retrieval machinery
|
||||
|
||||
local function Create()
|
||||
return common.DeepCopyTable(my_style), struct
|
||||
end
|
||||
|
||||
return { Create = Create }
|
|
@ -1,229 +0,0 @@
|
|||
--[[ The function GetOptions retrieves the list of extensions and other command-line options. It pulls data from a multitude of sources, though it begins with the command-line.
|
||||
|
||||
It takes the following parameters:
|
||||
- An array of the command-line options.
|
||||
|
||||
It returns a table containing the following entries:
|
||||
- spec: What specification will be generated. One of the following:
|
||||
- gl: Uses the OpenGL spec. Default
|
||||
- glX: Uses the glX spec.
|
||||
- wgl: Uses the WGL "spec".
|
||||
- version: OpenGL version to export. All core features from that version and below will be exported. Will only be present when exporting "gl" loaders.
|
||||
- profile: OpenGL profile to use. Default is chosen based on GL version. One of the following:
|
||||
- core: Default
|
||||
- compatibility:
|
||||
- extensions: A list of OpenGL extensions to export.
|
||||
- outname: The base filename of the file to create.
|
||||
- style: A string containing the particular style of binding. This can be:
|
||||
- pointer_c: The default. The functions will be stored in pointers exposed to the user. #defines will be used to rename the pointers to the core GL function names.
|
||||
- pointer_cpp: The functions will be stored in pointers, but the pointers and enumerators will be placed in the namespace "gl".
|
||||
- indent: A string that defines the indentation style for the output.
|
||||
- tab: Uses tabs. Default.
|
||||
- space: Uses 2 spaces.
|
||||
- prefix: A prefix to be added to the names of identifiers that must be global, while avoiding name clashes. This is useful if you want to have different sets of bindings to different APIs (like a GL 3.3 and 2.1 binding). Defaults to the empty string.
|
||||
]]
|
||||
|
||||
local cmd = require "CmdLineOptions"
|
||||
local util = require "util"
|
||||
local Styles = require "Styles"
|
||||
local Specs = require "Specs"
|
||||
|
||||
local function FixupExtensionName(ext)
|
||||
return ext
|
||||
end
|
||||
|
||||
local parseOpts = cmd.CreateOptionGroup()
|
||||
parseOpts:enum(
|
||||
"spec",
|
||||
"spec",
|
||||
"Specification to use.",
|
||||
{"gl", "glX", "wgl"},
|
||||
1)
|
||||
parseOpts:value(
|
||||
"version",
|
||||
"version",
|
||||
{"OpenGL version to export.", "Only use this with the 'gl' spec."},
|
||||
nil,
|
||||
true)
|
||||
parseOpts:enum(
|
||||
"profile",
|
||||
"profile",
|
||||
{"OpenGL profile to use.", "Only use this with the 'gl' spec."},
|
||||
{"core", "compatibility"},
|
||||
1,
|
||||
true)
|
||||
parseOpts:enum(
|
||||
"style",
|
||||
"style",
|
||||
{"Export style."},
|
||||
Styles.GetStyleList(),
|
||||
1)
|
||||
parseOpts:enum(
|
||||
"indent",
|
||||
"indent",
|
||||
{"Indentation style."},
|
||||
{"tab", "space"},
|
||||
1)
|
||||
parseOpts:array(
|
||||
"exts",
|
||||
"extensions",
|
||||
{"A list of extensions to export."},
|
||||
FixupExtensionName,
|
||||
true)
|
||||
parseOpts:array_single(
|
||||
"ext",
|
||||
"extensions",
|
||||
{"A single extension name to export."},
|
||||
FixupExtensionName,
|
||||
true)
|
||||
parseOpts:array_single(
|
||||
"extfile",
|
||||
"extfiles",
|
||||
{"A file to load extensions from.", "Files are always relative to the current directory."},
|
||||
nil,
|
||||
true)
|
||||
parseOpts:array_single(
|
||||
"stdext",
|
||||
"stdexts",
|
||||
{"A file to load extensions from, within the ./extfiles directory.", "These are the standard extension files."},
|
||||
nil,
|
||||
true)
|
||||
parseOpts:value(
|
||||
"prefix",
|
||||
"prefix",
|
||||
{
|
||||
"String to prefix to various globals. Set this to ",
|
||||
"prevent interference with multiple loaders."
|
||||
},
|
||||
"")
|
||||
parseOpts:pos_opt(
|
||||
1,
|
||||
"outname",
|
||||
"Base filename (sans extension)",
|
||||
"outname")
|
||||
|
||||
local extFileLines;
|
||||
|
||||
local function LoadExtFile(extensions, extfilename, baseDir)
|
||||
if(baseDir) then
|
||||
extfilename = baseDir .. extfilename
|
||||
end
|
||||
local hFile = assert(io.open(extfilename, "r"), "Could not find the file " .. extfilename)
|
||||
|
||||
for line in hFile:lines() do
|
||||
for _, test in ipairs(extFileLines) do
|
||||
local matches = {line:match(test.pttrn)}
|
||||
if(#matches ~= 0) then
|
||||
test.proc(extensions, baseDir, unpack(matches))
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
hFile:close()
|
||||
end
|
||||
|
||||
--Function gets the list of extensions, the base directory of the currently
|
||||
--processing file, and whatever matches came from the pattern.
|
||||
extFileLines =
|
||||
{
|
||||
{
|
||||
pttrn = '^%s*%#include [%"](.+)[%"]',
|
||||
proc = function(extensions, basedir, file)
|
||||
local name, dir = util.ParsePath(file)
|
||||
if(baseDir and dir) then
|
||||
dir = baseDir .. dir
|
||||
elseif(baseDir) then
|
||||
dir = baseDir
|
||||
end
|
||||
|
||||
file = name
|
||||
|
||||
LoadExtFile(extensions, file, dir)
|
||||
end,
|
||||
},
|
||||
{
|
||||
pttrn = '^%s*%#include [%<](.+)[%>]',
|
||||
proc = function(extensions, basedir, file)
|
||||
local name, dir = util.ParsePath(SysRelPath(file))
|
||||
--Ignore the base directory; we start with the system directory.
|
||||
|
||||
LoadExtFile(extensions, name, dir)
|
||||
end,
|
||||
},
|
||||
{
|
||||
pttrn = '^%s*%-%-',
|
||||
proc = function(extensions, basedir) --[[Ignore the line. Comment]] end,
|
||||
},
|
||||
{
|
||||
pttrn = '^%s*%/%/',
|
||||
proc = function(extensions, basedir) --[[Ignore the line. Comment]] end,
|
||||
},
|
||||
{
|
||||
pttrn = '(%S+)',
|
||||
proc = function(extensions, basedir, ext)
|
||||
table.insert(extensions, ext)
|
||||
end,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
local function FixupExtname(ext)
|
||||
--Cull the (W)GL(X)_ part of the name, if any.
|
||||
|
||||
local bareName = ext:match("W?GLX?_(.+)")
|
||||
|
||||
return bareName or ext
|
||||
end
|
||||
|
||||
local optTbl = {}
|
||||
|
||||
function optTbl.GetOptions(cmd_line)
|
||||
local options, pos_args = parseOpts:ProcessCmdLine(cmd_line)
|
||||
|
||||
local spec = Specs.GetSpec(options.spec)
|
||||
|
||||
if(options.version) then
|
||||
--Check the version against the allowed versions.
|
||||
local versionTest = util.InvertTable(spec.GetCoreVersions())
|
||||
parseOpts:AssertParse(versionTest[options.version], "The version " .. options.version .. " is not a legal version number.")
|
||||
else
|
||||
--Check to see that no versions are offered.
|
||||
parseOpts:AssertParse(#spec.GetCoreVersions() == 0, "You must specify a version for the specification " .. options.spec)
|
||||
end
|
||||
|
||||
spec.VerifyOptions(options, parseOpts)
|
||||
|
||||
--Load and collate the extensions.
|
||||
options.extensions = options.extensions or {}
|
||||
options.extfiles = options.extfiles or {}
|
||||
options.stdexts = options.stdexts or {}
|
||||
|
||||
for _, file in ipairs(options.extfiles) do
|
||||
LoadExtFile(options.extensions, util.ParsePath(file)) --vararg
|
||||
end
|
||||
|
||||
--Local extension files.
|
||||
for _, file in ipairs(options.stdexts) do
|
||||
LoadExtFile(options.extensions, util.ParsePath(SysRelPath("extfiles/" .. file))) --vararg
|
||||
end
|
||||
|
||||
--Fixup names and remove duplicates.
|
||||
local dups = {}
|
||||
local exts = {}
|
||||
for _, ext in ipairs(options.extensions) do
|
||||
local fixExt = FixupExtname(ext)
|
||||
if(not dups[fixExt]) then
|
||||
exts[#exts + 1] = fixExt
|
||||
dups[fixExt] = true
|
||||
end
|
||||
end
|
||||
|
||||
options.extensions = exts
|
||||
options.extfiles = nil
|
||||
options.stdexts = nil
|
||||
|
||||
return options
|
||||
end
|
||||
|
||||
return optTbl
|
|
@ -1,140 +0,0 @@
|
|||
--[[
|
||||
The function, LoadLuaSpec exposed here will load a spec.lua file. It takes a filename
|
||||
pointing to a spec.lua file.
|
||||
|
||||
This function will also add some features to the object before returning it.
|
||||
|
||||
The format will be as defined in LuaFormat.md, with the following addendums:
|
||||
|
||||
- enumtable: A table of enumerators, indexed by their names.
|
||||
- functable: A table of functions, indexed by their names.
|
||||
- extdefs: This is a table of extensions, indexed by extension name.
|
||||
Each entry contains:
|
||||
-- enums: An array of enumerators. These enumerators are the entries in the main enum array.
|
||||
-- funcs: An array of functions. These functions are the entries in the main funcData array.
|
||||
- core_profiledefs: This is a table of core versions, listing all the funcs/enums in the core profile of the spec.
|
||||
-- enums: An array of enumerators. These enumerators are the entries in the main enum array.
|
||||
-- funcs: An array of functions. These functions are the entries in the main funcData array.
|
||||
- compat_profiledefs: This is a table of core versions, listing all the funcs/enums in the compatibility profile of the spec. As per `coredefs`.
|
||||
|
||||
|
||||
All enumerators and functions are found in one of these two lists. Some of them are in both.
|
||||
|
||||
Other changes are:
|
||||
- Fixes for certain extensions. Certain extensions are non-core, but the enums and functions have no suffixes as if they were core.
|
||||
]]
|
||||
|
||||
local util = require "util"
|
||||
|
||||
|
||||
local load = {}
|
||||
|
||||
function load.LoadLuaSpec(luaFilename, spec)
|
||||
|
||||
local listOfCoreVersions = spec.GetCoreVersions()
|
||||
|
||||
local specData = dofile(luaFilename)
|
||||
|
||||
specData.extdefs = {}
|
||||
specData.coredefs = {}
|
||||
specData.enumtable = {}
|
||||
specData.functable = {}
|
||||
local extdefs = specData.extdefs
|
||||
local coredefs = specData.coredefs
|
||||
local enumtable = specData.enumtable
|
||||
local functable = specData.functable
|
||||
|
||||
local function GetCore(version)
|
||||
if(not coredefs[version]) then
|
||||
local coredef = {}
|
||||
coredefs[version] = coredef
|
||||
coredef.enums = {}
|
||||
coredef.funcs = {}
|
||||
end
|
||||
|
||||
return coredefs[version]
|
||||
end
|
||||
|
||||
local function GetExt(extName)
|
||||
if(not extdefs[extName]) then
|
||||
local extdef = {}
|
||||
extdefs[extName] = extdef
|
||||
extdef.enums = {}
|
||||
extdef.funcs = {}
|
||||
end
|
||||
|
||||
return extdefs[extName]
|
||||
end
|
||||
|
||||
--Add all extensions to the extdefs.
|
||||
for i, extName in ipairs(specData.extensions) do
|
||||
GetExt(extName)
|
||||
end
|
||||
|
||||
for i, enum in ipairs(specData.enumerators) do
|
||||
if(not enum.name) then print(enum.value) end
|
||||
enumtable[enum.name] = enum
|
||||
|
||||
if(enum.extensions) then
|
||||
for k, extName in ipairs(enum.extensions) do
|
||||
table.insert(GetExt(extName).enums, enum)
|
||||
end
|
||||
end
|
||||
|
||||
if(enum.core) then
|
||||
for _, coreSpec in ipairs(enum.core) do
|
||||
if(coreSpec[2] == "core") then
|
||||
table.insert(GetCore(coreSpec[1]).enums, enum)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for i, func in ipairs(specData.funcData.functions) do
|
||||
functable[func.name] = func
|
||||
|
||||
if(func.extensions) then
|
||||
for k, extName in ipairs(func.extensions) do
|
||||
table.insert(GetExt(extName).funcs, func)
|
||||
end
|
||||
end
|
||||
|
||||
if(func.core) then
|
||||
for _, coreSpec in ipairs(func.core) do
|
||||
if(coreSpec[2] == "core") then
|
||||
table.insert(GetCore(coreSpec[1]).funcs, func)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--Sort functions and enums by name. Just for nicer presentation.
|
||||
for extName, data in pairs(extdefs) do
|
||||
table.sort(data.enums, function(lhs, rhs) return lhs.name < rhs.name end)
|
||||
table.sort(data.funcs, function(lhs, rhs) return lhs.name < rhs.name end)
|
||||
end
|
||||
|
||||
for version, data in pairs(coredefs) do
|
||||
table.sort(data.enums, function(lhs, rhs) return lhs.name < rhs.name end)
|
||||
table.sort(data.funcs, function(lhs, rhs) return lhs.name < rhs.name end)
|
||||
end
|
||||
|
||||
--[[
|
||||
local coreextsByVersion = spec.GetCoreExts()
|
||||
|
||||
local coreexts = {}
|
||||
specData.coreexts = coreexts
|
||||
for coreVersion, coreExtList in pairs(coreextsByVersion) do
|
||||
for i, coreExt in pairs(coreExtList) do
|
||||
coreexts[coreExt] = {name = coreExt, version = coreVersion}
|
||||
end
|
||||
end
|
||||
]]
|
||||
|
||||
return specData
|
||||
end
|
||||
|
||||
return load
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
|
||||
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
|
|
@ -1,468 +0,0 @@
|
|||
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, spec, options)
|
||||
hFile:fmt("typedef %s (%s *%s)(%s);\n",
|
||||
common.GetFuncReturnType(func),
|
||||
spec.GetCodegenPtrType(),
|
||||
GetFuncPtrTypedefName(func, spec, options),
|
||||
common.GetFuncParamList(func))
|
||||
end
|
||||
|
||||
local function GetFuncPtrDefDirect(func, spec, options)
|
||||
return string.format("%s (%s *%s)(%s)",
|
||||
common.GetFuncReturnType(func),
|
||||
spec.GetCodegenPtrType(),
|
||||
GetFuncPtrName(func, spec, options),
|
||||
common.GetFuncParamList(func, true))
|
||||
end
|
||||
|
||||
local function GetFuncPtrDefTypedef(func, 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, spec, options, funcSeen)
|
||||
if(funcSeen[func.name]) then return end
|
||||
|
||||
hFile:write("extern ", GetFuncPtrDefDirect(func, 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]", mapTableName, arrayLength)
|
||||
if(arrayLength == 1) then
|
||||
hFile:rawwrite "; //This is intensionally left uninitialized. \n"
|
||||
else
|
||||
hFile:rawwrite " = \n"
|
||||
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"
|
||||
end
|
||||
|
||||
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.enumerators) 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]
|
||||
funcName = "InternalGetExtensionString"
|
||||
|
||||
hFile:fmt("typedef %s (%s *MYGETEXTSTRINGPROC)(%s);\n",
|
||||
common.GetFuncReturnType(func),
|
||||
spec.GetCodegenPtrType(),
|
||||
common.GetFuncParamList(func))
|
||||
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, spec, options, funcSeen)
|
||||
if(funcSeen[func.name]) then return end
|
||||
|
||||
WriteFuncPtrTypedefStmt(hFile, func, spec, options)
|
||||
hFile:fmt("static %s %s Switch_%s(%s);\n",
|
||||
common.GetFuncReturnType(func),
|
||||
spec.GetCodegenPtrType(),
|
||||
func.name,
|
||||
common.GetFuncParamList(func, true))
|
||||
end
|
||||
|
||||
local defs = {}
|
||||
src.defs = defs
|
||||
|
||||
function defs.WriteFunction(hFile, func, spec, options, funcSeen)
|
||||
if(funcSeen[func.name]) then return end
|
||||
|
||||
hFile:fmt("%s = Switch_%s;\n",
|
||||
GetFuncPtrDefTypedef(func, spec, options),
|
||||
func.name)
|
||||
end
|
||||
|
||||
local switch = {}
|
||||
src.switch = switch
|
||||
|
||||
function switch.WriteFunction(hFile, func, spec, options, funcSeen)
|
||||
if(funcSeen[func.name]) then return end
|
||||
|
||||
hFile:fmt("static %s %s Switch_%s(%s)\n",
|
||||
common.GetFuncReturnType(func),
|
||||
spec.GetCodegenPtrType(),
|
||||
func.name,
|
||||
common.GetFuncParamList(func, 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)) then
|
||||
hFile:fmt('%s(%s);\n',
|
||||
GetFuncPtrName(func, spec, options),
|
||||
common.GetFuncParamCallList(func))
|
||||
else
|
||||
hFile:fmt('return %s(%s);\n',
|
||||
GetFuncPtrName(func, spec, options),
|
||||
common.GetFuncParamCallList(func))
|
||||
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),
|
||||
func.name,
|
||||
common.GetFuncParamList(func, 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)) then
|
||||
hFile:fmt('%s(%s);\n',
|
||||
GetFuncPtrName(func, spec, options),
|
||||
common.GetFuncParamCallList(func))
|
||||
else
|
||||
hFile:fmt('return %s(%s);\n',
|
||||
GetFuncPtrName(func, spec, options),
|
||||
common.GetFuncParamCallList(func))
|
||||
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, 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 }
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
|
||||
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="MainNamespace(hFile, spec, options)",
|
||||
{ type="write", name="LargeHeader(hFile, value, options)", value="Extension Variables", },
|
||||
{ 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="MainNamespace(hFile, spec, options)",
|
||||
{ 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"},
|
||||
{ type="block", name="Struct(hFile, spec, options)", style="init",
|
||||
common.Functions(),
|
||||
},
|
||||
{ type="blank"},
|
||||
sys_functions,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
my_struct = struct.BuildStructure(my_struct)
|
||||
return my_struct
|
|
@ -1,470 +0,0 @@
|
|||
local util = require "util"
|
||||
local struct = require "NoloadCpp_Struct"
|
||||
local common = require "CommonStyle"
|
||||
|
||||
--------------------------------------
|
||||
-- Common functions.
|
||||
local function GetIncludeGuard(spec, options)
|
||||
local temp =
|
||||
options.prefix .. spec.GetIncludeGuardString() .. "_NOLOAD_STYLE_HPP"
|
||||
return temp:upper()
|
||||
end
|
||||
|
||||
local function GetFuncPtrName(func, spec, options)
|
||||
return func.name
|
||||
end
|
||||
|
||||
local function GetFuncPtrTypedefName(func, spec, options)
|
||||
return "PFN" .. GetFuncPtrName(func, spec, options):upper() .. "PROC"
|
||||
end
|
||||
|
||||
local function WriteFuncPtrTypedefStmt(hFile, func, spec, options)
|
||||
hFile:fmt("typedef %s (%s *%s)(%s);\n",
|
||||
common.GetFuncReturnType(func),
|
||||
spec.GetCodegenPtrType(),
|
||||
GetFuncPtrTypedefName(func, spec, options),
|
||||
common.GetFuncParamList(func))
|
||||
end
|
||||
|
||||
local function GetFuncPtrDefDirect(func, spec, options)
|
||||
return string.format("%s (%s *%s)(%s)",
|
||||
common.GetFuncReturnType(func),
|
||||
spec.GetCodegenPtrType(),
|
||||
GetFuncPtrName(func, spec, options),
|
||||
common.GetFuncParamList(func, true))
|
||||
end
|
||||
|
||||
local function GetFuncPtrDefTypedef(func, 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.WriteBlockBeginMainNamespace(hFile, spec, options)
|
||||
if(#options.prefix > 0) then
|
||||
common.WriteNamespaceBegin(hFile, options.prefix)
|
||||
end
|
||||
|
||||
common.WriteNamespaceBegin(hFile, spec.FuncNamePrefix())
|
||||
end
|
||||
|
||||
function my_style.WriteBlockEndMainNamespace(hFile, spec, options)
|
||||
common.WriteNamespaceEnd(hFile, spec.FuncNamePrefix())
|
||||
|
||||
if(#options.prefix > 0) then
|
||||
common.WriteNamespaceEnd(hFile, options.prefix)
|
||||
end
|
||||
end
|
||||
|
||||
function my_style.WriteBlockBeginExtVariables(hFile, spec, options)
|
||||
common.WriteNamespaceBegin(hFile, "exts")
|
||||
end
|
||||
|
||||
function my_style.WriteBlockEndExtVariables(hFile, spec, options)
|
||||
common.WriteNamespaceEnd(hFile, "exts")
|
||||
end
|
||||
|
||||
function my_style.WriteBlockBeginSystem(hFile, spec, options)
|
||||
common.WriteNamespaceBegin(hFile, "sys")
|
||||
end
|
||||
|
||||
function my_style.WriteBlockEndSystem(hFile, spec, options)
|
||||
common.WriteNamespaceEnd(hFile, "sys")
|
||||
end
|
||||
|
||||
|
||||
---------------------------------------------
|
||||
-- Header functions.
|
||||
local hdr = {}
|
||||
my_style.hdr = hdr
|
||||
|
||||
function hdr.GetFilename(basename, spec, options)
|
||||
return basename .. ".hpp"
|
||||
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 bool var_%s;\n", extName)
|
||||
end
|
||||
|
||||
function hdr.WriteBlockBeginEnumerators(hFile, spec, options)
|
||||
hFile:writeblock("enum\n{\n")
|
||||
hFile:inc()
|
||||
end
|
||||
|
||||
function hdr.WriteBlockEndEnumerators(hFile, spec, options)
|
||||
hFile:dec()
|
||||
hFile:write("};\n")
|
||||
end
|
||||
|
||||
function hdr.WriteEnumerator(hFile, enum, enumTable, spec, options, enumSeen)
|
||||
if(enumSeen[enum.name]) then
|
||||
hFile:fmt("//%s seen in %s\n", enum.name, enumSeen[enum.name])
|
||||
else
|
||||
local name = common.GetCppEnumName(enum)
|
||||
hFile:fmt("%s%s= %s,\n",
|
||||
name,
|
||||
common.GetNameLengthPadding(name, 33),
|
||||
common.ResolveEnumValue(enum, enumTable))
|
||||
end
|
||||
end
|
||||
|
||||
function hdr.WriteFunction(hFile, func, spec, options, funcSeen)
|
||||
if(funcSeen[func.name]) then return end
|
||||
|
||||
hFile:write("extern ", GetFuncPtrDefDirect(func, spec, options), ";\n")
|
||||
end
|
||||
|
||||
function hdr.WriteSetupFunction(hFile, specData, spec, options)
|
||||
hFile:fmt("void CheckExtensions(%s);\n", 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 .. ".cpp"
|
||||
end
|
||||
|
||||
function src.WriteIncludes(hFile, basename, spec, options)
|
||||
hFile:writeblock([[
|
||||
#include <algorithm>
|
||||
#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("bool var_%s = false;\n", extName)
|
||||
end
|
||||
|
||||
function src.WriteSetupFunction(hFile, specData, spec, options)
|
||||
common.WriteNamespaceBegin(hFile, "")
|
||||
|
||||
hFile:write "void ClearExtensionVariables()\n"
|
||||
hFile:write "{\n"
|
||||
hFile:inc()
|
||||
|
||||
for _, extName in ipairs(options.extensions) do
|
||||
hFile:fmt("exts::var_%s = false;\n", extName)
|
||||
end
|
||||
|
||||
hFile:dec()
|
||||
hFile:write "}\n"
|
||||
hFile:write "\n"
|
||||
|
||||
hFile:writeblock[[
|
||||
struct MapEntry
|
||||
{
|
||||
const char *extName;
|
||||
bool *extVariable;
|
||||
};
|
||||
|
||||
struct MapCompare
|
||||
{
|
||||
MapCompare(const char *test_) : test(test_) {}
|
||||
bool operator()(const MapEntry &other) { return strcmp(test, other.extName) == 0; }
|
||||
const char *test;
|
||||
};
|
||||
|
||||
struct ClearEntry
|
||||
{
|
||||
void operator()(MapEntry &entry) { *(entry.extVariable) = false;}
|
||||
};
|
||||
|
||||
]]
|
||||
local arrayLength = #options.extensions
|
||||
if(arrayLength == 0) then arrayLength = 1 end
|
||||
|
||||
hFile:fmt("MapEntry g_mappingTable[%i]", arrayLength)
|
||||
if(arrayLength == 1) then
|
||||
hFile:rawwrite "; //This is intensionally left uninitialized. \n"
|
||||
else
|
||||
hFile:rawwrite " =\n"
|
||||
hFile:write "{\n"
|
||||
hFile:inc()
|
||||
for _, extName in ipairs(options.extensions) do
|
||||
hFile:fmt('{"%s%s", &exts::var_%s},\n',
|
||||
spec.ExtNamePrefix(),
|
||||
extName,
|
||||
extName)
|
||||
end
|
||||
hFile:dec()
|
||||
hFile:write "};\n"
|
||||
end
|
||||
|
||||
hFile:write "\n"
|
||||
hFile:fmtblock([[
|
||||
void LoadExtByName(const char *extensionName)
|
||||
{
|
||||
MapEntry *tableEnd = &g_mappingTable[%i];
|
||||
MapEntry *entry = std::find_if(&g_mappingTable[0], tableEnd, MapCompare(extensionName));
|
||||
|
||||
if(entry != tableEnd)
|
||||
*(entry->extVariable) = true;
|
||||
}
|
||||
]], #options.extensions)
|
||||
|
||||
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.enumerators) 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;
|
||||
]] .. indexed[1].name
|
||||
.. [[(]] .. indexed[2].name
|
||||
.. [[, &iNumExtensions);
|
||||
|
||||
for(iLoop = 0; iLoop < iNumExtensions; iLoop++)
|
||||
{
|
||||
const char *strExtensionName = (const char *)]] ..
|
||||
indexed[3].name ..
|
||||
[[(]] .. indexed[4].name .. [[, iLoop);
|
||||
LoadExtByName(strExtensionName);
|
||||
}
|
||||
}
|
||||
]])
|
||||
else
|
||||
hFile:writeblock(
|
||||
common.GetProcessExtsFromStringFunc("LoadExtByName(%s)"))
|
||||
end
|
||||
|
||||
common.WriteNamespaceEnd(hFile, "")
|
||||
|
||||
hFile:fmt("void CheckExtensions(%s)\n", spec.GetLoaderParams())
|
||||
hFile:write "{\n"
|
||||
hFile:inc()
|
||||
hFile:write "ClearExtensionVariables();\n"
|
||||
hFile:fmt("std::for_each(&g_mappingTable[0], &g_mappingTable[%i], ClearEntry());\n", #options.extensions)
|
||||
hFile:write "\n"
|
||||
if(indexed) then
|
||||
hFile:write("ProcExtsFromExtList();\n")
|
||||
else
|
||||
--First, check if the GetExtStringFuncName is in the specData.
|
||||
local funcName = spec.GetExtStringFuncName()
|
||||
if(specData.functable[funcName]) then
|
||||
--Create a function pointer and load it.
|
||||
local func = specData.functable[funcName]
|
||||
funcName = "InternalGetExtensionString"
|
||||
|
||||
hFile:fmt("typedef %s (%s *MYGETEXTSTRINGPROC)(%s);\n",
|
||||
common.GetFuncReturnType(func),
|
||||
spec.GetCodegenPtrType(),
|
||||
common.GetFuncParamList(func))
|
||||
hFile:fmt('MYGETEXTSTRINGPROC %s = (MYGETEXTSTRINGPROC)%s("%s%s");\n',
|
||||
funcName,
|
||||
spec.GetPtrLoaderFuncName(),
|
||||
spec.FuncNamePrefix(),
|
||||
func.name)
|
||||
hFile:fmt("if(!%s) return;\n", funcName)
|
||||
hFile:write "\n"
|
||||
end
|
||||
|
||||
hFile:fmt("ProcExtsFromExtString((const char *)%s(%s));\n",
|
||||
funcName,
|
||||
spec.GetExtStringParamList(
|
||||
function (name) return spec.FuncNamePrefix() .. "::" .. name end))
|
||||
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, spec, options, funcSeen)
|
||||
if(funcSeen[func.name]) then return end
|
||||
WriteFuncPtrTypedefStmt(hFile, func, spec, options)
|
||||
end
|
||||
|
||||
local defs = {}
|
||||
src.defs = defs
|
||||
|
||||
function defs.WriteFunction(hFile, func, spec, options, funcSeen)
|
||||
if(funcSeen[func.name]) then return end
|
||||
hFile:write(GetFuncPtrDefTypedef(func, spec, options), ";\n")
|
||||
end
|
||||
|
||||
local switch = {}
|
||||
src.switch = switch
|
||||
|
||||
function switch.WriteFunction(hFile, func, spec, options, funcSeen)
|
||||
if(funcSeen[func.name]) then return end
|
||||
hFile:fmt("static %s %s Switch_%s(%s)\n",
|
||||
common.GetFuncReturnType(func),
|
||||
spec.GetCodegenPtrType(),
|
||||
func.name,
|
||||
common.GetFuncParamList(func, 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)) then
|
||||
hFile:fmt('%s(%s);\n',
|
||||
GetFuncPtrName(func, spec, options),
|
||||
common.GetFuncParamCallList(func))
|
||||
else
|
||||
hFile:fmt('return %s(%s);\n',
|
||||
GetFuncPtrName(func, spec, options),
|
||||
common.GetFuncParamCallList(func))
|
||||
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),
|
||||
func.name,
|
||||
common.GetFuncParamList(func, 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)) then
|
||||
hFile:fmt('%s(%s);\n',
|
||||
GetFuncPtrName(func, spec, options),
|
||||
common.GetFuncParamCallList(func))
|
||||
else
|
||||
hFile:fmt('return %s(%s);\n',
|
||||
GetFuncPtrName(func, spec, options),
|
||||
common.GetFuncParamCallList(func))
|
||||
end
|
||||
hFile:dec()
|
||||
hFile:write "}\n\n"
|
||||
end
|
||||
end
|
||||
|
||||
local init = {}
|
||||
src.init = init
|
||||
|
||||
function init.WriteBlockBeginStruct(hFile, spec, options)
|
||||
common.WriteNamespaceBegin(hFile, "")
|
||||
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")
|
||||
common.WriteNamespaceEnd(hFile, "")
|
||||
end
|
||||
|
||||
function init.WriteFunction(hFile, func, spec, options, funcSeen)
|
||||
if(funcSeen[func.name]) then return end
|
||||
|
||||
hFile:fmt("%s = Switch_%s;\n", func.name, func.name)
|
||||
end
|
||||
|
||||
|
||||
local function Create()
|
||||
return util.DeepCopyTable(my_style), struct
|
||||
end
|
||||
|
||||
return { Create = Create }
|
||||
|
|
@ -1,723 +0,0 @@
|
|||
|
||||
local common = require "CommonStyle"
|
||||
local util = require "util"
|
||||
|
||||
local my_style = {}
|
||||
my_style.header = {}
|
||||
my_style.source = {}
|
||||
|
||||
----------------------------------------------------
|
||||
-- Global styling functions.
|
||||
function my_style.WriteLargeHeading(hFile, headingName)
|
||||
hFile:write(string.rep("/", 6 + #headingName), "\n")
|
||||
hFile:write("// ", headingName, "\n")
|
||||
hFile:write(string.rep("/", 6 + #headingName), "\n")
|
||||
end
|
||||
|
||||
function my_style.WriteSmallHeading(hFile, headingName)
|
||||
hFile:write("// ", headingName, "\n")
|
||||
end
|
||||
|
||||
------------------------------------------------------
|
||||
-- Header styling functions
|
||||
|
||||
function my_style.header.GetFilename(basename, options)
|
||||
return basename .. ".hpp"
|
||||
end
|
||||
|
||||
local function GenIncludeGuardName(hFile, spec, options)
|
||||
local str = "POINTER_CPP_GENERATED_HEADER" ..
|
||||
spec.GetIncludeGuardString() .. "_HPP"
|
||||
|
||||
if(#options.prefix > 0) then
|
||||
return options.prefix:upper() .. "_" .. str
|
||||
end
|
||||
|
||||
return str
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockBeginIncludeGuard(hFile, spec, options)
|
||||
local inclGuard = GenIncludeGuardName(hFile, spec, options)
|
||||
|
||||
hFile:fmt("#ifndef %s\n", inclGuard)
|
||||
hFile:fmt("#define %s\n", inclGuard)
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockEndIncludeGuard(hFile, spec, options)
|
||||
hFile:fmt("#endif //%s\n", GenIncludeGuardName(hFile, spec, options))
|
||||
end
|
||||
|
||||
function my_style.header.WriteInit(hFile, spec, options)
|
||||
hFile:rawwrite(spec.GetHeaderInit())
|
||||
end
|
||||
|
||||
function my_style.header.WriteStdTypedefs(hFile, specData, spec, options)
|
||||
local defArray = common.GetStdTypedefs()
|
||||
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")
|
||||
end
|
||||
|
||||
function my_style.header.WriteSpecTypedefs(hFile, specData, spec, options)
|
||||
hFile:push()
|
||||
common.WritePassthruData(hFile, specData.funcData.passthru)
|
||||
hFile:pop()
|
||||
end
|
||||
|
||||
local function StartNamespace(hFile, namespaceName)
|
||||
hFile:fmt("namespace %s\n", namespaceName or "")
|
||||
hFile:write("{\n")
|
||||
hFile:inc()
|
||||
end
|
||||
|
||||
local function EndNamespace(hFile, namespaceName)
|
||||
hFile:dec()
|
||||
hFile:fmt("} //namespace %s\n", namespaceName or "")
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockBeginDecl(hFile, spec, options)
|
||||
if(#options.prefix > 0) then
|
||||
StartNamespace(hFile, options.prefix)
|
||||
end
|
||||
StartNamespace(hFile, spec.FuncNamePrefix())
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockEndDecl(hFile, spec, options)
|
||||
EndNamespace(hFile, spec.FuncNamePrefix())
|
||||
if(#options.prefix > 0) then
|
||||
EndNamespace(hFile, options.prefix)
|
||||
end
|
||||
end
|
||||
|
||||
local extBlockNamespace = "exts"
|
||||
local extVariableTypeDefinition = [[
|
||||
class LoadTest
|
||||
{
|
||||
private:
|
||||
//Safe bool idiom. Joy!
|
||||
typedef void (LoadTest::*bool_type)() const;
|
||||
void big_long_name_that_really_doesnt_matter() const {}
|
||||
|
||||
public:
|
||||
operator bool_type() const
|
||||
{
|
||||
return m_isLoaded ? &LoadTest::big_long_name_that_really_doesnt_matter : 0;
|
||||
}
|
||||
|
||||
int GetNumMissing() const {return m_numMissing;}
|
||||
|
||||
LoadTest() : m_isLoaded(false), m_numMissing(0) {}
|
||||
LoadTest(bool isLoaded, int numMissing) : m_isLoaded(isLoaded), m_numMissing(numMissing) {}
|
||||
private:
|
||||
bool m_isLoaded;
|
||||
int m_numMissing;
|
||||
};
|
||||
]]
|
||||
|
||||
function my_style.header.WriteBlockBeginExtVarDecl(hFile, spec, options)
|
||||
StartNamespace(hFile, extBlockNamespace)
|
||||
hFile:writeblock(extVariableTypeDefinition)
|
||||
hFile:write("\n")
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockEndExtVarDecl(hFile, spec, options)
|
||||
EndNamespace(hFile, extBlockNamespace)
|
||||
end
|
||||
|
||||
local function GenExtensionVarName(extName, spec, options)
|
||||
return "var_" .. extName;
|
||||
end
|
||||
|
||||
function my_style.header.WriteExtVariableDecl(hFile, extName,
|
||||
specData, spec, options)
|
||||
hFile:fmt("extern LoadTest %s;\n",
|
||||
GenExtensionVarName(extName, spec, options));
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockBeginEnumDecl(hFile, spec, options)
|
||||
hFile:write("enum\n")
|
||||
hFile:write("{\n")
|
||||
hFile:inc()
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockEndEnumDecl(hFile, spec, options)
|
||||
hFile:dec()
|
||||
hFile:write("};\n")
|
||||
end
|
||||
|
||||
local function GenEnumName(enum)
|
||||
return common.GetCppEnumName(enum)
|
||||
end
|
||||
|
||||
function my_style.header.WriteEnumDecl(hFile, enum, enumTable, spec, options,
|
||||
enumSeen)
|
||||
if(enumSeen[enum.name]) then
|
||||
hFile:fmt("//%s taken from ext: %s\n", enum.name, enumSeen[enum.name])
|
||||
else
|
||||
|
||||
local enumName = GenEnumName(enum)
|
||||
local lenEnum = #enumName
|
||||
local numIndent = 33
|
||||
|
||||
local numSpaces = numIndent - lenEnum
|
||||
if(numSpaces < 1) then
|
||||
numSpaces = 1
|
||||
end
|
||||
|
||||
hFile:fmt("%s%s= %s,\n",
|
||||
enumName,
|
||||
string.rep(" ", numSpaces),
|
||||
common.ResolveEnumValue(enum, enumTable))
|
||||
end
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockBeginFuncDecl(hFile, spec, options)
|
||||
--Block containing all spec function declarations.
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockEndFuncDecl(hFile, spec, options)
|
||||
--Block containing all spec function declarations.
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockBeginExtFuncDecl(hFile, extName, spec, options)
|
||||
--Block containing all spec function declarations for a particular extension.
|
||||
--Useful for include-guards around extension function pointers.
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockEndExtFuncDecl(hFile, extName, spec, options)
|
||||
--Block containing all spec function declarations for a particular extension.
|
||||
end
|
||||
|
||||
local function GenFuncPtrName(func, spec, options)
|
||||
return func.name
|
||||
end
|
||||
|
||||
local function GenFuncPtrTypedefName(func, spec, options)
|
||||
return "PFN" .. GenFuncPtrName(func, spec, options):upper()
|
||||
end
|
||||
|
||||
local function WriteFuncPtrTypedefStmt(hFile, func, spec, options)
|
||||
hFile:fmt("typedef %s (%s *%s)(%s);\n",
|
||||
common.GetFuncReturnType(func),
|
||||
spec.GetCodegenPtrType(),
|
||||
GenFuncPtrTypedefName(func, spec, options),
|
||||
common.GetFuncParamList(func))
|
||||
end
|
||||
|
||||
local function GenFuncPtrDefDirect(func, spec, options)
|
||||
return string.format("%s (%s *%s)(%s)",
|
||||
common.GetFuncReturnType(func),
|
||||
spec.GetCodegenPtrType(),
|
||||
GenFuncPtrName(func, spec, options),
|
||||
common.GetFuncParamList(func, true))
|
||||
end
|
||||
|
||||
local function GenFuncPtrDefTypedef(func, spec, options)
|
||||
return string.format("%s %s",
|
||||
GenFuncPtrTypedefName(func, spec, options),
|
||||
GenFuncPtrName(func, spec, options))
|
||||
end
|
||||
|
||||
function my_style.header.WriteFuncDecl(hFile, func, spec, options)
|
||||
hFile:write("extern ",
|
||||
GenFuncPtrDefDirect(func, spec, options),
|
||||
";\n")
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockBeginSysDecl(hFile, spec, options)
|
||||
StartNamespace(hFile, "sys")
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockEndSysDecl(hFile, spec, options)
|
||||
EndNamespace(hFile, "sys")
|
||||
end
|
||||
|
||||
function my_style.header.WriteUtilityDecls(hFile, spec, options)
|
||||
--Write declarations for public utility stuff. Enums for return values, etc.
|
||||
end
|
||||
|
||||
function my_style.header.WriteMainLoaderFuncDecl(hFile, spec, options)
|
||||
hFile:fmt("%s::LoadTest LoadFunctions(%s);\n", extBlockNamespace, spec.GetLoaderParams())
|
||||
end
|
||||
|
||||
function my_style.header.WriteVersioningFuncDecls(hFile, spec, options)
|
||||
hFile:writeblock([[
|
||||
int GetMinorVersion();
|
||||
int GetMajorVersion();
|
||||
bool IsVersionGEQ(int majorVersion, int minorVersion);
|
||||
]])
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
-- Source code styling functions.
|
||||
function my_style.source.GetFilename(basename, options)
|
||||
return basename .. ".cpp"
|
||||
end
|
||||
|
||||
function my_style.source.WriteIncludes(hFile, basename, spec, options)
|
||||
hFile:writeblock([[
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
]])
|
||||
|
||||
local base = util.ParsePath(my_style.header.GetFilename(basename, options))
|
||||
hFile:fmt('#include "%s"\n', base)
|
||||
end
|
||||
|
||||
function my_style.source.WriteLoaderData(hFile, spec, options)
|
||||
hFile:writeblock(spec.GetLoaderFunc())
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockBeginDef(hFile, spec, options)
|
||||
if(#options.prefix > 0) then
|
||||
StartNamespace(hFile, options.prefix)
|
||||
end
|
||||
StartNamespace(hFile, spec.FuncNamePrefix())
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockEndDef(hFile, spec, options)
|
||||
EndNamespace(hFile, spec.FuncNamePrefix())
|
||||
if(#options.prefix > 0) then
|
||||
EndNamespace(hFile, options.prefix)
|
||||
end
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockBeginExtVarDef(hFile, spec, options)
|
||||
StartNamespace(hFile, extBlockNamespace)
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockEndExtVarDef(hFile, spec, options)
|
||||
EndNamespace(hFile, extBlockNamespace)
|
||||
end
|
||||
|
||||
function my_style.source.WriteExtVariableDef(hFile, extName,
|
||||
specData, spec, options)
|
||||
hFile:fmt("LoadTest %s;\n",
|
||||
GenExtensionVarName(extName, spec, options));
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockBeginExtFuncDef(hFile, extName, spec, options)
|
||||
--Block containing the extension function definitions and load function
|
||||
--for the functions in the extension `extName`.
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockEndExtFuncDef(hFile, extName, spec, options)
|
||||
--Block containing the extension function definitions and load function
|
||||
--for the functions in the extension `extName`.
|
||||
end
|
||||
|
||||
function my_style.source.WriteFuncDef(hFile, func, spec, options, funcSeen)
|
||||
if(not funcSeen[func.name]) then
|
||||
WriteFuncPtrTypedefStmt(hFile, func, spec, options)
|
||||
hFile:write(GenFuncPtrDefTypedef(func, spec, options),
|
||||
" = 0;\n")
|
||||
end
|
||||
end
|
||||
|
||||
local function GenExtLoaderFuncName(extName, spec, options)
|
||||
return "Load_" .. extName;
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockBeginExtLoader(hFile, extName, spec, options)
|
||||
hFile:fmt("static int %s()\n", GenExtLoaderFuncName(extName, spec, options))
|
||||
hFile:write("{\n")
|
||||
hFile:inc()
|
||||
hFile:write("int numFailed = 0;\n")
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockEndExtLoader(hFile, extName, spec, options)
|
||||
hFile:write "return numFailed;\n"
|
||||
hFile:dec()
|
||||
hFile:write("}\n")
|
||||
end
|
||||
|
||||
function my_style.source.WriteExtFuncLoader(hFile, func, spec, options)
|
||||
hFile:fmt('%s = reinterpret_cast<%s>(%s("%s%s"));\n',
|
||||
GenFuncPtrName(func, spec, options),
|
||||
GenFuncPtrTypedefName(func, spec, options),
|
||||
common.GetProcAddressName(spec),
|
||||
spec.FuncNamePrefix(), func.name)
|
||||
hFile:fmt('if(!%s) ++numFailed;\n', GenFuncPtrName(func, spec, options))
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockBeginCoreFuncDef(hFile, version, spec, options)
|
||||
--Block containing the core functions for `version`.
|
||||
--The block also contains the loading function for this version.
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockEndCoreFuncDef(hFile, version, spec, options)
|
||||
--Block containing the core functions for `version`.
|
||||
end
|
||||
|
||||
local function GenCoreLoaderFuncName(version, spec, options)
|
||||
return "LoadCoreFunctions"
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockBeginCoreLoader(hFile, version, spec, options)
|
||||
hFile:fmt("static int %s()\n", GenCoreLoaderFuncName(version, spec, options))
|
||||
hFile:write("{\n")
|
||||
hFile:inc()
|
||||
hFile:write("int numFailed = 0;\n")
|
||||
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockEndCoreLoader(hFile, version, spec, options)
|
||||
hFile:write "return numFailed;\n"
|
||||
hFile:dec()
|
||||
hFile:write("}\n")
|
||||
end
|
||||
|
||||
function my_style.source.WriteCoreFuncLoader(hFile, func, spec, options)
|
||||
hFile:fmt('%s = reinterpret_cast<%s>(%s("%s%s"));\n',
|
||||
GenFuncPtrName(func, spec, options),
|
||||
GenFuncPtrTypedefName(func, spec, options),
|
||||
common.GetProcAddressName(spec),
|
||||
spec.FuncNamePrefix(), func.name)
|
||||
|
||||
--Special hack for DSA_EXT functions in core functions.
|
||||
--They do not count against the loaded count.
|
||||
if(func.name:match("EXT$")) then
|
||||
hFile:write("//An EXT_direct_state_access-based function. Don't count it if it fails to load.\n")
|
||||
else
|
||||
hFile:fmt('if(!%s) ++numFailed;\n', GenFuncPtrName(func, spec, options))
|
||||
end
|
||||
end
|
||||
|
||||
function my_style.source.WriteExtStringFuncDef(hFile, specData, spec, options, funcSeen)
|
||||
if(funcSeen[spec.GetExtStringFuncName()]) then
|
||||
return
|
||||
end
|
||||
|
||||
--Check to see if its something we have to load.
|
||||
local function FindFuncName(funcName)
|
||||
for _, func in ipairs(specData.funcData.functions) do
|
||||
if(func.name == funcName) then
|
||||
return func
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
local extStringFunc = FindFuncName(spec.GetExtStringFuncName())
|
||||
|
||||
if(extStringFunc) then
|
||||
hFile:write("\n")
|
||||
WriteFuncPtrTypedefStmt(hFile, extStringFunc, spec, options)
|
||||
hFile:write("static ", GenFuncPtrDefTypedef(extStringFunc, spec, options),
|
||||
" = 0;\n")
|
||||
hFile:write("\n")
|
||||
end
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockBeginSysDef(hFile, spec, options)
|
||||
StartNamespace(hFile, "sys")
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockEndSysDef(hFile, spec, options)
|
||||
EndNamespace(hFile, "sys")
|
||||
end
|
||||
|
||||
function my_style.source.WriteUtilityDefs(hFile, specData, spec, options)
|
||||
--Write our mapping table definitions.
|
||||
StartNamespace(hFile)
|
||||
hFile:writeblock[[
|
||||
typedef int (*PFN_LOADEXTENSION)();
|
||||
struct MapEntry
|
||||
{
|
||||
MapEntry(const char *_extName, exts::LoadTest *_extVariable)
|
||||
: extName(_extName)
|
||||
, extVariable(_extVariable)
|
||||
, loaderFunc(0)
|
||||
{}
|
||||
|
||||
MapEntry(const char *_extName, exts::LoadTest *_extVariable, PFN_LOADEXTENSION _loaderFunc)
|
||||
: extName(_extName)
|
||||
, extVariable(_extVariable)
|
||||
, loaderFunc(_loaderFunc)
|
||||
{}
|
||||
|
||||
const char *extName;
|
||||
exts::LoadTest *extVariable;
|
||||
PFN_LOADEXTENSION loaderFunc;
|
||||
};
|
||||
|
||||
struct MapCompare
|
||||
{
|
||||
MapCompare(const char *test_) : test(test_) {}
|
||||
bool operator()(const MapEntry &other) { return strcmp(test, other.extName) == 0; }
|
||||
const char *test;
|
||||
};
|
||||
|
||||
]]
|
||||
|
||||
--Write the table initialization function.
|
||||
hFile:write "void InitializeMappingTable(std::vector<MapEntry> &table)\n"
|
||||
hFile:write "{\n"
|
||||
hFile:inc()
|
||||
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',
|
||||
spec.ExtNamePrefix() .. extName,
|
||||
GenExtensionVarName(extName, spec, options),
|
||||
GenExtLoaderFuncName(extName, spec, options))
|
||||
else
|
||||
hFile:fmt('table.push_back(MapEntry("%s", &exts::%s));\n',
|
||||
spec.ExtNamePrefix() .. extName,
|
||||
GenExtensionVarName(extName, spec, options))
|
||||
end
|
||||
end
|
||||
hFile:dec()
|
||||
hFile:write "}\n"
|
||||
hFile:write "\n"
|
||||
|
||||
--Write the function to clear the extension variables.
|
||||
hFile:fmt("void ClearExtensionVars()\n")
|
||||
hFile:write("{\n")
|
||||
hFile:inc()
|
||||
for _, extName in ipairs(options.extensions) do
|
||||
hFile:fmt('exts::%s = exts::LoadTest();\n',
|
||||
GenExtensionVarName(extName, spec, options))
|
||||
end
|
||||
hFile:dec()
|
||||
hFile:write("}\n")
|
||||
hFile:write "\n"
|
||||
|
||||
--Write a function that loads an extension by name. It is called when
|
||||
--processing, so it should also set the extension variable based on the load.
|
||||
hFile:writeblock([[
|
||||
void LoadExtByName(std::vector<MapEntry> &table, const char *extensionName)
|
||||
{
|
||||
std::vector<MapEntry>::iterator entry = std::find_if(table.begin(), table.end(), MapCompare(extensionName));
|
||||
|
||||
if(entry != table.end())
|
||||
{
|
||||
if(entry->loaderFunc)
|
||||
(*entry->extVariable) = exts::LoadTest(true, entry->loaderFunc());
|
||||
else
|
||||
(*entry->extVariable) = exts::LoadTest(true, 0);
|
||||
}
|
||||
}
|
||||
]])
|
||||
EndNamespace(hFile)
|
||||
hFile:write "\n"
|
||||
end
|
||||
|
||||
local function GenQualifier(spec, options)
|
||||
local ret = ""
|
||||
if(#options.prefix > 0) then
|
||||
ret = options.prefix .. "::"
|
||||
end
|
||||
ret = ret .. spec.FuncNamePrefix() .. "::"
|
||||
return ret
|
||||
end
|
||||
|
||||
local function GenQualifiedEnumName(enum, spec, options)
|
||||
return GenQualifier(spec, options) .. GenEnumName(enum, spec, options)
|
||||
end
|
||||
|
||||
local function GenQualifiedFuncPtrName(func, spec, options)
|
||||
return GenQualifier(spec, options) .. GenFuncPtrName(func, spec, options)
|
||||
end
|
||||
|
||||
local function WriteAncillaryFuncs(hFile, specData, spec, options)
|
||||
local indexed = spec.GetIndexedExtStringFunc(options);
|
||||
if(indexed) then
|
||||
for _, func in ipairs(specData.funcData.functions) do
|
||||
if(indexed[1] == func.name) then
|
||||
indexed[1] = func
|
||||
end
|
||||
if(indexed[3] == func.name) then
|
||||
indexed[3] = func
|
||||
end
|
||||
end
|
||||
for _, enum in ipairs(specData.enumerators) do
|
||||
if(indexed[2] == enum.name) then
|
||||
indexed[2] = enum
|
||||
end
|
||||
if(indexed[4] == enum.name) then
|
||||
indexed[4] = enum
|
||||
end
|
||||
end
|
||||
|
||||
hFile:writeblock([[
|
||||
static void ProcExtsFromExtList(std::vector<MapEntry> &table)
|
||||
{
|
||||
GLint iLoop;
|
||||
GLint iNumExtensions = 0;
|
||||
]] .. GenQualifiedFuncPtrName(indexed[1], spec, options)
|
||||
.. [[(]] .. GenQualifiedEnumName(indexed[2], spec, options)
|
||||
.. [[, &iNumExtensions);
|
||||
|
||||
for(iLoop = 0; iLoop < iNumExtensions; iLoop++)
|
||||
{
|
||||
const char *strExtensionName = (const char *)]] ..
|
||||
GenQualifiedFuncPtrName(indexed[3], spec, options) ..
|
||||
[[(]] .. GenQualifiedEnumName(indexed[4], spec, options) .. [[, iLoop);
|
||||
LoadExtByName(table, strExtensionName);
|
||||
}
|
||||
}
|
||||
]])
|
||||
else
|
||||
hFile:writeblock(common.GetProcessExtsFromStringFunc(
|
||||
"LoadExtByName(table, %s)", ", std::vector<MapEntry> &table"))
|
||||
end
|
||||
|
||||
hFile:write "\n"
|
||||
|
||||
return indexed
|
||||
end
|
||||
|
||||
|
||||
local function WriteInMainFuncLoader(hFile, func, spec, options)
|
||||
hFile:fmt('%s = reinterpret_cast<%s>(%s("%s%s"));\n',
|
||||
GenFuncPtrName(func, spec, options),
|
||||
GenFuncPtrTypedefName(func, spec, options),
|
||||
common.GetProcAddressName(spec),
|
||||
spec.FuncNamePrefix(), func.name)
|
||||
hFile:fmt('if(!%s) return exts::LoadTest();\n',
|
||||
GenFuncPtrName(func, spec, options))
|
||||
end
|
||||
|
||||
function my_style.source.WriteMainLoaderFunc(hFile, specData, spec, options)
|
||||
StartNamespace(hFile)
|
||||
local indexed = WriteAncillaryFuncs(hFile, specData, spec, options)
|
||||
EndNamespace(hFile)
|
||||
|
||||
hFile:write "\n"
|
||||
|
||||
hFile:fmt("exts::LoadTest LoadFunctions(%s)\n", spec.GetLoaderParams())
|
||||
hFile:write("{\n")
|
||||
hFile:inc()
|
||||
hFile:writeblock[[
|
||||
ClearExtensionVars();
|
||||
std::vector<MapEntry> table;
|
||||
InitializeMappingTable(table);
|
||||
]]
|
||||
hFile:write("\n")
|
||||
|
||||
if(indexed) then
|
||||
WriteInMainFuncLoader(hFile, indexed[1], spec, options)
|
||||
WriteInMainFuncLoader(hFile, indexed[3], spec, options)
|
||||
hFile:write("\n")
|
||||
hFile:write("ProcExtsFromExtList(table);\n")
|
||||
else
|
||||
local extListName, needLoad = spec.GetExtStringFuncName()
|
||||
if(needLoad) then
|
||||
for _, func in ipairs(specData.funcData.functions) do
|
||||
if(extListName == func.name) then
|
||||
extListName = func
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
WriteInMainFuncLoader(hFile, extListName, spec, options)
|
||||
|
||||
extListName = GenQualifiedFuncPtrName(extListName, spec, options);
|
||||
end
|
||||
|
||||
local function EnumResolve(enumName)
|
||||
return GenQualifiedEnumName(specData.enumtable[enumName], spec, options)
|
||||
end
|
||||
|
||||
hFile:write "\n"
|
||||
hFile:fmt("ProcExtsFromExtString((const char *)%s(%s), table);\n",
|
||||
extListName,
|
||||
spec.GetExtStringParamList(EnumResolve))
|
||||
end
|
||||
|
||||
if(options.version) then
|
||||
hFile:write "\n"
|
||||
hFile:fmt("int numFailed = %s();\n",
|
||||
GenCoreLoaderFuncName(options.version, spec, options))
|
||||
|
||||
hFile:write("return exts::LoadTest(true, numFailed);\n")
|
||||
else
|
||||
hFile:fmt("return exts::LoadTest(true, 0);\n")
|
||||
end
|
||||
|
||||
|
||||
hFile:dec()
|
||||
hFile:write("}\n")
|
||||
end
|
||||
|
||||
function my_style.source.WriteVersioningFuncs(hFile, specData, spec, options)
|
||||
hFile:fmt("static int g_major_version = 0;\n")
|
||||
hFile:fmt("static int g_minor_version = 0;\n")
|
||||
hFile:write "\n"
|
||||
|
||||
if(tonumber(options.version) >= 3.0) then
|
||||
hFile:writeblock([[
|
||||
static void GetGLVersion()
|
||||
{
|
||||
GetIntegerv(MAJOR_VERSION, &g_major_version);
|
||||
GetIntegerv(MINOR_VERSION, &g_minor_version);
|
||||
}
|
||||
]])
|
||||
else
|
||||
hFile:writeblock(common.GetParseVersionFromString())
|
||||
hFile:write "\n"
|
||||
|
||||
hFile:writeblock([[
|
||||
static void GetGLVersion()
|
||||
{
|
||||
ParseVersionFromString(&g_major_version, &g_minor_version, GetString(VERSION));
|
||||
}
|
||||
]])
|
||||
end
|
||||
|
||||
hFile:write "\n"
|
||||
hFile:writeblock([[
|
||||
int GetMajorVersion()
|
||||
{
|
||||
if(g_major_version == 0)
|
||||
GetGLVersion();
|
||||
return g_major_version;
|
||||
}
|
||||
]])
|
||||
hFile:write "\n"
|
||||
|
||||
hFile:writeblock([[
|
||||
int GetMinorVersion()
|
||||
{
|
||||
if(g_major_version == 0) //Yes, check the major version to get the minor one.
|
||||
GetGLVersion();
|
||||
return g_minor_version;
|
||||
}
|
||||
]])
|
||||
hFile:write "\n"
|
||||
|
||||
hFile:writeblock([[
|
||||
bool IsVersionGEQ(int majorVersion, int minorVersion)
|
||||
{
|
||||
if(g_major_version == 0)
|
||||
GetGLVersion();
|
||||
|
||||
if(majorVersion > g_major_version) return true;
|
||||
if(majorVersion < g_major_version) return false;
|
||||
if(minorVersion >= g_minor_version) return true;
|
||||
return false;
|
||||
}
|
||||
]])
|
||||
|
||||
end
|
||||
|
||||
|
||||
--------------------------------------------------
|
||||
-- Style retrieval machinery
|
||||
|
||||
local function Create()
|
||||
return common.DeepCopyTable(my_style), common.GetStandardStructure()
|
||||
end
|
||||
|
||||
return { Create = Create }
|
|
@ -1,575 +0,0 @@
|
|||
|
||||
local common = require "CommonStyle"
|
||||
local struct = require "Structure"
|
||||
local util = require "util"
|
||||
|
||||
|
||||
local my_style = {}
|
||||
my_style.header = {}
|
||||
my_style.source = {}
|
||||
|
||||
function my_style.WriteLargeHeading(hFile, headingName)
|
||||
hFile:write("/*", string.rep("*", #headingName), "*/\n")
|
||||
hFile:write("/*", headingName, "*/\n")
|
||||
end
|
||||
|
||||
function my_style.WriteSmallHeading(hFile, headingName)
|
||||
hFile:write("/*", headingName, "*/\n")
|
||||
end
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- Header file construction
|
||||
|
||||
function my_style.header.GetFilename(basename, options)
|
||||
return basename .. ".h"
|
||||
end
|
||||
|
||||
|
||||
local function GetIncludeGuard(hFile, spec, options)
|
||||
local str = "POINTER_C_GENERATED_HEADER_" ..
|
||||
spec.GetIncludeGuardString() .. "_H"
|
||||
|
||||
if(#options.prefix > 0) then
|
||||
return options.prefix:upper() .. "_" .. str
|
||||
end
|
||||
|
||||
return str
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockBeginIncludeGuard(hFile, spec, options)
|
||||
local inclGuard = GetIncludeGuard(hFile, spec, options)
|
||||
|
||||
hFile:fmt("#ifndef %s\n", inclGuard)
|
||||
hFile:fmt("#define %s\n", inclGuard)
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockEndIncludeGuard(hFile, spec, options)
|
||||
local inclGuard = GetIncludeGuard(hFile, spec, options)
|
||||
|
||||
hFile:fmt("#endif //%s\n", inclGuard)
|
||||
end
|
||||
|
||||
function my_style.header.WriteInit(hFile, spec, options)
|
||||
hFile:rawwrite(spec.GetHeaderInit())
|
||||
end
|
||||
|
||||
function my_style.header.WriteStdTypedefs(hFile, specData, 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")
|
||||
end
|
||||
|
||||
function my_style.header.WriteSpecTypedefs(hFile, specData, options)
|
||||
hFile:push()
|
||||
common.WritePassthruData(hFile, specData.funcData.passthru)
|
||||
hFile:pop()
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockBeginDecl(hFile, specData, options)
|
||||
common.WriteExternCStart(hFile)
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockBeginExtVarDecl(hFile, spec, options)
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockEndExtVarDecl(hFile, spec, options)
|
||||
end
|
||||
|
||||
local function GetExtVariableName(extName, spec, options)
|
||||
return options.prefix .. spec.DeclPrefix() .. "ext_" .. extName
|
||||
end
|
||||
|
||||
function my_style.header.WriteExtVariableDecl(hFile, extName, specData, spec, options)
|
||||
hFile:write("extern int ", GetExtVariableName(extName, spec, options), ";\n");
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockBeginEnumDecl(hFile, specData, options) end
|
||||
|
||||
function my_style.header.WriteBlockEndEnumDecl(hFile, specData, options) end
|
||||
|
||||
local function GetEnumName(enum, spec, options)
|
||||
return spec.EnumNamePrefix() .. enum.name
|
||||
end
|
||||
|
||||
function my_style.header.WriteEnumDecl(hFile, enum, enumTable, spec, options, enumSeen)
|
||||
if(enumSeen[enum.name]) then
|
||||
hFile:fmt("/*Copied %s%s From: %s*/\n",
|
||||
spec.EnumNamePrefix(),
|
||||
enum.name,
|
||||
enumSeen[enum.name])
|
||||
else
|
||||
hFile:fmt("#define %s %s\n",
|
||||
GetEnumName(enum, spec, options),
|
||||
common.ResolveEnumValue(enum, enumTable))
|
||||
end
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockBeginFuncDecl(hFile, specData, options)
|
||||
end
|
||||
|
||||
local function GetFuncPtrName(func, spec, options)
|
||||
return options.prefix .. "_ptrc_".. spec.FuncNamePrefix() .. func.name
|
||||
end
|
||||
|
||||
local function GetFuncPtrType(hFile, func, spec, options)
|
||||
return string.format("%s (%s *)(%s)",
|
||||
common.GetFuncReturnType(func),
|
||||
spec.GetCodegenPtrType(),
|
||||
common.GetFuncParamList(func))
|
||||
end
|
||||
|
||||
local function GetFuncPtrDef(hFile, func, spec, options)
|
||||
return string.format("%s (%s *%s)(%s)",
|
||||
common.GetFuncReturnType(func),
|
||||
spec.GetCodegenPtrType(),
|
||||
GetFuncPtrName(func, spec, options),
|
||||
common.GetFuncParamList(func))
|
||||
end
|
||||
|
||||
function my_style.header.WriteFuncDecl(hFile, func, spec, options)
|
||||
--Declare the function pointer.
|
||||
hFile:write("extern ",
|
||||
GetFuncPtrDef(hFile, func, spec, options),
|
||||
";\n")
|
||||
|
||||
--#define it to the proper OpenGL name.
|
||||
hFile:fmt("#define %s %s\n",
|
||||
common.GetOpenGLFuncName(func, spec),
|
||||
GetFuncPtrName(func, spec, options))
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockEndFuncDecl(hFile, specData, options)
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockBeginExtFuncDecl(hFile, extName,
|
||||
spec, options)
|
||||
hFile:fmt("#ifndef %s\n", spec.ExtNamePrefix() .. extName)
|
||||
hFile:fmt("#define %s 1\n", spec.ExtNamePrefix() .. extName)
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockEndExtFuncDecl(hFile, extName,
|
||||
spec, options)
|
||||
hFile:fmt("#endif /*%s*/ \n", spec.ExtNamePrefix() .. extName)
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockBeginSysDecl(hFile, spec, options)
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockEndSysDecl(hFile, spec, options)
|
||||
end
|
||||
|
||||
local function GetStatusCodeEnumName(spec, options)
|
||||
return string.format("%s%sLoadStatus", options.prefix, spec.DeclPrefix())
|
||||
end
|
||||
|
||||
local function GetStatusCodeName(name, spec, options)
|
||||
return string.format("%s%s%s", options.prefix, spec.DeclPrefix(), name)
|
||||
end
|
||||
|
||||
function my_style.header.WriteUtilityDecls(hFile, spec, options)
|
||||
hFile:fmt("enum %s\n", GetStatusCodeEnumName(spec, options))
|
||||
hFile:write("{\n")
|
||||
hFile:inc()
|
||||
hFile:write(GetStatusCodeName("LOAD_FAILED", spec, options), " = 0,\n")
|
||||
hFile:write(GetStatusCodeName("LOAD_SUCCEEDED", spec, options), " = 1,\n")
|
||||
hFile:dec()
|
||||
hFile:write("};\n")
|
||||
end
|
||||
|
||||
local function DecorateFuncName(name, spec, options)
|
||||
return string.format("%s%s%s", options.prefix, spec.DeclPrefix(), name)
|
||||
end
|
||||
|
||||
local function GetLoaderFuncName(spec, options)
|
||||
return DecorateFuncName("LoadFunctions", spec, options)
|
||||
end
|
||||
|
||||
function my_style.header.WriteMainLoaderFuncDecl(hFile, spec, options)
|
||||
hFile:fmt("int %s(%s);\n",
|
||||
GetLoaderFuncName(spec, options),
|
||||
spec.GetLoaderParams())
|
||||
end
|
||||
|
||||
function my_style.header.WriteVersioningFuncDecls(hFile, spec, options)
|
||||
--Only for GL
|
||||
if(options.spec ~= "gl") then
|
||||
return
|
||||
end
|
||||
|
||||
hFile:fmt("int %s();\n", DecorateFuncName("GetMinorVersion", spec, options))
|
||||
hFile:fmt("int %s();\n", DecorateFuncName("GetMajorVersion", spec, options))
|
||||
hFile:fmt("int %s(int majorVersion, int minorVersion);\n",
|
||||
DecorateFuncName("IsVersionGEQ", spec, options))
|
||||
end
|
||||
|
||||
function my_style.header.WriteBlockEndDecl(hFile, specData, options)
|
||||
common.WriteExternCEnd(hFile)
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
-- Source file construction functions.
|
||||
|
||||
function my_style.source.GetFilename(basename, options)
|
||||
return basename .. ".c"
|
||||
end
|
||||
|
||||
function my_style.source.WriteIncludes(hFile, basename, spec, options)
|
||||
hFile:writeblock([[
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
]])
|
||||
local base = util.ParsePath(my_style.header.GetFilename(basename, options))
|
||||
hFile:fmt('#include "%s"\n', base)
|
||||
end
|
||||
|
||||
function my_style.source.WriteLoaderData(hFile, spec, options)
|
||||
hFile:writeblock(spec.GetLoaderFunc())
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockBeginDef(hFile, spec, options) end
|
||||
function my_style.source.WriteBlockEndDef(hFile, spec, options) end
|
||||
|
||||
function my_style.source.WriteBlockBeginExtVarDef(hFile, spec, options)
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockEndExtVarDef(hFile, spec, options)
|
||||
end
|
||||
|
||||
function my_style.source.WriteExtVariableDef(hFile, extName, specData, spec, options)
|
||||
hFile:fmt("int %s = %s;\n", GetExtVariableName(extName, spec, options),
|
||||
GetStatusCodeName("LOAD_FAILED", spec, options));
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockBeginExtFuncDef(hFile, extName, spec, options)
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockEndExtFuncDef(hFile, extName, spec, options)
|
||||
end
|
||||
|
||||
function my_style.source.WriteFuncDef(hFile, func, spec, options, funcSeen)
|
||||
--Declare the function pointer, if not already declared.
|
||||
if(funcSeen[func.name]) then return end
|
||||
|
||||
hFile:fmt("%s = NULL;\n",
|
||||
GetFuncPtrDef(hFile, func, spec, options))
|
||||
end
|
||||
|
||||
local function GetExtLoaderFuncName(extName, spec, options)
|
||||
return "Load_" .. extName;
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockBeginExtLoader(hFile, extName, spec, options)
|
||||
hFile:fmt("static int %s()\n", GetExtLoaderFuncName(extName, spec, options))
|
||||
hFile:write("{\n")
|
||||
hFile:inc()
|
||||
hFile:write("int numFailed = 0;\n")
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockEndExtLoader(hFile, extName, spec, options)
|
||||
hFile:write("return numFailed;\n")
|
||||
hFile:dec()
|
||||
hFile:write("}\n")
|
||||
end
|
||||
|
||||
function my_style.source.WriteExtFuncLoader(hFile, func, spec, options)
|
||||
hFile:fmt('%s = (%s)%s("%s%s");\n',
|
||||
GetFuncPtrName(func, spec, options),
|
||||
GetFuncPtrType(hFile, func, spec, options),
|
||||
common.GetProcAddressName(spec),
|
||||
spec.FuncNamePrefix(), func.name)
|
||||
hFile:fmt('if(!%s) numFailed++;\n', GetFuncPtrName(func, spec, options))
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockBeginCoreFuncDef(hFile, spec, options)
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockEndCoreFuncDef(hFile, spec, options)
|
||||
end
|
||||
|
||||
local function GetCoreLoaderFuncName(spec, options)
|
||||
return "Load_Version_" .. options.version:gsub("%.", "_")
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockBeginCoreLoader(hFile, spec, options)
|
||||
hFile:fmt("static int %s()\n", GetCoreLoaderFuncName(spec, options))
|
||||
hFile:write("{\n")
|
||||
hFile:inc()
|
||||
hFile:write("int numFailed = 0;\n")
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockEndCoreLoader(hFile, version, spec, options)
|
||||
hFile:write("return numFailed;\n")
|
||||
hFile:dec()
|
||||
hFile:write("}\n")
|
||||
end
|
||||
|
||||
function my_style.source.WriteCoreFuncLoader(hFile, func, spec, options)
|
||||
hFile:fmt('%s = (%s)%s("%s%s");\n',
|
||||
GetFuncPtrName(func, spec, options),
|
||||
GetFuncPtrType(hFile, func, spec, options),
|
||||
common.GetProcAddressName(spec),
|
||||
spec.FuncNamePrefix(), func.name)
|
||||
|
||||
--Special hack for DSA_EXT functions in core functions.
|
||||
--They do not count against the loaded count.
|
||||
if(func.name:match("EXT$")) then
|
||||
hFile:write("/*An EXT_direct_state_access-based function. Don't count it.*/")
|
||||
else
|
||||
hFile:fmt('if(!%s) numFailed++;\n', GetFuncPtrName(func, spec, options))
|
||||
end
|
||||
end
|
||||
|
||||
function my_style.source.WriteExtStringFuncDef(hFile, specData, spec, options, funcSeen)
|
||||
if(funcSeen[spec.GetExtStringFuncName()]) then
|
||||
return
|
||||
end
|
||||
|
||||
--Check to see if its something we have to load.
|
||||
local function FindFuncName(funcName)
|
||||
for _, func in ipairs(specData.funcData.functions) do
|
||||
if(func.name == funcName) then
|
||||
return func
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
local extStringFunc = FindFuncName(spec.GetExtStringFuncName())
|
||||
|
||||
if(extStringFunc) then
|
||||
hFile:write("\n")
|
||||
hFile:fmt("static %s = NULL;\n",
|
||||
GetFuncPtrDef(hFile, extStringFunc, spec, options))
|
||||
hFile:write("\n")
|
||||
end
|
||||
end
|
||||
|
||||
local function GetMapTableStructName(spec, options)
|
||||
return string.format("%s%sStrToExtMap", options.prefix, spec.DeclPrefix())
|
||||
end
|
||||
|
||||
local function GetMapTableVarName()
|
||||
return "ExtensionMap"
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockBeginSysDef(hFile, spec, options)
|
||||
end
|
||||
|
||||
function my_style.source.WriteBlockEndSysDef(hFile, spec, options)
|
||||
end
|
||||
|
||||
function my_style.source.WriteUtilityDefs(hFile, specData, spec, options)
|
||||
--Write the struct for the mapping table.
|
||||
local mapStructName = string.format("%s%sStrToExtMap_s", options.prefix, spec.DeclPrefix())
|
||||
common.WriteCMappingTable(hFile, specData, spec, options,
|
||||
GetMapTableStructName(spec, options),
|
||||
GetMapTableVarName(),
|
||||
GetExtVariableName,
|
||||
GetExtLoaderFuncName)
|
||||
hFile:write "\n"
|
||||
|
||||
--Write function to find map entry by name.
|
||||
common.WriteCFindExtEntryFunc(hFile, specData, spec, options,
|
||||
GetMapTableStructName(spec, options),
|
||||
GetMapTableVarName())
|
||||
hFile:write "\n"
|
||||
|
||||
--Write the function to clear the extension variables.
|
||||
common.WriteCClearExtensionVarsFunc(hFile, specData, spec, options,
|
||||
GetExtVariableName,
|
||||
GetStatusCodeName("LOAD_FAILED", spec, options))
|
||||
hFile:write "\n"
|
||||
|
||||
--Write a function that loads an extension by name.
|
||||
common.WriteCLoadExtByNameFunc(hFile, specData, spec, options,
|
||||
GetMapTableStructName(spec, options),
|
||||
GetStatusCodeName("LOAD_SUCCEEDED", spec, options))
|
||||
hFile:write "\n"
|
||||
end
|
||||
|
||||
local function WriteAncillaryFuncs(hFile, specData, spec, options)
|
||||
local indexed = spec.GetIndexedExtStringFunc(options);
|
||||
if(indexed) then
|
||||
common.FixupIndexedList(specData, indexed)
|
||||
hFile:writeblock(common.GetProcExtsFromExtListFunc(
|
||||
hFile, specData, spec, options,
|
||||
indexed, GetFuncPtrName, GetEnumName))
|
||||
else
|
||||
hFile:writeblock(common.GetProcessExtsFromStringFunc("LoadExtByName(%s)"))
|
||||
end
|
||||
|
||||
hFile:write "\n"
|
||||
|
||||
return indexed
|
||||
end
|
||||
|
||||
local function WriteInMainFuncLoader(hFile, func, spec, options)
|
||||
hFile:fmt('%s = (%s)%s("%s%s");\n',
|
||||
GetFuncPtrName(func, spec, options),
|
||||
GetFuncPtrType(hFile, func, spec, options),
|
||||
common.GetProcAddressName(spec),
|
||||
spec.FuncNamePrefix(), func.name)
|
||||
hFile:fmt('if(!%s) return %s;\n',
|
||||
GetFuncPtrName(func, spec, options),
|
||||
GetStatusCodeName("LOAD_FAILED", spec, options))
|
||||
end
|
||||
|
||||
|
||||
function my_style.source.WriteMainLoaderFunc(hFile, specData, spec, options)
|
||||
local indexed = WriteAncillaryFuncs(hFile, specData, spec, options)
|
||||
|
||||
--Write the function that calls the extension and core loaders.
|
||||
hFile:fmt("int %s(%s)\n",
|
||||
GetLoaderFuncName(spec, options),
|
||||
spec.GetLoaderParams())
|
||||
hFile:write("{\n")
|
||||
hFile:inc()
|
||||
|
||||
if(options.version) then
|
||||
hFile:write("int numFailed = 0;\n")
|
||||
end
|
||||
|
||||
hFile:write("ClearExtensionVars();\n")
|
||||
hFile:write("\n")
|
||||
|
||||
--Load the extension, using runtime-facilities to tell what is available.
|
||||
if(indexed) then
|
||||
WriteInMainFuncLoader(hFile, indexed[1], spec, options)
|
||||
WriteInMainFuncLoader(hFile, indexed[3], spec, options)
|
||||
hFile:write("\n")
|
||||
hFile:write("ProcExtsFromExtList();\n")
|
||||
else
|
||||
local extListName, needLoad = spec.GetExtStringFuncName()
|
||||
if(needLoad) then
|
||||
for _, func in ipairs(specData.funcData.functions) do
|
||||
if(extListName == func.name) then
|
||||
extListName = func
|
||||
end
|
||||
end
|
||||
|
||||
WriteInMainFuncLoader(hFile, extListName, spec, options)
|
||||
|
||||
extListName = GetFuncPtrName(extListName, spec, options);
|
||||
end
|
||||
|
||||
local function EnumResolve(enumName)
|
||||
return GetEnumName(specData.enumtable[enumName], spec, options)
|
||||
end
|
||||
|
||||
hFile:write "\n"
|
||||
hFile:fmt("ProcExtsFromExtString((const char *)%s(%s));\n",
|
||||
extListName,
|
||||
spec.GetExtStringParamList(EnumResolve))
|
||||
end
|
||||
|
||||
if(options.version) then
|
||||
hFile:fmt("numFailed = %s();\n",
|
||||
GetCoreLoaderFuncName(spec, options))
|
||||
hFile:write "\n"
|
||||
|
||||
hFile:fmtblock([[
|
||||
if(numFailed == 0)
|
||||
return %s;
|
||||
else
|
||||
return %s + numFailed;
|
||||
]],
|
||||
GetStatusCodeName("LOAD_SUCCEEDED", spec, options),
|
||||
GetStatusCodeName("LOAD_SUCCEEDED", spec, options))
|
||||
else
|
||||
hFile:fmt("return %s;\n",
|
||||
GetStatusCodeName("LOAD_SUCCEEDED", spec, options))
|
||||
end
|
||||
|
||||
hFile:dec()
|
||||
hFile:write("}\n")
|
||||
end
|
||||
|
||||
function my_style.source.WriteVersioningFuncs(hFile, specData, spec, options)
|
||||
hFile:fmt("static int g_major_version = 0;\n")
|
||||
hFile:fmt("static int g_minor_version = 0;\n")
|
||||
hFile:write "\n"
|
||||
|
||||
if(tonumber(options.version) >= 3.0) then
|
||||
hFile:writeblock([[
|
||||
static void GetGLVersion()
|
||||
{
|
||||
glGetIntegerv(GL_MAJOR_VERSION, &g_major_version);
|
||||
glGetIntegerv(GL_MINOR_VERSION, &g_minor_version);
|
||||
}
|
||||
]])
|
||||
else
|
||||
hFile:writeblock(common.GetParseVersionFromString())
|
||||
hFile:write "\n"
|
||||
|
||||
hFile:writeblock([[
|
||||
static void GetGLVersion()
|
||||
{
|
||||
ParseVersionFromString(&g_major_version, &g_minor_version, (const char*)glGetString(GL_VERSION));
|
||||
}
|
||||
]])
|
||||
end
|
||||
|
||||
hFile:write "\n"
|
||||
hFile:fmt("int %s()\n", DecorateFuncName("GetMajorVersion", spec, options))
|
||||
hFile:writeblock([[
|
||||
{
|
||||
if(g_major_version == 0)
|
||||
GetGLVersion();
|
||||
return g_major_version;
|
||||
}
|
||||
]])
|
||||
hFile:write "\n"
|
||||
|
||||
hFile:fmt("int %s()\n", DecorateFuncName("GetMinorVersion", spec, options))
|
||||
hFile:writeblock([[
|
||||
{
|
||||
if(g_major_version == 0) //Yes, check the major version to get the minor one.
|
||||
GetGLVersion();
|
||||
return g_minor_version;
|
||||
}
|
||||
]])
|
||||
hFile:write "\n"
|
||||
|
||||
hFile:fmt("int %s(int majorVersion, int minorVersion)\n",
|
||||
DecorateFuncName("IsVersionGEQ", spec, options))
|
||||
hFile:writeblock([[
|
||||
{
|
||||
if(g_major_version == 0)
|
||||
GetGLVersion();
|
||||
|
||||
if(majorVersion > g_major_version) return 1;
|
||||
if(majorVersion < g_major_version) return 0;
|
||||
if(minorVersion >= g_minor_version) return 1;
|
||||
return 0;
|
||||
}
|
||||
]])
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------
|
||||
-- Style retrieval machinery
|
||||
|
||||
local function Create()
|
||||
return common.DeepCopyTable(my_style), common.GetStandardStructure()
|
||||
end
|
||||
|
||||
return { Create = Create }
|
|
@ -1,56 +0,0 @@
|
|||
local struct = require "Structure"
|
||||
local common = require "CommonStruct"
|
||||
|
||||
local my_struct =
|
||||
{
|
||||
{ type="file", style="hdr", name="GetFilename(basename, spec, options)",
|
||||
{ type="block", name="IncludeGuard",
|
||||
{ type="write", name="Guards(hFile, spec, options)", },
|
||||
{ type="blank" },
|
||||
{ type="write", name="Typedefs(hFile, specData, spec, options)",},
|
||||
{ type="blank" },
|
||||
{ type="block", name="Extern(hFile)",
|
||||
{ type="ext-iter",
|
||||
{ type="write", name="Extension(hFile, extName, spec, options)", },
|
||||
},
|
||||
{ type="blank" },
|
||||
common.Enumerators(),
|
||||
{ type="blank" },
|
||||
common.Functions(),
|
||||
{ type="blank" },
|
||||
{ type="write", name="MainLoaderFunc(hFile, spec, options)",},
|
||||
},
|
||||
},
|
||||
},
|
||||
{ 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="ext-iter",
|
||||
{ type="write", name="Extension(hFile, extName, spec, options)", },
|
||||
},
|
||||
{ type="blank" },
|
||||
common.Functions(),
|
||||
{ type="ext-iter",
|
||||
{ type="block", name="ExtFuncLoader(hFile, extName, spec, options)", cond="func-iter",
|
||||
{ type="func-iter",
|
||||
{ type="write", name="LoadFunction(hFile, func, spec, options)", },
|
||||
},
|
||||
},
|
||||
{ type="blank", cond="func-iter",},
|
||||
},
|
||||
{ type="block", name="CoreLoader(hFile, spec, options)", cond="core-funcs",
|
||||
{ type="version-iter",
|
||||
{type="func-iter",
|
||||
{ type="write", name="LoadFunction(hFile, func, spec, options)", },
|
||||
},
|
||||
},
|
||||
},
|
||||
{ type="blank", },
|
||||
{ type="write", name="MainLoaderFunc(hFile, specData, spec, options)",},
|
||||
},
|
||||
}
|
||||
|
||||
my_struct = struct.BuildStructure(my_struct)
|
||||
return my_struct
|
|
@ -1,301 +0,0 @@
|
|||
local util = require "util"
|
||||
local struct = require "Sample_Struct"
|
||||
local common = require "CommonStyle"
|
||||
|
||||
local function GetIncludeGuard(spec, options)
|
||||
local temp =
|
||||
options.prefix .. spec.GetIncludeGuardString() .. "_THIS_IS_A_TEST_H"
|
||||
return temp:upper()
|
||||
end
|
||||
|
||||
local function GetExtensionVarName(extName, spec, options)
|
||||
return options.prefix .. spec.DeclPrefix() .. "ext_" .. extName
|
||||
end
|
||||
|
||||
local function GetEnumName(enum, spec, options)
|
||||
return spec.EnumNamePrefix() .. enum.name
|
||||
end
|
||||
|
||||
local function GetFuncPtrName(func, spec, options)
|
||||
return options.prefix .. "_testc_".. spec.FuncNamePrefix() .. func.name
|
||||
end
|
||||
|
||||
local function GetFuncPtrDef(hFile, func, spec, options)
|
||||
return string.format("%s (%s *%s)(%s)",
|
||||
common.GetFuncReturnType(func),
|
||||
spec.GetCodegenPtrType(),
|
||||
GetFuncPtrName(func, spec, options),
|
||||
common.GetFuncParamList(func))
|
||||
end
|
||||
|
||||
local function GetFuncPtrType(hFile, func, spec, options)
|
||||
return string.format("%s (%s *)(%s)",
|
||||
common.GetFuncReturnType(func),
|
||||
spec.GetCodegenPtrType(),
|
||||
common.GetFuncParamList(func))
|
||||
end
|
||||
|
||||
local function GetMainLoaderFuncName(spec, options)
|
||||
return options.prefix .. spec.DeclPrefix() .. "LoadFunctions"
|
||||
end
|
||||
|
||||
local function GetExtFuncLoaderName(extName, spec, options)
|
||||
return "Load_" .. extName;
|
||||
end
|
||||
|
||||
local function GetMappingTableStructName(spec, options)
|
||||
return string.format("%s%sStringToExtMap",
|
||||
options.prefix, spec.DeclPrefix())
|
||||
end
|
||||
|
||||
local function GetMappingTableVarName()
|
||||
return "g_stringToExtMap"
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
local my_style = {}
|
||||
|
||||
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
|
||||
|
||||
hdr.WriteBlockBeginExtern = common.WriteExternCStart
|
||||
hdr.WriteBlockEndExtern = common.WriteExternCEnd
|
||||
|
||||
function hdr.WriteExtension(hFile, extName, spec, options)
|
||||
hFile:fmt("extern int %s;\n", GetExtensionVarName(extName, spec, options));
|
||||
end
|
||||
|
||||
function hdr.WriteEnumerator(hFile, enum, enumTable, spec, options, enumSeen)
|
||||
if(enumSeen[enum.name]) then return end
|
||||
|
||||
hFile:fmt("#define %s %s\n",
|
||||
GetEnumName(enum, spec, options),
|
||||
common.ResolveEnumValue(enum, enumTable))
|
||||
end
|
||||
|
||||
function hdr.WriteFunction(hFile, func, spec, options, funcSeen)
|
||||
if(funcSeen[func.name]) then return end
|
||||
|
||||
hFile:fmt("extern %s;\n",
|
||||
GetFuncPtrDef(hFile, func, spec, options))
|
||||
|
||||
hFile:fmt("#define %s %s\n",
|
||||
common.GetOpenGLFuncName(func, spec),
|
||||
GetFuncPtrName(func, spec, options))
|
||||
end
|
||||
|
||||
function hdr.WriteMainLoaderFunc(hFile, spec, options)
|
||||
hFile:fmt("int %s(%s);\n",
|
||||
GetMainLoaderFuncName(spec, options),
|
||||
spec.GetLoaderParams())
|
||||
end
|
||||
|
||||
|
||||
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>
|
||||
]])
|
||||
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 = 0;\n", GetExtensionVarName(extName, spec, options));
|
||||
end
|
||||
|
||||
function src.WriteFunction(hFile, func, spec, options, funcSeen)
|
||||
if(funcSeen[func.name]) then return end
|
||||
hFile:fmt("%s = NULL;\n", GetFuncPtrDef(hFile, func, spec, options));
|
||||
end
|
||||
|
||||
function src.WriteBlockBeginExtFuncLoader(hFile, extName, spec, options)
|
||||
hFile:fmt("static void %s()\n", GetExtFuncLoaderName(extName, spec, options))
|
||||
hFile:write("{\n")
|
||||
hFile:inc()
|
||||
end
|
||||
|
||||
function src.WriteBlockEndExtFuncLoader(hFile, extName, spec, options)
|
||||
hFile:dec()
|
||||
hFile:write("}\n")
|
||||
end
|
||||
|
||||
function src.WriteLoadFunction(hFile, func, spec, options)
|
||||
hFile:fmt('%s = (%s)%s("%s%s");\n',
|
||||
GetFuncPtrName(func, spec, options),
|
||||
GetFuncPtrType(hFile, func, spec, options),
|
||||
spec.GetPtrLoaderFuncName(),
|
||||
spec.FuncNamePrefix(),
|
||||
func.name)
|
||||
end
|
||||
|
||||
function src.WriteBlockBeginCoreLoader(hFile, spec, options)
|
||||
hFile:write("static void Load_Version()\n")
|
||||
hFile:write("{\n")
|
||||
hFile:inc()
|
||||
end
|
||||
|
||||
function src.WriteBlockEndCoreLoader(hFile, version, spec, options)
|
||||
hFile:dec()
|
||||
hFile:write("}\n")
|
||||
end
|
||||
|
||||
local function WriteHelpers(hFile, specData, spec, options)
|
||||
common.WriteCClearExtensionVarsFunc(hFile, specData, spec, options,
|
||||
GetExtensionVarName, "0")
|
||||
hFile:write("\n")
|
||||
hFile:write("typedef void (*PFN_LOADFUNCPOINTERS)();\n")
|
||||
hFile:fmt("typedef struct %s_s\n",
|
||||
GetMappingTableStructName(spec, options))
|
||||
hFile:write("{\n")
|
||||
hFile:inc()
|
||||
hFile:writeblock [[
|
||||
char *extensionName;
|
||||
int *extensionVariable;
|
||||
PFN_LOADFUNCPOINTERS LoadExtension;
|
||||
]]
|
||||
hFile:dec()
|
||||
hFile:fmt("} %s;\n", GetMappingTableStructName(spec, options))
|
||||
hFile:write "\n"
|
||||
|
||||
hFile:write "\n" --From last line of previous code.
|
||||
hFile:fmt("static %s %s[] = {\n",
|
||||
GetMappingTableStructName(spec, options),
|
||||
GetMappingTableVarName())
|
||||
hFile:inc()
|
||||
for _, extName in ipairs(options.extensions) do
|
||||
if(#specData.extdefs[extName].funcs > 0) then
|
||||
hFile:fmt('{"%s", &%s, %s},\n',
|
||||
spec.ExtNamePrefix() .. extName,
|
||||
GetExtensionVarName(extName, spec, options),
|
||||
GetExtFuncLoaderName(extName, spec, options))
|
||||
else
|
||||
hFile:fmt('{"%s", &%s, NULL},\n',
|
||||
spec.ExtNamePrefix() .. extName,
|
||||
GetExtensionVarName(extName, spec, options))
|
||||
end
|
||||
end
|
||||
hFile:dec()
|
||||
hFile:write("};\n")
|
||||
hFile:write("\n")
|
||||
hFile:fmt("static int g_extensionMapSize = %i;\n", #options.extensions);
|
||||
hFile:write "\n"
|
||||
|
||||
common.WriteCFindExtEntryFunc(hFile, specData, spec, options,
|
||||
GetMappingTableStructName(spec, options),
|
||||
GetMappingTableVarName())
|
||||
|
||||
hFile:write("\n")
|
||||
|
||||
hFile:fmtblock([[
|
||||
static void LoadExtByName(const char *extensionName)
|
||||
{
|
||||
%s *entry = NULL;
|
||||
entry = FindExtEntry(extensionName);
|
||||
if(entry)
|
||||
{
|
||||
if(entry->LoadExtension)
|
||||
{
|
||||
int numFailed = entry->LoadExtension();
|
||||
if(numFailed == 0)
|
||||
{
|
||||
*(entry->extensionVariable) = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(entry->extensionVariable) = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*(entry->extensionVariable) = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
]], GetMappingTableStructName(spec, options))
|
||||
|
||||
hFile:write("\n")
|
||||
local indexed = spec.GetIndexedExtStringFunc(options);
|
||||
if(not indexed) then
|
||||
common.WriteProcessExtsFromStringFunc(hFile, "LoadExtByName(%s)")
|
||||
else
|
||||
--New style
|
||||
end
|
||||
|
||||
return indexed
|
||||
end
|
||||
|
||||
function src.WriteMainLoaderFunc(hFile, specData, spec, options)
|
||||
WriteHelpers(hFile, specData, spec, options)
|
||||
hFile:write("\n")
|
||||
|
||||
hFile:fmt("int %s(%s)\n",
|
||||
GetMainLoaderFuncName(spec, options),
|
||||
spec.GetLoaderParams())
|
||||
hFile:write("{\n")
|
||||
hFile:inc()
|
||||
hFile:dec()
|
||||
hFile:write("}\n")
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
local function Create()
|
||||
return util.DeepCopyTable(my_style), struct
|
||||
end
|
||||
|
||||
return { Create = Create }
|
|
@ -1,163 +0,0 @@
|
|||
--[[ This module contains all of the spec-specific constructs (except where specs and styles overlap. That is, where styles have to do spec-specific work).
|
||||
|
||||
This module has a function called GetSpec which is given the spec name and returns a table containing functions/data that can be evaluated to do different jobs. This "class" contains:
|
||||
|
||||
- FilePrefix: nullary function that returns the filename prefix for this spec type.
|
||||
|
||||
- PlatformSetup: Takes a file and writes out platform-specific setup stuff.
|
||||
|
||||
- GetHeaderInit: Nullary function that returns a string to be written to the beginning of a header, just after the include guards.
|
||||
|
||||
- DeclPrefix: nullary function that returns the name of a prefix string for declarations.
|
||||
]]
|
||||
|
||||
local util = require "util"
|
||||
local LoadSpec = require "LoadLuaSpec"
|
||||
|
||||
|
||||
local gl_spec = {}
|
||||
local wgl_spec = {}
|
||||
local glx_spec = {}
|
||||
|
||||
local specTbl =
|
||||
{
|
||||
gl = gl_spec,
|
||||
wgl = wgl_spec,
|
||||
glX = glx_spec,
|
||||
}
|
||||
|
||||
-------------------------------------------------
|
||||
-- Spec-specific functions.
|
||||
--Validate the options.
|
||||
function gl_spec.VerifyOptions(options, parseOpts)
|
||||
if(options.profile == "compatibility") then
|
||||
parseOpts:AssertParse(tonumber(options.version) >= 3.0, "The OpenGL compatibility profile cannot be used with version " .. options.version)
|
||||
end
|
||||
end
|
||||
|
||||
function wgl_spec.VerifyOptions(options, parseOpts)
|
||||
return "wgl_"
|
||||
end
|
||||
function glx_spec.VerifyOptions(options, parseOpts)
|
||||
return "glx_"
|
||||
end
|
||||
|
||||
--Loads the appropriate Lua .spec file.
|
||||
function gl_spec.LoadSpec() return LoadSpec.LoadLuaSpec(util.GetSpecFilePath() .. "glspec.lua", gl_spec) end
|
||||
function wgl_spec.LoadSpec() return LoadSpec.LoadLuaSpec(util.GetSpecFilePath() .. "wglspec.lua", wgl_spec) end
|
||||
function glx_spec.LoadSpec() return LoadSpec.LoadLuaSpec(util.GetSpecFilePath() .. "glxspec.lua", glx_spec) end
|
||||
|
||||
--Name for displaying.
|
||||
function gl_spec.DisplayName() return "OpenGL" end
|
||||
function wgl_spec.DisplayName() return "WGL" end
|
||||
function glx_spec.DisplayName() return "GLX" end
|
||||
|
||||
---FilePrefix
|
||||
function gl_spec.FilePrefix() return "gl_" end
|
||||
function wgl_spec.FilePrefix() return "wgl_" end
|
||||
function glx_spec.FilePrefix() return "glx_" end
|
||||
|
||||
--Include-guard string.
|
||||
function gl_spec.GetIncludeGuardString() return "OPENGL" end
|
||||
function wgl_spec.GetIncludeGuardString() return "WINDOWSGL" end
|
||||
function glx_spec.GetIncludeGuardString() return "GLXWIN" end
|
||||
|
||||
--Declaration prefix.
|
||||
function gl_spec.DeclPrefix() return "ogl_" end
|
||||
function wgl_spec.DeclPrefix() return "wgl_" end
|
||||
function glx_spec.DeclPrefix() return "glx_" end
|
||||
|
||||
--Extension name prefix.
|
||||
function gl_spec.ExtNamePrefix() return "GL_" end
|
||||
function wgl_spec.ExtNamePrefix() return "WGL_" end
|
||||
function glx_spec.ExtNamePrefix() return "GLX_" end
|
||||
|
||||
--Enumerator name prefix. This is for defining "proper" GL enumerators.
|
||||
function gl_spec.EnumNamePrefix() return "GL_" end
|
||||
function wgl_spec.EnumNamePrefix() return "WGL_" end
|
||||
function glx_spec.EnumNamePrefix() return "GLX_" end
|
||||
|
||||
--Function name prefix. This is for defining "proper" GL function names.
|
||||
function gl_spec.FuncNamePrefix() return "gl" end
|
||||
function wgl_spec.FuncNamePrefix() return "wgl" end
|
||||
function glx_spec.FuncNamePrefix() return "glX" end
|
||||
|
||||
--Parameters given to the loader. No (), just the internals.
|
||||
function gl_spec.GetLoaderParams() return "" end
|
||||
function wgl_spec.GetLoaderParams() return "HDC hdc" end
|
||||
function glx_spec.GetLoaderParams() return "Display *display, int screen" end
|
||||
|
||||
--CodeGen function pointer type. For APIFUNC and so forth.
|
||||
function gl_spec.GetCodegenPtrType() return "CODEGEN_FUNCPTR" end
|
||||
function wgl_spec.GetCodegenPtrType() return "CODEGEN_FUNCPTR" end
|
||||
function glx_spec.GetCodegenPtrType() return "CODEGEN_FUNCPTR" end
|
||||
|
||||
--Name of the function that loads pointers
|
||||
function gl_spec.GetPtrLoaderFuncName() return "IntGetProcAddress" end
|
||||
function wgl_spec.GetPtrLoaderFuncName() return "IntGetProcAddress" end
|
||||
function glx_spec.GetPtrLoaderFuncName() return "IntGetProcAddress" end
|
||||
|
||||
--Name of extension string function. Also returns true if this function needs to be loaded. If false is returned, then use the string name *exactly as is*.
|
||||
function gl_spec.GetExtStringFuncName() return "GetString", true end
|
||||
function wgl_spec.GetExtStringFuncName() return "GetExtensionsStringARB", true end
|
||||
function glx_spec.GetExtStringFuncName() return "glXQueryExtensionsString", false end
|
||||
|
||||
--Gets the list of parameters that the extension string function will use. No (), just the internals. Pass a function used to resolve enumerator names into actual enumerator identifiers.
|
||||
function gl_spec.GetExtStringParamList(enumResolve)
|
||||
return enumResolve("EXTENSIONS")
|
||||
end
|
||||
function wgl_spec.GetExtStringParamList(enumResolve) return "hdc" end
|
||||
function glx_spec.GetExtStringParamList(enumResolve) return "display, screen" end
|
||||
|
||||
--Returns a table if it should use the indexed extension string functions. Returns false/nil otherwise.
|
||||
-- The table is an array of:
|
||||
-- Function name used to get the number of extensions.
|
||||
-- Enumerator name used to get the number of extensions.
|
||||
-- Function name used to get an extension string.
|
||||
-- Enumerator name used to get an extension string.
|
||||
function gl_spec.GetIndexedExtStringFunc(options)
|
||||
if(tonumber(options.version) >= 3.0) then
|
||||
return {"GetIntegerv", "NUM_EXTENSIONS", "GetStringi", "EXTENSIONS"}
|
||||
end
|
||||
return nil
|
||||
end
|
||||
function wgl_spec.GetIndexedExtStringFunc(options) return nil end
|
||||
function glx_spec.GetIndexedExtStringFunc(options) return nil end
|
||||
|
||||
local fileProps =
|
||||
{
|
||||
{"GetHeaderInit", "init"},
|
||||
-- {"GetVersions", "versions"},
|
||||
{"GetCoreVersions", "coreversions"},
|
||||
{"GetCoreExts", "coreexts"},
|
||||
{"GetLoaderFunc", "loaderfunc"},
|
||||
}
|
||||
|
||||
--Header initialization.
|
||||
for key, spec in pairs(specTbl) do
|
||||
for _, props in ipairs(fileProps) do
|
||||
spec[props[1]] = function()
|
||||
return dofile(util.GetDataFilePath() .. spec:FilePrefix() ..
|
||||
"spec" .. props[2] .. ".lua")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--------------------------------------------------
|
||||
-- Spec retrieval machinery
|
||||
local function CopyTable(tbl)
|
||||
local ret = {}
|
||||
for key, value in pairs(tbl) do
|
||||
ret[key] = value
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
local function GetSpec(spec)
|
||||
local spec_tbl = specTbl[spec]
|
||||
assert(spec_tbl, "Unknown specification " .. spec)
|
||||
return CopyTable(spec_tbl)
|
||||
end
|
||||
|
||||
return { GetSpec = GetSpec }
|
|
@ -1,757 +0,0 @@
|
|||
|
||||
local util = require "util"
|
||||
local TabbedFile = require "TabbedFile"
|
||||
|
||||
local actionTypes = {}
|
||||
local conditionals = {}
|
||||
|
||||
-------------------------------
|
||||
-- Action base-class
|
||||
local action = {}
|
||||
|
||||
function action:Process(context)
|
||||
--Allow start-of-iteration only data to parse.
|
||||
if(self.first) then
|
||||
--Note that it's *specifically* equal to false. Being 'nil' isn't enough.
|
||||
if(context._first == false) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
--Allow end-if-iteration only data to parse.
|
||||
if(self.last) then
|
||||
--Note that it's *specifically* equal to false. Being 'nil' isn't enough.
|
||||
if(context._last == false) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
--Conditional
|
||||
if(self._cond) then
|
||||
if(not conditionals[self._cond](context)) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
--NO MORE RETURNS FROM THIS POINT FORWARD!
|
||||
if(self.newStyle) then
|
||||
context:PushStyle(self.newStyle)
|
||||
end
|
||||
|
||||
local noChildren = nil
|
||||
if(self.PreProcess) then
|
||||
noChildren = self:PreProcess(context)
|
||||
end
|
||||
|
||||
if(not noChildren) then
|
||||
self:ProcessChildren(context)
|
||||
end
|
||||
|
||||
if(self.PostProcess) then
|
||||
self:PostProcess(context)
|
||||
end
|
||||
|
||||
if(self.newStyle) then
|
||||
context:PopStyle()
|
||||
end
|
||||
end
|
||||
|
||||
function action:ProcessChildren(context)
|
||||
for _, action in ipairs(self) do
|
||||
--Preserve the first value.
|
||||
local oldFirst = context._first
|
||||
local oldLast = context._last
|
||||
action:Process(context)
|
||||
context._first = oldFirst
|
||||
context._last = oldLast
|
||||
end
|
||||
end
|
||||
|
||||
local valueResolvers =
|
||||
{
|
||||
enum = function(enum) return enum.name end,
|
||||
func = function(func) return func.name end,
|
||||
spec = function(spec) return spec.FuncNamePrefix() end,
|
||||
}
|
||||
|
||||
local function ResolveValue(context, value)
|
||||
--Find every occurrance of %chars, and try to turn that into a context variable.
|
||||
local possibleVars = {}
|
||||
for var in value:gmatch("%%([_%a][_%w]*)") do
|
||||
possibleVars[var] = true
|
||||
end
|
||||
|
||||
for var, _ in pairs(possibleVars) do
|
||||
if(not context[var]) then
|
||||
return nil, "The variable " .. var .. " from the value string was not found.\n" .. value
|
||||
end
|
||||
|
||||
local replace = context[var]
|
||||
if(type(replace) ~= "string") then
|
||||
local str = tostring(replace)
|
||||
if(str) then
|
||||
replace = str
|
||||
elseif(valueResolvers[var]) then
|
||||
replace = valueResolvers[var](replace)
|
||||
elseif(type(replace) == "table" and replace._ValueResolve) then
|
||||
replace = replace:_ValueResolve()
|
||||
end
|
||||
end
|
||||
|
||||
if(type(replace) ~= "string") then
|
||||
return nil, "Could not convert the variable " .. var .. " into a string."
|
||||
end
|
||||
|
||||
value = value:gsub("%%" .. var, replace)
|
||||
end
|
||||
|
||||
return value
|
||||
end
|
||||
|
||||
function action:CallFunction(context, name)
|
||||
name = name or self.name
|
||||
self:Assert(name, "Unknown function name.")
|
||||
local style = context:FindStyleForFunc(name)
|
||||
|
||||
if(not style) then
|
||||
if(self.optional) then
|
||||
return
|
||||
else
|
||||
self:Assert(nil, "The style does not have a function " .. name)
|
||||
end
|
||||
end
|
||||
|
||||
if(self.value) then
|
||||
context.value = self:Assert(ResolveValue(context, self.value))
|
||||
end
|
||||
|
||||
local paramList = {}
|
||||
for _, param in ipairs(self.params) do
|
||||
assert(context[param], "The function " .. name ..
|
||||
" need a parameter " .. param .. " which doesn't exist at this point")
|
||||
paramList[#paramList + 1] = context[param]
|
||||
end
|
||||
|
||||
local rets = { style[name](unpack(paramList)) }
|
||||
|
||||
if(self.value) then
|
||||
context.value = nil
|
||||
end
|
||||
|
||||
return unpack(rets)
|
||||
end
|
||||
|
||||
function action:Assert(...)
|
||||
local test, text = ...
|
||||
if(not test) then
|
||||
local msg = ": " .. text
|
||||
if(self.name) then
|
||||
msg = self._actionType .. "." .. self.name .. msg
|
||||
else
|
||||
msg = self._actionType .. msg
|
||||
end
|
||||
assert(test, msg)
|
||||
end
|
||||
|
||||
return ...
|
||||
end
|
||||
|
||||
--Iterates over the list, setting the second element returned from the iterator
|
||||
--as the given context table key.
|
||||
function action:IterateChildren(context, list, key, PostProc)
|
||||
PostProc = PostProc or function() end
|
||||
|
||||
local oldVal = context[key]
|
||||
for _, val in ipairs(list) do
|
||||
context[key] = val
|
||||
context._first = (_ == 1)
|
||||
context._last = (_ == #list)
|
||||
self:ProcessChildren(context)
|
||||
PostProc(context, val)
|
||||
end
|
||||
context[key] = oldVal
|
||||
end
|
||||
|
||||
local function CreateAction(data, actionType)
|
||||
local act = {}
|
||||
util.DeepCopyTable(action, act)
|
||||
|
||||
assert(actionType, "No name given for action type")
|
||||
|
||||
--Create custom param list.
|
||||
if(data.name) then
|
||||
local name, params = data.name:match("([_%w]+)%s*%((.*)%)")
|
||||
if(name) then
|
||||
local paramList = {}
|
||||
for param in params:gmatch("([_%a][_%w]*)") do
|
||||
paramList[#paramList + 1] = param
|
||||
end
|
||||
params = paramList
|
||||
else
|
||||
name = data.name
|
||||
end
|
||||
|
||||
act.name = name
|
||||
act.params = params
|
||||
end
|
||||
|
||||
if(data.cond) then
|
||||
assert(conditionals[data.cond], "Unknown conditional " .. data.cond)
|
||||
act._cond = data.cond
|
||||
end
|
||||
|
||||
act.newStyle = data.style
|
||||
act.optional = data.optional
|
||||
act.value = data.value
|
||||
|
||||
--Make child actions recursively.
|
||||
for _, child in ipairs(data) do
|
||||
assert(actionTypes[child.type], "Unknown command type " .. child.type)
|
||||
act[#act + 1] = actionTypes[child.type](child)
|
||||
end
|
||||
|
||||
if(data.first) then
|
||||
act.first = true
|
||||
end
|
||||
|
||||
if(data.last) then
|
||||
act.last = true
|
||||
end
|
||||
|
||||
act._actionType = actionType
|
||||
|
||||
return act
|
||||
end
|
||||
|
||||
local function MakeActionType(typeName, typeTable, PostInitFunc)
|
||||
actionTypes[typeName] = function(data)
|
||||
local act = CreateAction(data, typeName)
|
||||
util.DeepCopyTable(typeTable, act)
|
||||
|
||||
PostInitFunc(act, data)
|
||||
|
||||
return act
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-------------------------------------
|
||||
-- Group Action
|
||||
local groupAction = {}
|
||||
|
||||
MakeActionType("group", groupAction, function(self, data)
|
||||
end)
|
||||
|
||||
|
||||
-------------------------------------
|
||||
-- Call Action
|
||||
local callAction = {}
|
||||
|
||||
function callAction:PreProcess(context)
|
||||
self:CallFunction(context, self.name)
|
||||
end
|
||||
|
||||
MakeActionType("call", callAction, function(self, data)
|
||||
self.params = self.params or {}
|
||||
end)
|
||||
|
||||
|
||||
-------------------------------------
|
||||
-- Context Action
|
||||
local contextAction = {}
|
||||
|
||||
function contextAction:PreProcess(context)
|
||||
self:Assert(context[self.key] == nil,
|
||||
"Attempt to nest the context variable " .. self.key)
|
||||
|
||||
if(self.data) then
|
||||
context[self.key] = self.data
|
||||
else
|
||||
context[self.key] = self:CallFunction(context, self.name)
|
||||
end
|
||||
end
|
||||
|
||||
function contextAction:PostProcess(context)
|
||||
if(self.dispose) then
|
||||
local style = context:FindStyleForFunc(self.dispose)
|
||||
self:Assert(style,
|
||||
string.format("Could not find the disposal function %s for %s.",
|
||||
self.dispose, self.key))
|
||||
|
||||
style[self.dispose](context[self.key])
|
||||
end
|
||||
context[self.key] = nil
|
||||
end
|
||||
|
||||
MakeActionType("context", contextAction, function(self, data)
|
||||
assert(data.key, "Context actions must have a `key`.")
|
||||
assert(data.key:match("%_$"), "Context action keys must end in `_`.")
|
||||
self.key = data.key
|
||||
self.data = data.data
|
||||
if(self.name) then
|
||||
self.name = "State" .. self.name
|
||||
end
|
||||
self.dispose = data.dispose
|
||||
if(self.dispose) then
|
||||
self.dispose = "Dispose" .. self.dispose
|
||||
end
|
||||
|
||||
assert(self.data or self.name, "Context actions must have either `data` or `name`.")
|
||||
|
||||
self.params = self.params or {}
|
||||
end)
|
||||
|
||||
|
||||
-------------------------------------------
|
||||
-- Filter Action
|
||||
local filterAction = {}
|
||||
|
||||
function filterAction:PreProcess(context)
|
||||
local shouldFilter = self:CallFunction(context, self.name)
|
||||
if(self.neg) then
|
||||
shouldFilter = not shouldFilter
|
||||
end
|
||||
return not shouldFilter
|
||||
end
|
||||
|
||||
MakeActionType("filter", filterAction, function(self, data)
|
||||
assert(data.name, "Filter actions must have a `name`")
|
||||
self.name = "Filter" .. self.name
|
||||
self.neg = data.neg
|
||||
self.params = self.params or {}
|
||||
end)
|
||||
|
||||
|
||||
----------------------------
|
||||
-- File Action
|
||||
local fileAction = {}
|
||||
|
||||
function fileAction:PreProcess(context)
|
||||
self:Assert(context.hFile == nil, "You cannot nest `file` blocks.")
|
||||
|
||||
local filename = self:CallFunction(context)
|
||||
|
||||
context.hFile = util.CreateFile(filename, context.options.indent)
|
||||
end
|
||||
|
||||
function fileAction:PostProcess(context)
|
||||
context.hFile:close()
|
||||
context.hFile = nil
|
||||
end
|
||||
|
||||
MakeActionType("file", fileAction, function(self, data)
|
||||
assert(data.style, "File actions must have a `style`")
|
||||
assert(data.name, "File actions need a name to call.")
|
||||
|
||||
self.params = self.params or {"basename", "options"}
|
||||
end)
|
||||
|
||||
|
||||
-------------------------------------
|
||||
-- Block Action
|
||||
local blockAction = {}
|
||||
|
||||
function blockAction:PreProcess(context)
|
||||
assert(context.hFile, "Cannot write a block outside of a file. " .. self.name)
|
||||
self:CallFunction(context, "WriteBlockBegin" .. self.name)
|
||||
end
|
||||
|
||||
function blockAction:PostProcess(context)
|
||||
self:CallFunction(context, "WriteBlockEnd" .. self.name)
|
||||
end
|
||||
|
||||
MakeActionType("block", blockAction, function(self, data)
|
||||
assert(data.name, "Block actions must have a `name`")
|
||||
|
||||
self.params = self.params or {"hFile", "spec", "options"}
|
||||
end)
|
||||
|
||||
|
||||
------------------------------------------
|
||||
-- Write Action
|
||||
local writeAction = {}
|
||||
|
||||
function writeAction:PreProcess(context)
|
||||
assert(context.hFile, "Cannot write data outside of a file.")
|
||||
self:CallFunction(context)
|
||||
end
|
||||
|
||||
MakeActionType("write", writeAction, function(self, data)
|
||||
assert(data.name, "Write actions must have a `name`")
|
||||
self.name = "Write" .. self.name
|
||||
self.params = self.params or {"hFile", "specData", "spec", "options"}
|
||||
end)
|
||||
|
||||
|
||||
------------------------------------------
|
||||
-- Blank Action
|
||||
local blankAction = {}
|
||||
|
||||
function blankAction:PreProcess(context)
|
||||
self:Assert(context.hFile, "Blanks must be in files.")
|
||||
context.hFile:write("\n")
|
||||
end
|
||||
|
||||
MakeActionType("blank", blankAction, function(self, data)
|
||||
end)
|
||||
|
||||
|
||||
---------------------------------------------
|
||||
-- Extension Iterator Action
|
||||
local extIterAction = {}
|
||||
|
||||
function extIterAction:PreProcess(context)
|
||||
self:Assert(context.extName == nil, "Cannot nest ext-iter actions.")
|
||||
self:IterateChildren(context, context.options.extensions, "extName")
|
||||
return true --Stops regular child processing.
|
||||
end
|
||||
|
||||
MakeActionType("ext-iter", extIterAction, function(self, data)
|
||||
end)
|
||||
|
||||
conditionals["ext-iter"] = function(context)
|
||||
return #context.options.extensions ~= 0
|
||||
end
|
||||
|
||||
|
||||
-----------------------------------------------
|
||||
-- Version Iterator
|
||||
local versionIterAction = {}
|
||||
|
||||
function versionIterAction:PreProcess(context)
|
||||
self:Assert(context.version == nil, "Cannot nest version-iter actions.")
|
||||
local rawVersionList = context.specData.versions or {}
|
||||
local versionList = {}
|
||||
for _, version in ipairs(rawVersionList) do
|
||||
if(tonumber(version) <= tonumber(context.options.version)) then
|
||||
versionList[#versionList + 1] = version
|
||||
end
|
||||
end
|
||||
|
||||
self:IterateChildren(context, versionList, "version")
|
||||
return true --Stops regular child processing.
|
||||
end
|
||||
|
||||
MakeActionType("version-iter", versionIterAction, function(self, data)
|
||||
end)
|
||||
|
||||
conditionals["version-iter"] = function(context)
|
||||
return context.specData.versions ~= nil
|
||||
end
|
||||
|
||||
|
||||
-----------------------------------------------
|
||||
-- Sub-Version Iterator
|
||||
local subVersionIterAction = {}
|
||||
|
||||
function subVersionIterAction:PreProcess(context)
|
||||
self:Assert(context.sub_version == nil, "Cannot nest sub-version-iter actions.")
|
||||
self:Assert(context.version, "Must put sub-version-iter inside versions.")
|
||||
local rawVersionList = context.specData.versions or {}
|
||||
local versionList = {}
|
||||
for _, version in ipairs(rawVersionList) do
|
||||
if(tonumber(version) <= tonumber(context.version)) then
|
||||
versionList[#versionList + 1] = version
|
||||
end
|
||||
end
|
||||
|
||||
self:IterateChildren(context, versionList, "sub_version")
|
||||
return true --Stops regular child processing.
|
||||
end
|
||||
|
||||
MakeActionType("sub-version-iter", subVersionIterAction, function(self, data)
|
||||
end)
|
||||
|
||||
---------------------------------------------
|
||||
-- Core Extension Iterator Action
|
||||
local coreExtIterAction = {}
|
||||
|
||||
function coreExtIterAction:PreProcess(context)
|
||||
self:Assert(context.version, "Must put this in a version iterator")
|
||||
self:Assert(context.extName == nil, "Cannot nest core-ext-iter actions.")
|
||||
local coreExts = context._coreExts
|
||||
if(coreExts[context.version]) then
|
||||
self:IterateChildren(context, coreExts[context.version], "extName")
|
||||
end
|
||||
return true --Stops regular child processing.
|
||||
end
|
||||
|
||||
MakeActionType("core-ext-iter", coreExtIterAction, function(self, data)
|
||||
end)
|
||||
|
||||
conditionals["core-ext-iter"] = function(context)
|
||||
assert(context.version, "Cannot have a core-ext-iter conditional outside of a version.")
|
||||
return context._coreExts[context.version] ~= nil
|
||||
end
|
||||
|
||||
|
||||
--[==[
|
||||
---------------------------------------------
|
||||
-- Core Extension Iterator Action, culled against the requested extensions.
|
||||
local coreExtCullIterAction = {}
|
||||
|
||||
local function BuildCulledExtList(context)
|
||||
local coreExts = context._coreExts
|
||||
if(coreExts[context.version]) then
|
||||
local extList = {}
|
||||
for _, ext in ipairs(coreExts[context.version]) do
|
||||
if(not context._extTbl[ext]) then
|
||||
extList[#extList + 1] = ext
|
||||
end
|
||||
end
|
||||
return extList
|
||||
else
|
||||
return {}
|
||||
end
|
||||
end
|
||||
|
||||
function coreExtCullIterAction:PreProcess(context)
|
||||
self:Assert(context.version, "Must put core-ext-cull-iters in a version")
|
||||
self:Assert(context.extName == nil, "Cannot nest core-ext-cull-iter actions.")
|
||||
local extList = BuildCulledExtList(context)
|
||||
if(#extList > 0) then
|
||||
self:IterateChildren(context, extList, "extName")
|
||||
end
|
||||
return true --Stops regular child processing.
|
||||
end
|
||||
|
||||
MakeActionType("core-ext-cull-iter", coreExtCullIterAction, function(self, data)
|
||||
end)
|
||||
|
||||
conditionals["core-ext-cull-iter"] = function(context)
|
||||
assert(context.version, "Cannot have a core-ext-cull-iter conditional outside of a version.")
|
||||
return #BuildCulledExtList(context) > 0
|
||||
end
|
||||
|
||||
]==]
|
||||
----------------------------------------------
|
||||
-- Enum Seen Action
|
||||
local enumSeenAction = {}
|
||||
|
||||
function enumSeenAction:PreProcess(context)
|
||||
self:Assert(context.enumSeen == nil, "Cannot nest enum-seen actions.")
|
||||
context.enumSeen = {}
|
||||
end
|
||||
|
||||
function enumSeenAction:PostProcess(context)
|
||||
context.enumSeen = nil
|
||||
end
|
||||
|
||||
MakeActionType("enum-seen", enumSeenAction, function(self, data)
|
||||
end)
|
||||
|
||||
|
||||
-----------------------------------------------
|
||||
-- Enumerator Iterator
|
||||
local enumIterAction = {}
|
||||
|
||||
local function GetEnumList(context)
|
||||
if(context.extName) then
|
||||
--Get enum list for the extension.
|
||||
return context.specData.extdefs[context.extName].enums, context.extName
|
||||
else
|
||||
--Get enum list from core version.
|
||||
if(context.options.profile ~= "core") then
|
||||
return context.specData.coredefs[context.version].enums, context.version
|
||||
end
|
||||
|
||||
local defList = {}
|
||||
local targetVersion = tonumber(context.options.version)
|
||||
|
||||
for _, def in ipairs(context.specData.coredefs[context.version].enums) do
|
||||
for ix = #def.core, 1, -1 do
|
||||
if(tonumber(def.core[ix][1]) <= targetVersion) then
|
||||
if(def.core[ix][2] == "core") then
|
||||
table.insert(defList, def)
|
||||
end
|
||||
break;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return defList, context.version
|
||||
end
|
||||
end
|
||||
|
||||
function enumIterAction:PreProcess(context)
|
||||
self:Assert(context.version or context.extName, "Enumeration iterators must go within a version or extension iterator.")
|
||||
|
||||
local enumList, source = GetEnumList(context)
|
||||
|
||||
if(not source) then
|
||||
print(context.version, context.extName)
|
||||
end
|
||||
|
||||
context.enumTable = context.specData.enumtable
|
||||
self:IterateChildren(context, enumList, "enum",
|
||||
function(context, enum)
|
||||
if(context.enumSeen) then
|
||||
context.enumSeen[enum.name] = source
|
||||
end
|
||||
end)
|
||||
context.enumTable = nil
|
||||
return true --Stops regular child processing.
|
||||
end
|
||||
|
||||
MakeActionType("enum-iter", enumIterAction, function(self, data)
|
||||
end)
|
||||
|
||||
conditionals["enum-iter"] = function(context)
|
||||
assert(context.version or context.extName, "Cannot have an enum-iter conditional outside of a version or extension iterator.")
|
||||
|
||||
return #GetEnumList(context) > 0
|
||||
end
|
||||
|
||||
----------------------------------------------
|
||||
-- Func Seen Action
|
||||
local funcSeenAction = {}
|
||||
|
||||
function funcSeenAction:PreProcess(context)
|
||||
self:Assert(context.funcSeen == nil, "Cannot nest func-seen actions.")
|
||||
context.funcSeen = {}
|
||||
end
|
||||
|
||||
function funcSeenAction:PostProcess(context)
|
||||
context.funcSeen = nil
|
||||
end
|
||||
|
||||
MakeActionType("func-seen", funcSeenAction, function(self, data)
|
||||
end)
|
||||
|
||||
|
||||
-----------------------------------------------
|
||||
-- Function Iterator
|
||||
local funcIterAction = {}
|
||||
|
||||
local function GetFuncList(context)
|
||||
if(context.extName) then
|
||||
--Get function list for the extension.
|
||||
return context.specData.extdefs[context.extName].funcs, context.extName
|
||||
else
|
||||
--Get function list from core version.
|
||||
if(context.options.profile ~= "core") then
|
||||
return context.specData.coredefs[context.version].funcs, context.version
|
||||
end
|
||||
|
||||
local defList = {}
|
||||
local targetVersion = tonumber(context.options.version)
|
||||
|
||||
for _, def in ipairs(context.specData.coredefs[context.version].funcs) do
|
||||
for ix = #def.core, 1, -1 do
|
||||
if(tonumber(def.core[ix][1]) <= targetVersion) then
|
||||
if(def.core[ix][2] == "core") then
|
||||
table.insert(defList, def)
|
||||
end
|
||||
break;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return defList, context.version
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
function funcIterAction:PreProcess(context)
|
||||
self:Assert(context.version or context.extName, "Function iterators must go within a version or extension iterator.")
|
||||
|
||||
local funcList, source = GetFuncList(context)
|
||||
|
||||
self:IterateChildren(context, funcList, "func",
|
||||
function(context, func)
|
||||
if(context.funcSeen) then
|
||||
context.funcSeen[func.name] = source
|
||||
end
|
||||
end)
|
||||
return true --Stops regular child processing.
|
||||
end
|
||||
|
||||
MakeActionType("func-iter", funcIterAction, function(self, data)
|
||||
end)
|
||||
|
||||
conditionals["func-iter"] = function(context)
|
||||
assert(context.version or context.extName, "Cannot have a func-iter conditional outside of a version or extension iterator.")
|
||||
|
||||
return #GetFuncList(context) > 0
|
||||
end
|
||||
|
||||
conditionals["core-funcs"] = function(context)
|
||||
return context.options.spec == "gl"
|
||||
end
|
||||
|
||||
|
||||
|
||||
local struct = {}
|
||||
|
||||
function struct.BuildStructure(structure)
|
||||
local actions = {}
|
||||
for _, data in ipairs(structure) do
|
||||
assert(actionTypes[data.type], "Unknown command type " .. data.type)
|
||||
actions[#actions + 1] = actionTypes[data.type](data)
|
||||
end
|
||||
|
||||
actions.Proc = function(basename, style, specData, spec, options)
|
||||
local context = {}
|
||||
context.basename = basename
|
||||
context.style = style
|
||||
context.specData = specData
|
||||
context.spec = spec
|
||||
context.options = options
|
||||
|
||||
context._coreExts = spec.GetCoreExts()
|
||||
context._extTbl = util.InvertTable(options.extensions)
|
||||
context._styles = { style }
|
||||
|
||||
function context:GetStyle()
|
||||
return context._styles[#context._styles]
|
||||
end
|
||||
|
||||
function context:FindStyleForFunc(funcName)
|
||||
for i = #context._styles, 1, -1 do
|
||||
if(context._styles[i][funcName]) then
|
||||
return context._styles[i]
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
function context:PushStyle(newStyleName)
|
||||
--Find the style in the stack, from top to bottom.
|
||||
local ix = nil
|
||||
for styleIx = #context._styles, 1, -1 do
|
||||
if(context._styles[styleIx][newStyleName]) then
|
||||
ix = styleIx
|
||||
break;
|
||||
end
|
||||
end
|
||||
assert(ix, "Could not find a style named " .. newStyleName)
|
||||
|
||||
table.insert(context._styles, context._styles[ix][newStyleName])
|
||||
context.style = context._styles[#context._styles]
|
||||
|
||||
if(context.style._init) then
|
||||
context.style._init()
|
||||
end
|
||||
end
|
||||
|
||||
function context:PopStyle()
|
||||
local ret = context._styles[#context._styles]
|
||||
context._styles[#context._styles] = nil
|
||||
context.style = context._styles[#context._styles]
|
||||
|
||||
if(ret._exit) then
|
||||
ret._exit()
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
for _, action in ipairs(actions) do
|
||||
action:Process(context)
|
||||
end
|
||||
end
|
||||
|
||||
return actions
|
||||
end
|
||||
|
||||
return struct
|
|
@ -1,58 +0,0 @@
|
|||
--[[This module is the interface to all of the style-based code generation facilities.
|
||||
|
||||
The module has a function called GetStyleList, which returns a list of all available styles.
|
||||
|
||||
This module has a function called GetStyle, which is given a style name. It will return a table of functions that can be evaluated to do different code generation tasks.
|
||||
|
||||
SampleStyle.lua contains an example, with documentation for what's going on. Every function you need to define will be there, with comments. Just copy and use as needed.
|
||||
|
||||
If you want to extend this to new styles, then create a file in this directory called "UserStyles.lua". In that file, return a table, where the keys in that table are string names for the command-line style name, and the value is the style data itself. The style data is a table containing a Create function, which takes no parameters and returns a style and a structure (two return values).
|
||||
]]
|
||||
|
||||
local style_registry =
|
||||
{
|
||||
pointer_c = require("PointerC_Style"),
|
||||
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"
|
||||
|
||||
local status, userStyles = pcall(require, "UserStyles")
|
||||
|
||||
if(status and type(userStyles) == "table") then
|
||||
for styleName, style in pairs(userStyles) do
|
||||
if(style_registry[styleName] ~= nil) then
|
||||
print("User-defined style name " .. styleName .. " conflicts with an existing style.")
|
||||
else
|
||||
style_registry[styleName] = style
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function GetStyleList()
|
||||
--Make sure the default is first.
|
||||
local list = {default_style}
|
||||
assert(style_registry[default_style], "Bad default style.")
|
||||
|
||||
for style, data in pairs(style_registry) do
|
||||
if(style ~= default_style) then
|
||||
list[#list + 1] = style
|
||||
end
|
||||
end
|
||||
|
||||
return list
|
||||
end
|
||||
|
||||
local function GetStyle(name)
|
||||
assert(style_registry[name], "Unknown style named " .. name)
|
||||
|
||||
return style_registry[name].Create()
|
||||
end
|
||||
|
||||
return{
|
||||
GetStyleList = GetStyleList,
|
||||
GetStyle = GetStyle,
|
||||
}
|
|
@ -1,136 +0,0 @@
|
|||
--[[ Exports a table containing one function: TabbedFile. It wraps a regular Lua file-handle, providing extra functions. Tabs can either be a number of spaces or one tab. It provides the following functions, in addition to (or replacing) the Lua standard ones:
|
||||
|
||||
- inc: Increments the tab count by the number given, or by 1 if nothing is given.
|
||||
- dec: Decrements the tab count by the number given, or by 1 if nothing is given.
|
||||
- push: Preserves the current tab count.
|
||||
- pop: Restores the previously preserved tab count.
|
||||
- write: An indented write; everything is written after the indent.
|
||||
- writeblock: Takes a single string, breaks it down into multiple lines, and writes each line indented.
|
||||
- fmt: As string.format followed by an indented write
|
||||
- fmtblock: As string.format, followed by calling `writeblock`.
|
||||
- rawfmt: As string.format followed by a NON-indented write.
|
||||
- rawwrite: hFile:write.
|
||||
|
||||
|
||||
Each call to one of the non-raw writing functions will indent the text.
|
||||
]]
|
||||
|
||||
local members = {}
|
||||
|
||||
function members:inc(count)
|
||||
count = count or 1
|
||||
rawset(self, "_indent", self._indent + count)
|
||||
end
|
||||
|
||||
function members:dec(count)
|
||||
count = count or 1
|
||||
rawset(self, "_indent", self._indent - count)
|
||||
end
|
||||
|
||||
function members:push()
|
||||
local stack = rawget(self, "_indentStack")
|
||||
stack[#stack + 1] = rawget(self, "_indent")
|
||||
end
|
||||
|
||||
function members:pop()
|
||||
local stack = rawget(self, "_indentStack")
|
||||
assert(#stack > 0, "Tab stack underflow.")
|
||||
rawset(self, "_indent", stack[#stack])
|
||||
stack[#stack] = nil
|
||||
end
|
||||
|
||||
function members:fmt(fmt, ...)
|
||||
self:_Indent()
|
||||
local str = fmt:format(...)
|
||||
rawget(self, "_hFile"):write(str)
|
||||
end
|
||||
|
||||
function members:rawfmt(fmt, ...)
|
||||
local str = fmt:format(...)
|
||||
rawget(self, "_hFile"):write(str)
|
||||
end
|
||||
|
||||
function members:write(...)
|
||||
self:_Indent()
|
||||
rawget(self, "_hFile"):write(...)
|
||||
end
|
||||
|
||||
function members:writeblock(block, ...)
|
||||
assert(#{...} == 0, "writeblock takes one argument")
|
||||
for line in block:gmatch("([^\n]*)\n") do
|
||||
self:write(line, "\n")
|
||||
end
|
||||
|
||||
local last = block:match("\n([^\n]*)$")
|
||||
if(last and #last ~= 0) then
|
||||
self:write(last)
|
||||
end
|
||||
end
|
||||
|
||||
function members:fmtblock(block, ...)
|
||||
self:writeblock(block:format(...))
|
||||
end
|
||||
|
||||
function members:rawwrite(...)
|
||||
rawget(self, "_hFile"):write(...)
|
||||
end
|
||||
|
||||
-----------------------------------------------------
|
||||
-- Standard members
|
||||
local fileMembers =
|
||||
{
|
||||
"close",
|
||||
"flush",
|
||||
"lines",
|
||||
"read",
|
||||
"seek",
|
||||
"setvbuf",
|
||||
"write",
|
||||
}
|
||||
|
||||
for _, fileMem in ipairs(fileMembers) do
|
||||
if(not members[fileMem]) then
|
||||
members[fileMem] = function(self, ...)
|
||||
local hFile = rawget(self, "_hFile")
|
||||
return hFile[fileMem](hFile, ...)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local metatable = {}
|
||||
|
||||
function metatable.__index(self, key)
|
||||
return members[key]
|
||||
end
|
||||
|
||||
metatable.__newindex = {}
|
||||
|
||||
local function IndentFunc(self)
|
||||
self._hFile:write(string.rep(self._indentStr, self._indent))
|
||||
end
|
||||
|
||||
local function TabbedFile(hFile, style, numSpaces)
|
||||
numSpaces = numSpaces or 2
|
||||
|
||||
local proxy =
|
||||
{
|
||||
_hFile = hFile,
|
||||
_indent = 0,
|
||||
_Indent = IndentFunc,
|
||||
_indentStack = {}
|
||||
}
|
||||
|
||||
if(style == "tab") then
|
||||
proxy._indentStr = "\t"
|
||||
elseif(style == "space") then
|
||||
proxy._indentStr = string.rep(" ", numSpaces)
|
||||
else
|
||||
error("Unknown indent style " .. style)
|
||||
end
|
||||
|
||||
setmetatable(proxy, metatable)
|
||||
|
||||
return proxy
|
||||
end
|
||||
|
||||
return { TabbedFile = TabbedFile }
|
|
@ -1,88 +0,0 @@
|
|||
|
||||
local TabbedFile = require "TabbedFile"
|
||||
|
||||
local util = {}
|
||||
|
||||
function util.GetSpecFilePath()
|
||||
return FixupPath("glspecs/");
|
||||
end
|
||||
|
||||
function util.GetDataFilePath()
|
||||
return FixupPath("data/");
|
||||
end
|
||||
|
||||
function util.InvertTable(tbl)
|
||||
local ret = {}
|
||||
for i, val in ipairs(tbl) do
|
||||
ret[val] = true
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
--Returns two values: the base filename and the directory.
|
||||
--If the base filename is nil, it doesn't have a pathname.
|
||||
--If the directory is nil, then there was no directory.
|
||||
function util.ParsePath(pathname)
|
||||
local base = pathname:match("([^\\/]+)$")
|
||||
local dir = pathname:match("^(.*[\\/])")
|
||||
|
||||
return base, dir
|
||||
end
|
||||
|
||||
local function DeepCopyTable(tbl, destTbl)
|
||||
local ret = destTbl or {}
|
||||
for key, value in pairs(tbl) do
|
||||
if(type(value) == "table") then
|
||||
if(type(ret[key]) == "table") then
|
||||
ret[key] = DeepCopyTable(value, ret[key])
|
||||
else
|
||||
ret[key] = DeepCopyTable(value)
|
||||
end
|
||||
else
|
||||
ret[key] = value
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
util.DeepCopyTable = DeepCopyTable
|
||||
|
||||
--Ensures the given path exists. Creates the directories when they don't.
|
||||
--Note: Only works if LFS is available.
|
||||
--`path` should end in a directory separator.
|
||||
function util.EnsurePath(path)
|
||||
local status, lfs = pcall(require, "lfs")
|
||||
|
||||
if(not status) then return end
|
||||
|
||||
--strip the last directory separator off.
|
||||
path = path:match("^(.+)[/\\]$")
|
||||
|
||||
local mode, err = lfs.attributes(path, "mode")
|
||||
if(not mode) then
|
||||
local creates = {}
|
||||
local currPath = path
|
||||
repeat
|
||||
table.insert(creates, 1, currPath)
|
||||
currPath = currPath:match("(.*[/\\])[^/\\]*$")
|
||||
if(currPath) then
|
||||
currPath = currPath:match("^(.+)[/\\]$")
|
||||
mode, err = lfs.attributes(currPath, "mode")
|
||||
end
|
||||
until(mode or currPath == nil)
|
||||
|
||||
for _, newDir in ipairs(creates) do
|
||||
assert(lfs.mkdir(newDir))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function util.CreateFile(filename, indent)
|
||||
local base, dir = util.ParsePath(filename)
|
||||
util.EnsurePath(dir)
|
||||
local hFile = assert(io.open(filename, "w"))
|
||||
return TabbedFile.TabbedFile(hFile, indent)
|
||||
end
|
||||
|
||||
|
||||
return util
|
|
@ -1,74 +0,0 @@
|
|||
--This file exports a function, WriteTable, which takes a file stream
|
||||
-- and a table to write.
|
||||
|
||||
local function WriteTabs(hFile, iRecursion)
|
||||
hFile:write(string.rep("\t", iRecursion));
|
||||
end
|
||||
|
||||
local writeKey = {};
|
||||
|
||||
function writeKey.string(hFile, value, iRecursion)
|
||||
hFile:write("[\"", value, "\"]")
|
||||
end
|
||||
|
||||
function writeKey.number(hFile, value, iRecursion)
|
||||
hFile:write("[", value, "]")
|
||||
end
|
||||
|
||||
local writeValue = {};
|
||||
|
||||
function writeValue.string(hFile, value, iRecursion)
|
||||
hFile:write("[==[", value, "]==]")
|
||||
end
|
||||
|
||||
function writeValue.number(hFile, value, iRecursion)
|
||||
hFile:write(value)
|
||||
end
|
||||
|
||||
function writeValue.boolean(hFile, value, iRecursion)
|
||||
if(value) then hFile:write("true"); else hFile:write("false"); end;
|
||||
end
|
||||
|
||||
function writeValue.table(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
|
||||
|
||||
return { WriteTable = function(hFile, outTable) writeValue.table(hFile, outTable) end, }
|
|
@ -1,197 +0,0 @@
|
|||
#include <string>
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "gl_test.hpp"
|
||||
#ifdef _WIN32
|
||||
#include "wgl_test.hpp"
|
||||
#else
|
||||
#include "glx_test.hpp"
|
||||
#endif
|
||||
#include <GL/freeglut.h>
|
||||
|
||||
GLuint positionBufferObject;
|
||||
GLuint program;
|
||||
GLuint vao;
|
||||
|
||||
GLuint BuildShader(GLenum eShaderType, const std::string &shaderText)
|
||||
{
|
||||
GLuint shader = gl::CreateShader(eShaderType);
|
||||
const char *strFileData = shaderText.c_str();
|
||||
gl::ShaderSource(shader, 1, &strFileData, NULL);
|
||||
|
||||
gl::CompileShader(shader);
|
||||
|
||||
GLint status;
|
||||
gl::GetShaderiv(shader, gl::COMPILE_STATUS, &status);
|
||||
if (status == gl::FALSE_)
|
||||
{
|
||||
GLint infoLogLength;
|
||||
gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &infoLogLength);
|
||||
|
||||
GLchar *strInfoLog = new GLchar[infoLogLength + 1];
|
||||
gl::GetShaderInfoLog(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()
|
||||
{
|
||||
gl::GenVertexArrays(1, &vao);
|
||||
gl::BindVertexArray(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,
|
||||
};
|
||||
|
||||
gl::GenBuffers(1, &positionBufferObject);
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, positionBufferObject);
|
||||
gl::BufferData(gl::ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, gl::STATIC_DRAW);
|
||||
gl::BindBuffer(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 = gl::CreateProgram();
|
||||
gl::AttachShader(program, vertShader);
|
||||
gl::AttachShader(program, fragShader);
|
||||
gl::LinkProgram(program);
|
||||
|
||||
GLint status;
|
||||
gl::GetProgramiv (program, gl::LINK_STATUS, &status);
|
||||
if (status == gl::FALSE_)
|
||||
{
|
||||
GLint infoLogLength;
|
||||
gl::GetProgramiv(program, gl::INFO_LOG_LENGTH, &infoLogLength);
|
||||
|
||||
GLchar *strInfoLog = new GLchar[infoLogLength + 1];
|
||||
gl::GetProgramInfoLog(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()
|
||||
{
|
||||
gl::ClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
gl::Clear(gl::COLOR_BUFFER_BIT);
|
||||
|
||||
gl::UseProgram(program);
|
||||
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, positionBufferObject);
|
||||
gl::EnableVertexAttribArray(0);
|
||||
gl::VertexAttribPointer(0, 4, gl::FLOAT, gl::FALSE_, 0, 0);
|
||||
|
||||
gl::DrawArrays(gl::TRIANGLES, 0, 3);
|
||||
|
||||
gl::DisableVertexAttribArray(0);
|
||||
gl::UseProgram(0);
|
||||
|
||||
glutSwapBuffers();
|
||||
}
|
||||
|
||||
//Called whenever the window is resized. The new window size is given, in pixels.
|
||||
//This is an opportunity to call gl::Viewport or gl::Scissor to keep up with the change in size.
|
||||
void reshape (int w, int h)
|
||||
{
|
||||
gl::Viewport(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);
|
||||
|
||||
gl::exts::LoadTest didLoad = gl::sys::LoadFunctions();
|
||||
if(!didLoad)
|
||||
printf("OpenGL: %i\n", didLoad.GetNumMissing());
|
||||
else
|
||||
printf("OpenGL Loaded!\n");
|
||||
|
||||
init();
|
||||
|
||||
#ifdef _WIN32
|
||||
HDC hdc = wglGetCurrentDC();
|
||||
wgl::exts::LoadTest load = wgl::sys::LoadFunctions(hdc);
|
||||
if(!load)
|
||||
printf("WGL: %i\n", load.GetNumMissing());
|
||||
else
|
||||
printf("WGL Loaded!\n");
|
||||
#else
|
||||
#endif
|
||||
|
||||
glutDisplayFunc(display);
|
||||
glutReshapeFunc(reshape);
|
||||
glutKeyboardFunc(keyboard);
|
||||
glutMainLoop();
|
||||
return 0;
|
||||
}
|
|
@ -1,193 +0,0 @@
|
|||
#include <string>
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "gl_test.hpp"
|
||||
#ifdef _WIN32
|
||||
#include "wgl_test.hpp"
|
||||
#else
|
||||
#include "glx_test.hpp"
|
||||
#endif
|
||||
#include <GL/freeglut.h>
|
||||
|
||||
GLuint positionBufferObject;
|
||||
GLuint program;
|
||||
GLuint vao;
|
||||
|
||||
GLuint BuildShader(GLenum eShaderType, const std::string &shaderText)
|
||||
{
|
||||
GLuint shader = gl::CreateShader(eShaderType);
|
||||
const char *strFileData = shaderText.c_str();
|
||||
gl::ShaderSource(shader, 1, &strFileData, NULL);
|
||||
|
||||
gl::CompileShader(shader);
|
||||
|
||||
GLint status;
|
||||
gl::GetShaderiv(shader, gl::COMPILE_STATUS, &status);
|
||||
if (status == gl::FALSE_)
|
||||
{
|
||||
GLint infoLogLength;
|
||||
gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &infoLogLength);
|
||||
|
||||
GLchar *strInfoLog = new GLchar[infoLogLength + 1];
|
||||
gl::GetShaderInfoLog(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,
|
||||
};
|
||||
|
||||
gl::GenBuffers(1, &positionBufferObject);
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, positionBufferObject);
|
||||
gl::BufferData(gl::ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, gl::STATIC_DRAW);
|
||||
gl::BindBuffer(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 = gl::CreateProgram();
|
||||
gl::AttachShader(program, vertShader);
|
||||
gl::AttachShader(program, fragShader);
|
||||
gl::LinkProgram(program);
|
||||
|
||||
GLint status;
|
||||
gl::GetProgramiv (program, gl::LINK_STATUS, &status);
|
||||
if (status == gl::FALSE_)
|
||||
{
|
||||
GLint infoLogLength;
|
||||
gl::GetProgramiv(program, gl::INFO_LOG_LENGTH, &infoLogLength);
|
||||
|
||||
GLchar *strInfoLog = new GLchar[infoLogLength + 1];
|
||||
gl::GetProgramInfoLog(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()
|
||||
{
|
||||
gl::ClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
gl::Clear(gl::COLOR_BUFFER_BIT);
|
||||
|
||||
gl::UseProgram(program);
|
||||
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, positionBufferObject);
|
||||
gl::EnableVertexAttribArray(0);
|
||||
gl::VertexAttribPointer(0, 4, gl::FLOAT, gl::FALSE_, 0, 0);
|
||||
|
||||
gl::DrawArrays(gl::TRIANGLES, 0, 3);
|
||||
|
||||
gl::DisableVertexAttribArray(0);
|
||||
gl::UseProgram(0);
|
||||
|
||||
glutSwapBuffers();
|
||||
}
|
||||
|
||||
//Called whenever the window is resized. The new window size is given, in pixels.
|
||||
//This is an opportunity to call gl::Viewport or gl::Scissor to keep up with the change in size.
|
||||
void reshape (int w, int h)
|
||||
{
|
||||
gl::Viewport(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);
|
||||
|
||||
gl::exts::LoadTest didLoad = gl::sys::LoadFunctions();
|
||||
if(!didLoad)
|
||||
printf("OpenGL: %i\n", didLoad.GetNumMissing());
|
||||
else
|
||||
printf("OpenGL Loaded!\n");
|
||||
|
||||
init();
|
||||
|
||||
#ifdef _WIN32
|
||||
HDC hdc = wglGetCurrentDC();
|
||||
wgl::exts::LoadTest load = wgl::sys::LoadFunctions(hdc);
|
||||
if(!load)
|
||||
printf("WGL: %i\n", load.GetNumMissing());
|
||||
else
|
||||
printf("WGL Loaded!\n");
|
||||
#else
|
||||
#endif
|
||||
|
||||
glutDisplayFunc(display);
|
||||
glutReshapeFunc(reshape);
|
||||
glutKeyboardFunc(keyboard);
|
||||
glutMainLoop();
|
||||
return 0;
|
||||
}
|
|
@ -1,191 +0,0 @@
|
|||
#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;
|
||||
}
|
|
@ -1,187 +0,0 @@
|
|||
#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
|
||||
|
||||
init();
|
||||
|
||||
|
||||
glutDisplayFunc(display);
|
||||
glutReshapeFunc(reshape);
|
||||
glutKeyboardFunc(keyboard);
|
||||
glutMainLoop();
|
||||
return 0;
|
||||
}
|
|
@ -1,187 +0,0 @@
|
|||
#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;
|
||||
}
|
|
@ -1,191 +0,0 @@
|
|||
#include <string>
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "gl_test.hpp"
|
||||
#ifdef _WIN32
|
||||
#include "wgl_test.hpp"
|
||||
#else
|
||||
#include "glx_test.hpp"
|
||||
#endif
|
||||
#include <GL/freeglut.h>
|
||||
|
||||
GLuint positionBufferObject;
|
||||
GLuint program;
|
||||
GLuint vao;
|
||||
|
||||
GLuint BuildShader(GLenum eShaderType, const std::string &shaderText)
|
||||
{
|
||||
GLuint shader = gl::CreateShader(eShaderType);
|
||||
const char *strFileData = shaderText.c_str();
|
||||
gl::ShaderSource(shader, 1, &strFileData, NULL);
|
||||
|
||||
gl::CompileShader(shader);
|
||||
|
||||
GLint status;
|
||||
gl::GetShaderiv(shader, gl::COMPILE_STATUS, &status);
|
||||
if (status == gl::FALSE_)
|
||||
{
|
||||
GLint infoLogLength;
|
||||
gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &infoLogLength);
|
||||
|
||||
GLchar *strInfoLog = new GLchar[infoLogLength + 1];
|
||||
gl::GetShaderInfoLog(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()
|
||||
{
|
||||
gl::GenVertexArrays(1, &vao);
|
||||
gl::BindVertexArray(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,
|
||||
};
|
||||
|
||||
gl::GenBuffers(1, &positionBufferObject);
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, positionBufferObject);
|
||||
gl::BufferData(gl::ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, gl::STATIC_DRAW);
|
||||
gl::BindBuffer(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 = gl::CreateProgram();
|
||||
gl::AttachShader(program, vertShader);
|
||||
gl::AttachShader(program, fragShader);
|
||||
gl::LinkProgram(program);
|
||||
|
||||
GLint status;
|
||||
gl::GetProgramiv (program, gl::LINK_STATUS, &status);
|
||||
if (status == gl::FALSE_)
|
||||
{
|
||||
GLint infoLogLength;
|
||||
gl::GetProgramiv(program, gl::INFO_LOG_LENGTH, &infoLogLength);
|
||||
|
||||
GLchar *strInfoLog = new GLchar[infoLogLength + 1];
|
||||
gl::GetProgramInfoLog(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()
|
||||
{
|
||||
gl::ClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
gl::Clear(gl::COLOR_BUFFER_BIT);
|
||||
|
||||
gl::UseProgram(program);
|
||||
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, positionBufferObject);
|
||||
gl::EnableVertexAttribArray(0);
|
||||
gl::VertexAttribPointer(0, 4, gl::FLOAT, gl::FALSE_, 0, 0);
|
||||
|
||||
gl::DrawArrays(gl::TRIANGLES, 0, 3);
|
||||
|
||||
gl::DisableVertexAttribArray(0);
|
||||
gl::UseProgram(0);
|
||||
|
||||
glutSwapBuffers();
|
||||
}
|
||||
|
||||
//Called whenever the window is resized. The new window size is given, in pixels.
|
||||
//This is an opportunity to call gl::Viewport or gl::Scissor to keep up with the change in size.
|
||||
void reshape (int w, int h)
|
||||
{
|
||||
gl::Viewport(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);
|
||||
|
||||
gl::sys::CheckExtensions();
|
||||
#ifdef _WIN32
|
||||
wgl::sys::CheckExtensions(wglGetCurrentDC());
|
||||
#endif
|
||||
|
||||
if(gl::exts::var_EXT_texture_compression_s3tc)
|
||||
printf("Yay!\n");
|
||||
else
|
||||
printf("Fooey.\n");
|
||||
init();
|
||||
|
||||
|
||||
glutDisplayFunc(display);
|
||||
glutReshapeFunc(reshape);
|
||||
glutKeyboardFunc(keyboard);
|
||||
glutMainLoop();
|
||||
return 0;
|
||||
}
|
|
@ -1,193 +0,0 @@
|
|||
#include <string>
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "gl_test.hpp"
|
||||
#ifdef _WIN32
|
||||
#include "wgl_test.hpp"
|
||||
#else
|
||||
#include "glx_test.hpp"
|
||||
#endif
|
||||
#include <GL/freeglut.h>
|
||||
|
||||
GLuint positionBufferObject;
|
||||
GLuint program;
|
||||
GLuint vao;
|
||||
|
||||
GLuint BuildShader(GLenum eShaderType, const std::string &shaderText)
|
||||
{
|
||||
GLuint shader = gl::CreateShader(eShaderType);
|
||||
const char *strFileData = shaderText.c_str();
|
||||
gl::ShaderSource(shader, 1, &strFileData, NULL);
|
||||
|
||||
gl::CompileShader(shader);
|
||||
|
||||
GLint status;
|
||||
gl::GetShaderiv(shader, gl::COMPILE_STATUS, &status);
|
||||
if (status == gl::FALSE_)
|
||||
{
|
||||
GLint infoLogLength;
|
||||
gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &infoLogLength);
|
||||
|
||||
GLchar *strInfoLog = new GLchar[infoLogLength + 1];
|
||||
gl::GetShaderInfoLog(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()
|
||||
{
|
||||
gl::GenVertexArrays(1, &vao);
|
||||
gl::BindVertexArray(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,
|
||||
};
|
||||
|
||||
gl::GenBuffers(1, &positionBufferObject);
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, positionBufferObject);
|
||||
gl::BufferData(gl::ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, gl::STATIC_DRAW);
|
||||
gl::BindBuffer(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 = gl::CreateProgram();
|
||||
gl::AttachShader(program, vertShader);
|
||||
gl::AttachShader(program, fragShader);
|
||||
gl::LinkProgram(program);
|
||||
|
||||
GLint status;
|
||||
gl::GetProgramiv (program, gl::LINK_STATUS, &status);
|
||||
if (status == gl::FALSE_)
|
||||
{
|
||||
GLint infoLogLength;
|
||||
gl::GetProgramiv(program, gl::INFO_LOG_LENGTH, &infoLogLength);
|
||||
|
||||
GLchar *strInfoLog = new GLchar[infoLogLength + 1];
|
||||
gl::GetProgramInfoLog(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()
|
||||
{
|
||||
gl::ClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
gl::Clear(gl::COLOR_BUFFER_BIT);
|
||||
|
||||
gl::UseProgram(program);
|
||||
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, positionBufferObject);
|
||||
gl::EnableVertexAttribArray(0);
|
||||
gl::VertexAttribPointer(0, 4, gl::FLOAT, gl::FALSE_, 0, 0);
|
||||
|
||||
gl::DrawArrays(gl::TRIANGLES, 0, 3);
|
||||
|
||||
gl::DisableVertexAttribArray(0);
|
||||
gl::UseProgram(0);
|
||||
|
||||
glutSwapBuffers();
|
||||
}
|
||||
|
||||
//Called whenever the window is resized. The new window size is given, in pixels.
|
||||
//This is an opportunity to call gl::Viewport or gl::Scissor to keep up with the change in size.
|
||||
void reshape (int w, int h)
|
||||
{
|
||||
gl::Viewport(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);
|
||||
|
||||
gl::sys::CheckExtensions();
|
||||
#ifdef _WIN32
|
||||
wgl::sys::CheckExtensions(wglGetCurrentDC());
|
||||
#endif
|
||||
|
||||
/*
|
||||
if(gl::exts::var_EXT_texture_compression_s3tc)
|
||||
printf("Yay!\n");
|
||||
else
|
||||
printf("Fooey.\n");
|
||||
*/
|
||||
init();
|
||||
|
||||
|
||||
glutDisplayFunc(display);
|
||||
glutReshapeFunc(reshape);
|
||||
glutKeyboardFunc(keyboard);
|
||||
glutMainLoop();
|
||||
return 0;
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
|
||||
dofile "glsdk/links.lua"
|
||||
|
||||
solution "test"
|
||||
configurations {"Debug", "Release"}
|
||||
defines {"_CRT_SECURE_NO_WARNINGS", "_SCL_SECURE_NO_WARNINGS"}
|
||||
|
||||
local tests =
|
||||
{
|
||||
{name = "ptr_cpp"},
|
||||
{name = "ptr_c"},
|
||||
{name = "ptr_cpp_comp"},
|
||||
{name = "ptr_c_comp"},
|
||||
{name = "func_cpp"},
|
||||
{name = "func_cpp_comp"},
|
||||
{name = "noload_cpp"},
|
||||
{name = "noload_cpp_noext"},
|
||||
{name = "noload_c"},
|
||||
{name = "noload_c_old"},
|
||||
{name = "noload_c_noext"},
|
||||
}
|
||||
|
||||
local oldDir = os.getcwd()
|
||||
for _, test in ipairs(tests) do
|
||||
os.chdir(path.getabsolute(test.name))
|
||||
|
||||
project(test.name .. "_test")
|
||||
kind "ConsoleApp"
|
||||
language "c++"
|
||||
objdir("obj")
|
||||
files {"**.cpp"}
|
||||
files {"**.c"}
|
||||
files {"**.hpp"}
|
||||
files {"**.h"}
|
||||
|
||||
if(test.include) then
|
||||
includedirs(test.include)
|
||||
end
|
||||
|
||||
UseLibs {"freeglut"}
|
||||
|
||||
configuration "windows"
|
||||
links {"glu32", "opengl32", "gdi32", "winmm", "user32"}
|
||||
|
||||
configuration "linux"
|
||||
links {"GL", "GLU", "Xrandr", "X11"}
|
||||
|
||||
configuration "Debug"
|
||||
targetsuffix "D"
|
||||
defines "_DEBUG"
|
||||
flags "Symbols"
|
||||
|
||||
configuration "Release"
|
||||
defines "NDEBUG"
|
||||
flags {"OptimizeSpeed", "NoFramePointer", "ExtraWarnings", "NoEditAndContinue"};
|
||||
|
||||
os.chdir(oldDir)
|
||||
end
|
|
@ -1,197 +0,0 @@
|
|||
#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 glScissor 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);
|
||||
|
||||
int loaded_gl = ogl_LoadFunctions();
|
||||
if(!loaded_gl)
|
||||
printf("Failed to load OpenGL.\n");
|
||||
else
|
||||
printf("OpenGL: %i\n", loaded_gl - ogl_LOAD_SUCCEEDED);
|
||||
|
||||
init();
|
||||
|
||||
#ifdef _WIN32
|
||||
HDC hdc = wglGetCurrentDC();
|
||||
int loaded_wgl = wgl_LoadFunctions(hdc);
|
||||
if(!loaded_wgl)
|
||||
printf("Failed to load WGL.\n");
|
||||
else
|
||||
printf("WGL: %i\n", loaded_wgl - wgl_LOAD_SUCCEEDED);
|
||||
#else
|
||||
#endif
|
||||
|
||||
glutDisplayFunc(display);
|
||||
glutReshapeFunc(reshape);
|
||||
glutKeyboardFunc(keyboard);
|
||||
glutMainLoop();
|
||||
return 0;
|
||||
}
|
|
@ -1,197 +0,0 @@
|
|||
#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 glScissor 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_COMPATIBILITY_PROFILE);
|
||||
glutInitWindowSize (width, height);
|
||||
glutInitWindowPosition (300, 200);
|
||||
glutCreateWindow (argv[0]);
|
||||
|
||||
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
|
||||
|
||||
int loaded_gl = ogl_LoadFunctions();
|
||||
if(!loaded_gl)
|
||||
printf("Failed to load OpenGL.\n");
|
||||
else
|
||||
printf("OpenGL: %i\n", loaded_gl - ogl_LOAD_SUCCEEDED);
|
||||
|
||||
init();
|
||||
|
||||
#ifdef _WIN32
|
||||
HDC hdc = wglGetCurrentDC();
|
||||
int loaded_wgl = wgl_LoadFunctions(hdc);
|
||||
if(!loaded_wgl)
|
||||
printf("Failed to load WGL.\n");
|
||||
else
|
||||
printf("WGL: %i\n", loaded_wgl - wgl_LOAD_SUCCEEDED);
|
||||
#else
|
||||
#endif
|
||||
|
||||
glutDisplayFunc(display);
|
||||
glutReshapeFunc(reshape);
|
||||
glutKeyboardFunc(keyboard);
|
||||
glutMainLoop();
|
||||
return 0;
|
||||
}
|
|
@ -1,197 +0,0 @@
|
|||
#include <string>
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "gl_test.hpp"
|
||||
#ifdef _WIN32
|
||||
#include "wgl_test.hpp"
|
||||
#else
|
||||
#include "glx_test.hpp"
|
||||
#endif
|
||||
#include <GL/freeglut.h>
|
||||
|
||||
GLuint positionBufferObject;
|
||||
GLuint program;
|
||||
GLuint vao;
|
||||
|
||||
GLuint BuildShader(GLenum eShaderType, const std::string &shaderText)
|
||||
{
|
||||
GLuint shader = gl::CreateShader(eShaderType);
|
||||
const char *strFileData = shaderText.c_str();
|
||||
gl::ShaderSource(shader, 1, &strFileData, NULL);
|
||||
|
||||
gl::CompileShader(shader);
|
||||
|
||||
GLint status;
|
||||
gl::GetShaderiv(shader, gl::COMPILE_STATUS, &status);
|
||||
if (status == gl::FALSE_)
|
||||
{
|
||||
GLint infoLogLength;
|
||||
gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &infoLogLength);
|
||||
|
||||
GLchar *strInfoLog = new GLchar[infoLogLength + 1];
|
||||
gl::GetShaderInfoLog(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()
|
||||
{
|
||||
gl::GenVertexArrays(1, &vao);
|
||||
gl::BindVertexArray(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,
|
||||
};
|
||||
|
||||
gl::GenBuffers(1, &positionBufferObject);
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, positionBufferObject);
|
||||
gl::BufferData(gl::ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, gl::STATIC_DRAW);
|
||||
gl::BindBuffer(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 = gl::CreateProgram();
|
||||
gl::AttachShader(program, vertShader);
|
||||
gl::AttachShader(program, fragShader);
|
||||
gl::LinkProgram(program);
|
||||
|
||||
GLint status;
|
||||
gl::GetProgramiv (program, gl::LINK_STATUS, &status);
|
||||
if (status == gl::FALSE_)
|
||||
{
|
||||
GLint infoLogLength;
|
||||
gl::GetProgramiv(program, gl::INFO_LOG_LENGTH, &infoLogLength);
|
||||
|
||||
GLchar *strInfoLog = new GLchar[infoLogLength + 1];
|
||||
gl::GetProgramInfoLog(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()
|
||||
{
|
||||
gl::ClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
gl::Clear(gl::COLOR_BUFFER_BIT);
|
||||
|
||||
gl::UseProgram(program);
|
||||
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, positionBufferObject);
|
||||
gl::EnableVertexAttribArray(0);
|
||||
gl::VertexAttribPointer(0, 4, gl::FLOAT, gl::FALSE_, 0, 0);
|
||||
|
||||
gl::DrawArrays(gl::TRIANGLES, 0, 3);
|
||||
|
||||
gl::DisableVertexAttribArray(0);
|
||||
gl::UseProgram(0);
|
||||
|
||||
glutSwapBuffers();
|
||||
}
|
||||
|
||||
//Called whenever the window is resized. The new window size is given, in pixels.
|
||||
//This is an opportunity to call gl::Viewport or gl::Scissor to keep up with the change in size.
|
||||
void reshape (int w, int h)
|
||||
{
|
||||
gl::Viewport(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);
|
||||
|
||||
gl::exts::LoadTest didLoad = gl::sys::LoadFunctions();
|
||||
if(!didLoad)
|
||||
printf("OpenGL: %i\n", didLoad.GetNumMissing());
|
||||
else
|
||||
printf("OpenGL Loaded!\n");
|
||||
|
||||
init();
|
||||
|
||||
#ifdef _WIN32
|
||||
HDC hdc = wglGetCurrentDC();
|
||||
wgl::exts::LoadTest load = wgl::sys::LoadFunctions(hdc);
|
||||
if(!load)
|
||||
printf("WGL: %i\n", load.GetNumMissing());
|
||||
else
|
||||
printf("WGL Loaded!\n");
|
||||
#else
|
||||
#endif
|
||||
|
||||
glutDisplayFunc(display);
|
||||
glutReshapeFunc(reshape);
|
||||
glutKeyboardFunc(keyboard);
|
||||
glutMainLoop();
|
||||
return 0;
|
||||
}
|
|
@ -1,197 +0,0 @@
|
|||
#include <string>
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "gl_test.hpp"
|
||||
#ifdef _WIN32
|
||||
#include "wgl_test.hpp"
|
||||
#else
|
||||
#include "glx_test.hpp"
|
||||
#endif
|
||||
#include <GL/freeglut.h>
|
||||
|
||||
GLuint positionBufferObject;
|
||||
GLuint program;
|
||||
GLuint vao;
|
||||
|
||||
GLuint BuildShader(GLenum eShaderType, const std::string &shaderText)
|
||||
{
|
||||
GLuint shader = gl::CreateShader(eShaderType);
|
||||
const char *strFileData = shaderText.c_str();
|
||||
gl::ShaderSource(shader, 1, &strFileData, NULL);
|
||||
|
||||
gl::CompileShader(shader);
|
||||
|
||||
GLint status;
|
||||
gl::GetShaderiv(shader, gl::COMPILE_STATUS, &status);
|
||||
if (status == gl::FALSE_)
|
||||
{
|
||||
GLint infoLogLength;
|
||||
gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &infoLogLength);
|
||||
|
||||
GLchar *strInfoLog = new GLchar[infoLogLength + 1];
|
||||
gl::GetShaderInfoLog(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()
|
||||
{
|
||||
gl::GenVertexArrays(1, &vao);
|
||||
gl::BindVertexArray(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,
|
||||
};
|
||||
|
||||
gl::GenBuffers(1, &positionBufferObject);
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, positionBufferObject);
|
||||
gl::BufferData(gl::ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, gl::STATIC_DRAW);
|
||||
gl::BindBuffer(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 = gl::CreateProgram();
|
||||
gl::AttachShader(program, vertShader);
|
||||
gl::AttachShader(program, fragShader);
|
||||
gl::LinkProgram(program);
|
||||
|
||||
GLint status;
|
||||
gl::GetProgramiv (program, gl::LINK_STATUS, &status);
|
||||
if (status == gl::FALSE_)
|
||||
{
|
||||
GLint infoLogLength;
|
||||
gl::GetProgramiv(program, gl::INFO_LOG_LENGTH, &infoLogLength);
|
||||
|
||||
GLchar *strInfoLog = new GLchar[infoLogLength + 1];
|
||||
gl::GetProgramInfoLog(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()
|
||||
{
|
||||
gl::ClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
gl::Clear(gl::COLOR_BUFFER_BIT);
|
||||
|
||||
gl::UseProgram(program);
|
||||
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, positionBufferObject);
|
||||
gl::EnableVertexAttribArray(0);
|
||||
gl::VertexAttribPointer(0, 4, gl::FLOAT, gl::FALSE_, 0, 0);
|
||||
|
||||
gl::DrawArrays(gl::TRIANGLES, 0, 3);
|
||||
|
||||
gl::DisableVertexAttribArray(0);
|
||||
gl::UseProgram(0);
|
||||
|
||||
glutSwapBuffers();
|
||||
}
|
||||
|
||||
//Called whenever the window is resized. The new window size is given, in pixels.
|
||||
//This is an opportunity to call gl::Viewport or gl::Scissor to keep up with the change in size.
|
||||
void reshape (int w, int h)
|
||||
{
|
||||
gl::Viewport(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_COMPATIBILITY_PROFILE);
|
||||
glutInitWindowSize (width, height);
|
||||
glutInitWindowPosition (300, 200);
|
||||
glutCreateWindow (argv[0]);
|
||||
|
||||
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
|
||||
|
||||
gl::exts::LoadTest didLoad = gl::sys::LoadFunctions();
|
||||
if(!didLoad)
|
||||
printf("OpenGL: %i\n", didLoad.GetNumMissing());
|
||||
else
|
||||
printf("OpenGL Loaded!\n");
|
||||
|
||||
init();
|
||||
|
||||
#ifdef _WIN32
|
||||
HDC hdc = wglGetCurrentDC();
|
||||
wgl::exts::LoadTest load = wgl::sys::LoadFunctions(hdc);
|
||||
if(!load)
|
||||
printf("WGL: %i\n", load.GetNumMissing());
|
||||
else
|
||||
printf("WGL Loaded!\n");
|
||||
#else
|
||||
#endif
|
||||
|
||||
glutDisplayFunc(display);
|
||||
glutReshapeFunc(reshape);
|
||||
glutKeyboardFunc(keyboard);
|
||||
glutMainLoop();
|
||||
return 0;
|
||||
}
|
|
@ -4,27 +4,16 @@
|
|||
#include "wgl_obs.h"
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <mach-o/dyld.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
static void* AppleGLGetProcAddress (const GLubyte *name)
|
||||
static void* AppleGLGetProcAddress (const char *name)
|
||||
{
|
||||
static const struct mach_header* image = NULL;
|
||||
NSSymbol symbol;
|
||||
char* symbolName;
|
||||
if (NULL == image)
|
||||
{
|
||||
image = NSAddImage("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", NSADDIMAGE_OPTION_RETURN_ON_ERROR);
|
||||
}
|
||||
/* prepend a '_' for the Unix C symbol mangling convention */
|
||||
symbolName = malloc(strlen((const char*)name) + 2);
|
||||
strcpy(symbolName+1, (const char*)name);
|
||||
symbolName[0] = '_';
|
||||
symbol = NULL;
|
||||
/* if (NSIsSymbolNameDefined(symbolName))
|
||||
symbol = NSLookupAndBindSymbol(symbolName); */
|
||||
symbol = image ? NSLookupSymbolInImage(image, symbolName, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR) : NULL;
|
||||
free(symbolName);
|
||||
return symbol ? NSAddressOfSymbol(symbol) : NULL;
|
||||
static void* image = NULL;
|
||||
|
||||
if (image == NULL)
|
||||
image = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
|
||||
|
||||
return (image ? dlsym(image, name) : NULL);
|
||||
}
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
|
|
Loading…
Reference in New Issue