added glad generator and a glad runtime

This commit is contained in:
Hartmut Seichter 2017-06-29 07:15:32 +02:00
parent 2017f6195e
commit ac18a84a9c
62 changed files with 32373 additions and 10 deletions

View file

@ -3,6 +3,9 @@
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/../deps/glfw-3.2.1/include
${CMAKE_CURRENT_SOURCE_DIR}/../deps/lua-5.3.4/src
${CMAKE_CURRENT_SOURCE_DIR}/../deps/glad/include
)
add_library(pw

View file

@ -30,7 +30,8 @@ void pw::context::yield()
void pw::context::script(const char *s)
{
_lua.script("w = pw.window.new()");
_lua.script("w:set_title(\"pixwerks\")");
_lua.script("w:set_title(\"pixwerks alpha\")");
_lua.script("w:set_size(320,240)");
_lua.script("while w:update() do end");
// luaL_loadstring(_state,s);

View file

@ -3,6 +3,7 @@
pw::window::window() {
_window = glfwCreateWindow(640, 480, "pixwerxs", NULL, NULL);
}
pw::window::~window() {
@ -31,13 +32,18 @@ void pw::window::set_title(const char *t)
glfwSetWindowTitle(_window,t);
}
void pw::window::load(sol::table &ns) {
void pw::window::set_size(int w,int h) {
glfwSetWindowSize(_window,w,h);
}
void pw::window::load(sol::table &ns)
{
glfwInit();
ns.new_usertype<window>("window",
"update",&window::update,
"set_title",&window::set_title
"set_title",&window::set_title,
"set_size",&window::set_size
);
}
}

View file

@ -1,7 +1,9 @@
#ifndef PW_WINDOW_HPP
#define PW_WINDOW_HPP
#include "glad/glad.h"
#include "GLFW/glfw3.h"
#include "sol.hpp"
namespace pw {
@ -23,6 +25,7 @@ public:
static void load(sol::table &ns);
void set_size(int w, int h);
};
}

View file

@ -1,3 +1,4 @@
add_subdirectory(glfw-3.2.1)
add_subdirectory(lua-5.3.4)
add_subdirectory(glad)

View file

@ -0,0 +1,4 @@
project(glad)
add_subdirectory(src)

View file

@ -0,0 +1,285 @@
#ifndef __khrplatform_h_
#define __khrplatform_h_
/*
** Copyright (c) 2008-2009 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are 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 Materials.
**
** THE MATERIALS ARE 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
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/* Khronos platform-specific types and definitions.
*
* $Revision: 32517 $ on $Date: 2016-03-11 02:41:19 -0800 (Fri, 11 Mar 2016) $
*
* Adopters may modify this file to suit their platform. Adopters are
* encouraged to submit platform specific modifications to the Khronos
* group so that they can be included in future versions of this file.
* Please submit changes by sending them to the public Khronos Bugzilla
* (http://khronos.org/bugzilla) by filing a bug against product
* "Khronos (general)" component "Registry".
*
* A predefined template which fills in some of the bug fields can be
* reached using http://tinyurl.com/khrplatform-h-bugreport, but you
* must create a Bugzilla login first.
*
*
* See the Implementer's Guidelines for information about where this file
* should be located on your system and for more details of its use:
* http://www.khronos.org/registry/implementers_guide.pdf
*
* This file should be included as
* #include <KHR/khrplatform.h>
* by Khronos client API header files that use its types and defines.
*
* The types in khrplatform.h should only be used to define API-specific types.
*
* Types defined in khrplatform.h:
* khronos_int8_t signed 8 bit
* khronos_uint8_t unsigned 8 bit
* khronos_int16_t signed 16 bit
* khronos_uint16_t unsigned 16 bit
* khronos_int32_t signed 32 bit
* khronos_uint32_t unsigned 32 bit
* khronos_int64_t signed 64 bit
* khronos_uint64_t unsigned 64 bit
* khronos_intptr_t signed same number of bits as a pointer
* khronos_uintptr_t unsigned same number of bits as a pointer
* khronos_ssize_t signed size
* khronos_usize_t unsigned size
* khronos_float_t signed 32 bit floating point
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
* nanoseconds
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
* khronos_boolean_enum_t enumerated boolean type. This should
* only be used as a base type when a client API's boolean type is
* an enum. Client APIs which use an integer or other type for
* booleans cannot use this as the base type for their boolean.
*
* Tokens defined in khrplatform.h:
*
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
*
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
*
* Calling convention macros defined in this file:
* KHRONOS_APICALL
* KHRONOS_APIENTRY
* KHRONOS_APIATTRIBUTES
*
* These may be used in function prototypes as:
*
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
* int arg1,
* int arg2) KHRONOS_APIATTRIBUTES;
*/
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APICALL
*-------------------------------------------------------------------------
* This precedes the return type of the function in the function prototype.
*/
#if defined(_WIN32) && !defined(__SCITECH_SNAP__)
# define KHRONOS_APICALL __declspec(dllimport)
#elif defined (__SYMBIAN32__)
# define KHRONOS_APICALL IMPORT_C
#elif defined(__ANDROID__)
# include <sys/cdefs.h>
# define KHRONOS_APICALL __attribute__((visibility("default"))) __NDK_FPABI__
#else
# define KHRONOS_APICALL
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIENTRY
*-------------------------------------------------------------------------
* This follows the return type of the function and precedes the function
* name in the function prototype.
*/
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
/* Win32 but not WinCE */
# define KHRONOS_APIENTRY __stdcall
#else
# define KHRONOS_APIENTRY
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIATTRIBUTES
*-------------------------------------------------------------------------
* This follows the closing parenthesis of the function prototype arguments.
*/
#if defined (__ARMCC_2__)
#define KHRONOS_APIATTRIBUTES __softfp
#else
#define KHRONOS_APIATTRIBUTES
#endif
/*-------------------------------------------------------------------------
* basic type definitions
*-----------------------------------------------------------------------*/
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
/*
* Using <stdint.h>
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(__VMS ) || defined(__sgi)
/*
* Using <inttypes.h>
*/
#include <inttypes.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
/*
* Win32
*/
typedef __int32 khronos_int32_t;
typedef unsigned __int32 khronos_uint32_t;
typedef __int64 khronos_int64_t;
typedef unsigned __int64 khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(__sun__) || defined(__digital__)
/*
* Sun or Digital
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#if defined(__arch64__) || defined(_LP64)
typedef long int khronos_int64_t;
typedef unsigned long int khronos_uint64_t;
#else
typedef long long int khronos_int64_t;
typedef unsigned long long int khronos_uint64_t;
#endif /* __arch64__ */
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif 0
/*
* Hypothetical platform with no float or int64 support
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#define KHRONOS_SUPPORT_INT64 0
#define KHRONOS_SUPPORT_FLOAT 0
#else
/*
* Generic fallback
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#endif
/*
* Types that are (so far) the same on all platforms
*/
typedef signed char khronos_int8_t;
typedef unsigned char khronos_uint8_t;
typedef signed short int khronos_int16_t;
typedef unsigned short int khronos_uint16_t;
/*
* Types that differ between LLP64 and LP64 architectures - in LLP64,
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
* to be the only LLP64 architecture in current use.
*/
#ifdef _WIN64
typedef signed long long int khronos_intptr_t;
typedef unsigned long long int khronos_uintptr_t;
typedef signed long long int khronos_ssize_t;
typedef unsigned long long int khronos_usize_t;
#else
typedef signed long int khronos_intptr_t;
typedef unsigned long int khronos_uintptr_t;
typedef signed long int khronos_ssize_t;
typedef unsigned long int khronos_usize_t;
#endif
#if KHRONOS_SUPPORT_FLOAT
/*
* Float type
*/
typedef float khronos_float_t;
#endif
#if KHRONOS_SUPPORT_INT64
/* Time types
*
* These types can be used to represent a time interval in nanoseconds or
* an absolute Unadjusted System Time. Unadjusted System Time is the number
* of nanoseconds since some arbitrary system event (e.g. since the last
* time the system booted). The Unadjusted System Time is an unsigned
* 64 bit value that wraps back to 0 every 584 years. Time intervals
* may be either signed or unsigned.
*/
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
typedef khronos_int64_t khronos_stime_nanoseconds_t;
#endif
/*
* Dummy value used to pad enum types to 32 bits.
*/
#ifndef KHRONOS_MAX_ENUM
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
#endif
/*
* Enumerated boolean type
*
* Values other than zero should be considered to be true. Therefore
* comparisons should not be made against KHRONOS_TRUE.
*/
typedef enum {
KHRONOS_FALSE = 0,
KHRONOS_TRUE = 1,
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
} khronos_boolean_enum_t;
#endif /* __khrplatform_h_ */

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,3 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include)
add_library(glad STATIC glad.c)

9598
src/deps/glad/src/glad.c Normal file

File diff suppressed because one or more lines are too long

14
tools/glad-0.1.14a0/.gitignore vendored Normal file
View file

@ -0,0 +1,14 @@
*.pyc
*.xml
*.kdev4
build/
*.o
a.out
*.kdev_include_paths
main.c
*.diff
.idea
dist/
*.egg-info
khrplatform.h
eglplatform.h

View file

@ -0,0 +1,90 @@
cmake_minimum_required(VERSION 3.0)
# Silence warning about if()
if(NOT CMAKE_VERSION VERSION_LESS 3.1)
cmake_policy(SET CMP0054 NEW)
endif()
project(GLAD)
set(GLAD_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(GLAD_OUT_DIR "${CMAKE_CURRENT_BINARY_DIR}")
find_package(PythonInterp REQUIRED)
# Options
set(GLAD_PROFILE "compatibility" CACHE STRING "OpenGL profile")
set(GLAD_API "" CACHE STRING "API type/version pairs, like \"gl=3.2,gles=\", no version means latest")
set(GLAD_GENERATOR "c" CACHE STRING "Language to generate the binding for")
set(GLAD_EXTENSIONS "" CACHE STRING "Path to extensions file or comma separated list of extensions, if missing all extensions are included")
set(GLAD_SPEC "gl" CACHE STRING "Name of the spec")
set(GLAD_NO_LOADER OFF CACHE BOOL "No loader")
set(GLAD_EXPORT ON CACHE BOOL "Set export variables for external project")
set(GLAD_INSTALL OFF CACHE BOOL "Generate installation target")
if(GLAD_GENERATOR STREQUAL "d")
list(APPEND GLAD_SOURCES
"${GLAD_OUT_DIR}/glad/gl/all.d"
"${GLAD_OUT_DIR}/glad/gl/enums.d"
"${GLAD_OUT_DIR}/glad/gl/ext.d"
"${GLAD_OUT_DIR}/glad/gl/funcs.d"
"${GLAD_OUT_DIR}/glad/gl/gl.d"
"${GLAD_OUT_DIR}/glad/gl/loader.d"
"${GLAD_OUT_DIR}/glad/gl/types.d"
)
elseif(GLAD_GENERATOR STREQUAL "volt")
list(APPEND GLAD_SOURCES
"${GLAD_OUT_DIR}/amp/gl/enums.volt"
"${GLAD_OUT_DIR}/amp/gl/ext.volt"
"${GLAD_OUT_DIR}/amp/gl/funcs.volt"
"${GLAD_OUT_DIR}/amp/gl/gl.volt"
"${GLAD_OUT_DIR}/amp/gl/loader.volt"
"${GLAD_OUT_DIR}/amp/gl/package.volt"
"${GLAD_OUT_DIR}/amp/gl/types.volt"
)
else()
set(GLAD_INCLUDE_DIRS "${GLAD_OUT_DIR}/include")
set(GLAD_LINKER_LANGUAGE CXX)
list(APPEND GLAD_SOURCES
"${GLAD_OUT_DIR}/src/glad.c"
"${GLAD_INCLUDE_DIRS}/glad/glad.h"
)
endif()
if(GLAD_NO_LOADER)
set(GLAD_NO_LOADER_ARG "--no-loader")
endif()
add_custom_command(
OUTPUT ${GLAD_SOURCES}
COMMAND ${PYTHON_EXECUTABLE} -m glad
--profile=${GLAD_PROFILE}
--out-path=${GLAD_OUT_DIR}
--api=${GLAD_API}
--generator=${GLAD_GENERATOR}
--extensions=${GLAD_EXTENSIONS}
--spec=${GLAD_SPEC}
${GLAD_NO_LOADER_ARG}
WORKING_DIRECTORY ${GLAD_DIR}
COMMENT "Generating GLAD"
)
add_library(glad STATIC ${GLAD_SOURCES})
target_include_directories(glad PUBLIC ${GLAD_INCLUDE_DIRS})
if(GLAD_LINKER_LANGUAGE)
set_target_properties(glad PROPERTIES LINKER_LANGUAGE ${GLAD_LINKER_LANGUAGE})
endif()
# Export
if(GLAD_EXPORT)
set(GLAD_LIBRARIES glad PARENT_SCOPE)
set(GLAD_INCLUDE_DIRS ${GLAD_INCLUDE_DIRS} PARENT_SCOPE)
endif()
# Install
if(GLAD_INSTALL)
if(GLAD_INCLUDE_DIRS)
install(DIRECTORY ${GLAD_INCLUDE_DIRS} DESTINATION ${CMAKE_INSTALL_PREFIX})
endif()
install(TARGETS glad EXPORT glad-targets
ARCHIVE DESTINATION lib)
endif()

View file

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2013 David Herberth
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.

View file

@ -0,0 +1,285 @@
glad
====
GL/GLES/EGL/GLX/WGL Loader-Generator based on the official specs.
Checkout the [webservice](http://glad.dav1d.de) to generate the files you need!
```c
// GLAD_DEBUG is only defined if the c-debug generator was used
#ifdef GLAD_DEBUG
// logs every gl call to the console
void pre_gl_call(const char *name, void *funcptr, int len_args, ...) {
printf("Calling: %s (%d arguments)\n", name, len_args);
}
#endif
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(width, height);
glutCreateWindow("cookie");
glutReshapeFunc(reshape);
glutDisplayFunc(display);
if(!gladLoadGL()) {
printf("Something went wrong!\n");
exit(-1);
}
#ifdef GLAD_DEBUG
// before every opengl call call pre_gl_call
glad_set_pre_callback(pre_gl_call);
// post callback checks for glGetError by default
// don't use the callback for glClear
// (glClear could be replaced with your own function)
glad_debug_glClear = glad_glClear;
#endif
// gladLoadGLLoader(&glutGetProcAddress);
printf("OpenGL %d.%d\n", GLVersion.major, GLVersion.minor);
if (GLVersion.major < 2) {
printf("Your system doesn't support OpenGL >= 2!\n");
return -1;
}
printf("OpenGL %s, GLSL %s\n", glGetString(GL_VERSION),
glGetString(GL_SHADING_LANGUAGE_VERSION));
glutMainLoop();
return 0;
}
```
Checkout the full example: [simple.c](https://github.com/Dav1dde/glad/blob/master/example/c/simple.c)
Or the C++ example using [GLFW](http://glfw.org):
[hellowindow2.cpp](https://github.com/Dav1dde/glad/blob/master/example/c%2B%2B/hellowindow2.cpp)
## Usage ##
**If you don't want to install glad you can use the [webservice](http://glad.dav1d.de)**
Otherwise either install glad via pip:
# Windows
pip install glad
# Linux
pip install --user glad
# Linux global (root)
pip install glad
glad --help
To install the most recent version from Github:
pip install --upgrade git+https://github.com/dav1dde/glad.git#egg=glad
Or launch glad directly (after cloning the repository):
python -m glad --help
Possible commandline options:
usage: glad [-h] [--profile {core,compatibility}] --out-path OUT
[--api API] --generator {c,d,volt}
[--extensions EXTENSIONS] [--spec {gl,egl,glx,wgl}]
[--no-loader]
Uses the official Khronos-XML specs to generate a GL/GLES/EGL/GLX/WGL Loader
made for your needs. Glad currently supports the languages C, D and Volt.
optional arguments:
-h, --help show this help message and exit
--profile {core,compatibility}
OpenGL profile (defaults to compatibility)
--out-path OUT Output path for loader
--api API API type/version pairs, like "gl=3.2,gles=", no
version means latest
--generator {c,c-debug,d,volt}
Language to generate the binding for
--extensions EXTENSIONS
Path to extensions file or comma separated list of
extensions, if missing all extensions are included
--spec {gl,egl,glx,wgl}
Name of the spec
--no-loader
--omit-khrplatform Omits inclusion of the khrplatform.h file which is
often unnecessary. Only has an effect if used
together with c generators.
--local-files Forces every file directly into the output directory.
No src or include subdirectories are generated. Only
has an effect if used together with c generators.
To generate a loader for C with two extensions, it could look like this:
python main.py --generator=c --extensions=GL_EXT_framebuffer_multisample,GL_EXT_texture_filter_anisotropic --out-path=GL
`--out-path` and `--generator` are required!
If the `--extensions` option is missing, glad adds support for all extensions found in the OpenGL spec.
## Generators ##
### C/C++ ###
```c
struct gladGLversionStruct {
int major;
int minor;
};
extern struct gladGLversionStruct GLVersion;
typedef void* (* GLADloadproc)(const char *name);
/*
* Load OpenGL using the internal loader.
* Returns the true/1 if loading succeeded.
*
*/
int gladLoadGL(void);
/*
* Load OpenGL using an external loader like SDL_GL_GetProcAddress.
*
* Substitute GL with the API you generated
*
*/
void gladLoadGLLoader(GLADloadproc);
```
`glad.h` completely replaces any `gl.h` or `gl3.h` only include `glad.h`.
```c
if(!gladLoadGL()) { exit(-1) };
printf("OpenGL Version %d.%d loaded", GLVersion.major, GLVersion.minor);
if(GLAD_GL_EXT_framebuffer_multisample) {
/* GL_EXT_framebuffer_multisample is supported */
}
if(GLAD_GL_VERSION_3_0) {
/* We support at least OpenGL version 3 */
}
```
On non-Windows platforms glad requires `libdl`, make sure to link with it (`-ldl` for gcc)!
Note, there are two kinds of extension/version symbols, e.g. `GL_VERSION_3_0` and
`GLAD_VERSION_3_0`. Latter is a runtime boolean (represented as integer), whereas
the first (not prefixed with `GLAD_`) is a compiletime-constant, indicating that this
header supports this version (the official headers define these symbols as well).
The runtime booleans are only valid *after* a succesful call to `gladLoadGL` or `gladLoadGLLoader`.
### C/C++ Debug ###
The C-Debug generator extends the API by these two functions:
```c
// this symbol only exists if generated with the c-debug generator
#define GLAD_DEBUG
typedef void (* GLADcallback)(const char *name, void *funcptr, int len_args, ...);
/*
* Sets a callback which will be called before every function call
* to a function loaded by glad.
*
*/
GLAPI void glad_set_pre_callback(GLADcallback cb);
/*
* Sets a callback which will be called after every function call
* to a function loaded by glad.
*
*/
GLAPI void glad_set_post_callback(GLADcallback cb);
```
To call a function like `glGetError` in a callback prefix it with `glad_`, e.g.
the default post callback looks like this:
```c
void _post_call_callback_default(const char *name, void *funcptr, int len_args, ...) {
GLenum error_code;
error_code = glad_glGetError();
if (error_code != GL_NO_ERROR) {
fprintf(stderr, "ERROR %d in %s\n", error_code, name);
}
}
```
You can also submit own implementations for every call made by overwriting
the function pointer with the name of the function prefixed by `glad_debug_`.
E.g. you could disable the callbacks for glClear with `glad_debug_glClear = glad_glClear`, where
`glad_glClear` is the function pointer loaded by glad.
The `glClear` macro is defined as `#define glClear glad_debug_glClear`,
`glad_debug_glClear` is initialized with a default implementation, which calls
the two callbacks and the real function, in this case `glad_glClear`.
### D ###
Import `glad.gl` for OpenGL functions/extensions, import `glad.loader` to import
the functions needed to initialize glad and load the OpenGL functions.
```d
enforce(gladLoadGL()); // optionally you can pass a loader to this function
writefln("OpenGL Version %d.%d loaded", GLVersion.major, GLVersion.minor);
if(GL_EXT_framebuffer_multisample) {
/* GL_EXT_framebuffer_multisample is supported */
}
if(GL_VERSION_3_0) {
/* We support at least OpenGL version 3 */
}
```
On non-Windows platforms glad requires `libdl`, make sure to link with it (`L-ldl` for dmd)!
## FAQ ##
### glad includes windows.h which breaks my code!
Defining `APIENTRY` before including `glad.h` solves this problem:
```c
#ifdef _WIN32
#define APIENTRY __stdcall
#endif
#include <glad/glad.h>
```
But make sure you have the correct definition of `APIENTRY` for platforms which define `_WIN32` but don't use `__stdcall`
Relevant issue: [#42](https://github.com/Dav1dde/glad/issues/42)
## Contribute ##
Contributing is easy! Found a bug? Message me or make a pull request! Added a new generator backend?
Make a pull request!
Special thanks for all the people who contributed and are going to contribute!
Also to these who helped me solve a problem when I simply could not think of a solution.

View file

@ -0,0 +1,98 @@
#include <iostream>
// THIS IS OPTIONAL AND NOT REQUIRED, ONLY USE THIS IF YOU DON'T WANT GLAD TO INCLUDE windows.h
// GLAD will include windows.h for APIENTRY if it was not previously defined.
// Make sure you have the correct definition for APIENTRY for platforms which define _WIN32 but don't use __stdcall
#ifdef _WIN32
#define APIENTRY __stdcall
#endif
// GLAD
#include <glad/glad.h>
#include <glad/glad_glx.h>
// confirm that GLAD didn't include windows.h
#ifdef _WINDOWS_
#error windows.h was included!
#endif
// GLFW
#include <GLFW/glfw3.h>
// This example is taken from http://learnopengl.com/
// http://learnopengl.com/code_viewer.php?code=getting-started/hellowindow2
// The code originally used GLEW, I replaced it with Glad
// Compile:
// g++ example/c++/hellowindow2.cpp -Ibuild/include build/src/glad.c -lglfw -ldl
// Function prototypes
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);
// Window dimensions
const GLuint WIDTH = 800, HEIGHT = 600;
// The MAIN function, from here we start the application and run the game loop
int main()
{
std::cout << "Starting GLFW context, OpenGL 3.3" << std::endl;
// Init GLFW
glfwInit();
// Set all the required options for GLFW
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
// Create a GLFWwindow object that we can use for GLFW's functions
GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", NULL, NULL);
glfwMakeContextCurrent(window);
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
// Set the required callback functions
glfwSetKeyCallback(window, key_callback);
if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress))
{
std::cout << "Failed to initialize OpenGL context" << std::endl;
return -1;
}
// Define the viewport dimensions
glViewport(0, 0, WIDTH, HEIGHT);
// Game loop
while (!glfwWindowShouldClose(window))
{
// Check if any events have been activated (key pressed, mouse moved etc.) and call corresponding response functions
glfwPollEvents();
// Render
// Clear the colorbuffer
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Swap the screen buffers
glfwSwapBuffers(window);
}
// Terminates GLFW, clearing any resources allocated by GLFW.
glfwTerminate();
return 0;
}
// Is called whenever a key is pressed/released via GLFW
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
std::cout << key << std::endl;
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
}

View file

@ -0,0 +1,87 @@
#include <stdio.h>
#include <stdlib.h>
#include <glad/glad.h>
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
// This file is a modified version of gl3w's test.c
// https://github.com/skaslev/gl3w/blob/master/src/test.c
// Compile:
// gcc example/c/simple.c -Ibuild/include build/src/glad.c -lglut -ldl
static int width = 600, height = 600;
static void display(void)
{
glClearColor(1.0f, 0.2f, 0.7f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glutSwapBuffers();
glutPostRedisplay();
}
static void reshape(int w, int h)
{
width = w > 1 ? w : 1;
height = h > 1 ? h : 1;
glViewport(0, 0, width, height);
glClearDepth(1.0);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glEnable(GL_DEPTH_TEST);
}
#ifdef GLAD_DEBUG
void pre_gl_call(const char *name, void *funcptr, int len_args, ...) {
printf("Calling: %s (%d arguments)\n", name, len_args);
}
#endif
int main(int argc, char **argv)
{
if(gladLoadGL()) {
// you need an OpenGL context before loading glad
printf("I did load GL with no context!\n");
exit(-1);
}
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(width, height);
glutCreateWindow("cookie");
glutReshapeFunc(reshape);
glutDisplayFunc(display);
if(!gladLoadGL()) {
printf("Something went wrong!\n");
exit(-1);
}
#ifdef GLAD_DEBUG
// before every opengl call call pre_gl_call
glad_set_pre_callback(pre_gl_call);
// don't use the callback for glClear
// (glClear could be replaced with your own function)
glad_debug_glClear = glad_glClear;
#endif
// gladLoadGLLoader(&glutGetProcAddress);
printf("OpenGL %d.%d\n", GLVersion.major, GLVersion.minor);
if (GLVersion.major < 2) {
printf("Your system doesn't support OpenGL >= 2!\n");
return -1;
}
printf("OpenGL %s, GLSL %s\n", glGetString(GL_VERSION),
glGetString(GL_SHADING_LANGUAGE_VERSION));
glutMainLoop();
return 0;
}

View file

@ -0,0 +1,3 @@
__version__ = '0.1.14a0'

View file

@ -0,0 +1,160 @@
#!/usr/bin/env python
"""
Uses the official Khronos-XML specs to generate a
GL/GLES/EGL/GLX/WGL Loader made for your needs. Glad currently supports
the languages C, D, Nim and Volt.
"""
from collections import namedtuple
import logging
import sys
from glad.opener import URLOpener
from glad.spec import SPECS
import glad.lang
Version = namedtuple('Version', ['major', 'minor'])
logger = logging.getLogger('glad')
def main():
import os.path
import argparse
from argparse import ArgumentParser
opener = URLOpener()
def get_spec(value):
if value not in SPECS:
raise argparse.ArgumentTypeError('Unknown specification')
spec_cls = SPECS[value]
if os.path.exists(value + '.xml'):
logger.info('using local specification: \'%s.xml\'', value)
return spec_cls.from_file(value + '.xml')
logger.info('getting \'%s\' specification from SVN', value)
return spec_cls.from_svn(opener=opener)
def ext_file(value):
msg = 'Invalid extensions argument'
if os.path.exists(value):
msg = 'Invalid extensions file'
try:
with open(value, 'r') as f:
return f.read().split()
except IOError:
pass
else:
return [v.strip() for v in value.split(',') if v]
raise argparse.ArgumentTypeError(msg)
def version(value):
if value is None or len(value.strip()) == 0:
return None
v = value
if '.' not in v:
v = '{}.0'.format(v)
try:
return Version(*map(int, v.split('.')))
except ValueError:
pass
raise argparse.ArgumentTypeError('Invalid version: "{}"'.format(value))
def cmdapi(value):
try:
return dict((p[0], version(p[1])) for p in
(list(map(str.strip, e.split('='))) for e in
filter(bool, map(str.strip, value.split(',')))))
except IndexError:
pass
raise argparse.ArgumentTypeError(
'Invalid api-string: "{}"'.format(value)
)
description = __doc__
parser = ArgumentParser(description=description)
parser.add_argument('--profile', dest='profile',
choices=['core', 'compatibility'],
default='compatibility',
help='OpenGL profile (defaults to compatibility)')
parser.add_argument('--out-path', dest='out', required=True,
help='Output path for loader')
parser.add_argument('--api', dest='api', type=cmdapi,
help='API type/version pairs, like "gl=3.2,gles=", '
'no version means latest')
parser.add_argument('--generator', dest='generator', default='d',
choices=['c', 'c-debug', 'd', 'nim', 'volt'], required=True,
help='Language to generate the binding for')
parser.add_argument('--extensions', dest='extensions',
default=None, type=ext_file,
help='Path to extensions file or comma separated '
'list of extensions, if missing '
'all extensions are included')
parser.add_argument('--spec', dest='spec', default='gl',
choices=['gl', 'egl', 'glx', 'wgl'],
help='Name of the spec')
parser.add_argument('--no-loader', dest='no_loader', action='store_true')
parser.add_argument('--omit-khrplatform', dest='omit_khrplatform', action='store_true',
help='Omits inclusion of the khrplatform.h '
'file which is often unnecessary. '
'Only has an effect if used together '
'with c generators.')
parser.add_argument('--local-files', dest='local_files', action='store_true',
help='Forces every file directly into the output '
'directory. No src or include subdirectories '
'are generated. '
'Only has an effect if used together '
'with c generators.')
parser.add_argument('--quiet', dest='quiet', action='store_true')
ns = parser.parse_args()
if not ns.quiet:
logging.basicConfig(
format='[%(asctime)s][%(levelname)s\t][%(name)-7s\t]: %(message)s',
datefmt='%m/%d/%Y %H:%M:%S', level=logging.DEBUG
)
spec = get_spec(ns.spec)
if spec.NAME == 'gl':
spec.profile = ns.profile
api = ns.api
if api is None or len(api.keys()) == 0:
api = {spec.NAME: None}
generator_cls, loader_cls = glad.lang.get_generator(
ns.generator, spec.NAME.lower()
)
if loader_cls is None:
return parser.error('API/Spec not yet supported')
loader = loader_cls(api, disabled=ns.no_loader, local_files=ns.local_files)
logger.info('generating \'%s\' bindings', spec.NAME)
with generator_cls(
ns.out,
spec,
api,
ns.extensions,
loader=loader,
opener=opener,
local_files=ns.local_files,
omit_khrplatform=ns.omit_khrplatform
) as generator:
generator.generate()
logger.info('generating \'%s\' bindings - done', spec.NAME)
if __name__ == '__main__':
main()

View file

@ -0,0 +1,19 @@
import glad.lang.c
import glad.lang.d
import glad.lang.nim
import glad.lang.volt
def get_generator(name, spec):
_langs = [
glad.lang.c,
glad.lang.d,
glad.lang.nim,
glad.lang.volt
]
for lang in _langs:
gen, loader = lang.get_generator(name, spec)
if gen is not None:
return gen, loader
return None, None

View file

@ -0,0 +1,28 @@
from glad.lang.c.loader.egl import EGLCLoader
from glad.lang.c.loader.gl import OpenGLCLoader
from glad.lang.c.loader.glx import GLXCLoader
from glad.lang.c.loader.wgl import WGLCLoader
from glad.lang.c.generator import CGenerator
from glad.lang.c.debug import CDebugGenerator
_specs = {
'egl': EGLCLoader,
'gl': OpenGLCLoader,
'glx': GLXCLoader,
'wgl': WGLCLoader
}
_generators = {
'c': CGenerator,
'c-debug': CDebugGenerator
}
def get_generator(name, spec):
gen = _generators.get(name)
loader = _specs.get(spec)
return gen, loader

View file

@ -0,0 +1,132 @@
from glad.lang.c.generator import CGenerator
DEFAULT_DEBUG_IMPL = '''
{return_def}
_pre_call_callback("{name}", {args_callback});
{return_assign} glad_{name}({args});
_post_call_callback("{name}", {args_callback});
{return_return}
'''
DEBUG_HEADER = '''
#define GLAD_DEBUG
typedef void (* GLADcallback)(const char *name, void *funcptr, int len_args, ...);
GLAPI void glad_set_pre_callback(GLADcallback cb);
GLAPI void glad_set_post_callback(GLADcallback cb);
'''
DEBUG_CODE = '''
static GLADcallback _pre_call_callback = _pre_call_callback_default;
void glad_set_pre_callback(GLADcallback cb) {
_pre_call_callback = cb;
}
static GLADcallback _post_call_callback = _post_call_callback_default;
void glad_set_post_callback(GLADcallback cb) {
_post_call_callback = cb;
}
'''
DEFAULT_CALLBACK = '''
void _pre_call_callback_default(const char *name, void *funcptr, int len_args, ...) {
(void) name;
(void) funcptr;
(void) len_args;
}
void _post_call_callback_default(const char *name, void *funcptr, int len_args, ...) {
(void) name;
(void) funcptr;
(void) len_args;
}
'''
DEFAULT_CALLBACK_GL = '''
void _pre_call_callback_default(const char *name, void *funcptr, int len_args, ...) {
(void) name;
(void) funcptr;
(void) len_args;
}
void _post_call_callback_default(const char *name, void *funcptr, int len_args, ...) {
GLenum error_code;
(void) funcptr;
(void) len_args;
error_code = glad_glGetError();
if (error_code != GL_NO_ERROR) {
fprintf(stderr, "ERROR %d in %s\\n", error_code, name);
}
}
'''
class CDebugGenerator(CGenerator):
NAME = 'c-debug'
NAME_LONG = 'C/C++ Debug'
def write_code_head(self, f):
CGenerator.write_code_head(self, f)
if self.spec.NAME == 'gl':
f.write(DEFAULT_CALLBACK_GL)
else:
f.write(DEFAULT_CALLBACK)
f.write(DEBUG_CODE)
def write_api_header(self, f):
CGenerator.write_api_header(self, f)
f.write(DEBUG_HEADER)
def write_function_prototype(self, fobj, func):
fobj.write('typedef {} (APIENTRYP PFN{}PROC)({});\n'.format(
func.proto.ret.to_c(), func.proto.name.upper(),
', '.join(param.type.raw for param in func.params)
))
fobj.write('GLAPI PFN{}PROC glad_{};\n'.format(
func.proto.name.upper(), func.proto.name
))
fobj.write('GLAPI PFN{}PROC glad_debug_{};\n'.format(
func.proto.name.upper(), func.proto.name
))
fobj.write('#define {0} glad_debug_{0}\n'.format(func.proto.name))
def write_function(self, fobj, func):
fobj.write('PFN{}PROC glad_{};\n'.format(
func.proto.name.upper(), func.proto.name
))
# write the default debug function
args_def = ', '.join(
'{type} arg{i}'.format(type=param.type.to_c(), i=i)
for i, param in enumerate(func.params)
)
fobj.write('{} APIENTRY glad_debug_impl_{}({}) {{'.format(
func.proto.ret.to_c(), func.proto.name, args_def
))
args = ', '.join('arg{}'.format(i) for i, _ in enumerate(func.params))
args_callback = ', '.join(filter(
None, ['(void*){}'.format(func.proto.name), str(len(func.params)), args]
))
return_def = ''
return_assign = ''
return_return = ''
# lower because of win API having VOID
if not func.proto.ret.to_c().lower() == 'void':
return_def = '\n {} ret;'.format(func.proto.ret.to_c())
return_assign = 'ret = '
return_return = 'return ret;'
fobj.write('\n'.join(filter(None, DEFAULT_DEBUG_IMPL.format(
name=func.proto.name, args=args, args_callback=args_callback,
return_def=return_def, return_assign=return_assign,
return_return=return_return
).splitlines())))
fobj.write('\n}\n')
fobj.write('PFN{0}PROC glad_debug_{1} = glad_debug_impl_{1};\n'.format(
func.proto.name.upper(), func.proto.name
))

View file

@ -0,0 +1,299 @@
import os
import sys
from glad.lang.common.generator import Generator
from glad.lang.common.util import makefiledir
KHRPLATFORM = 'https://www.khronos.org/registry/egl/api/KHR/khrplatform.h'
class CGenerator(Generator):
NAME = 'c'
NAME_LONG = 'C/C++'
def open(self):
suffix = ''
if not self.spec.NAME == 'gl':
suffix = '_{}'.format(self.spec.NAME)
if self.local_files:
self.h_include = '"glad{}.h"'.format(suffix)
self._f_c = open(make_path(self.path,
'glad{}.c'.format(suffix)), 'w')
self._f_h = open(make_path(self.path,
'glad{}.h'.format(suffix)), 'w')
khr = self.path
else:
self.h_include = '<glad/glad{}.h>'.format(suffix)
self._f_c = open(make_path(self.path, 'src',
'glad{}.c'.format(suffix)), 'w')
self._f_h = open(make_path(self.path, 'include', 'glad',
'glad{}.h'.format(suffix)), 'w')
khr = os.path.join(self.path, 'include', 'KHR')
if not self.omit_khrplatform:
khr_url = KHRPLATFORM
if os.path.exists('khrplatform.h'):
khr_url = 'file://' + os.path.abspath('khrplatform.h')
khrplatform = os.path.join(khr, 'khrplatform.h')
if not os.path.exists(khrplatform):
if not os.path.exists(khr):
os.makedirs(khr)
self.opener.urlretrieve(khr_url, khrplatform)
return self
def close(self):
self._f_c.close()
self._f_h.close()
def generate_header(self):
self._f_h.write('/*\n')
self._f_h.write(self.header)
self._f_h.write('*/\n\n')
self._f_c.write('/*\n')
self._f_c.write(self.header)
self._f_c.write('*/\n\n')
def generate_loader(self, features, extensions):
f = self._f_c
if self.spec.NAME in ('egl', 'wgl'):
features = {'egl': [], 'wgl': []}
written = set()
for api, version in self.api.items():
for feature in features[api]:
f.write('static void load_{}(GLADloadproc load) {{\n'
.format(feature.name))
if self.spec.NAME in ('gl', 'glx', 'wgl'):
f.write('\tif(!GLAD_{}) return;\n'.format(feature.name))
for func in feature.functions:
f.write('\tglad_{0} = (PFN{1}PROC)load("{0}");\n'
.format(func.proto.name, func.proto.name.upper()))
f.write('}\n')
for ext in extensions[api]:
if len(list(ext.functions)) == 0 or ext.name in written:
continue
f.write('static void load_{}(GLADloadproc load) {{\n'
.format(ext.name))
if self.spec.NAME in ('gl', 'glx', 'wgl'):
f.write('\tif(!GLAD_{}) return;\n'.format(ext.name))
if ext.name == 'GLX_SGIX_video_source': f.write('#ifdef _VL_H_\n')
if ext.name == 'GLX_SGIX_dmbuffer': f.write('#ifdef _DM_BUFFER_H_\n')
for func in ext.functions:
# even if they were in written we need to load it
f.write('\tglad_{0} = (PFN{1}PROC)load("{0}");\n'
.format(func.proto.name, func.proto.name.upper()))
if ext.name in ('GLX_SGIX_video_source', 'GLX_SGIX_dmbuffer'):
f.write('#else\n')
f.write('\t(void)load;\n')
f.write('#endif\n')
f.write('}\n')
written.add(ext.name)
f.write('static int find_extensions{}(void) {{\n'.format(api.upper()))
if self.spec.NAME in ('gl', 'glx', 'wgl'):
f.write('\tif (!get_exts()) return 0;\n')
for ext in extensions[api]:
f.write('\tGLAD_{0} = has_ext("{0}");\n'.format(ext.name))
if len(extensions[api]) == 0:
f.write('\t(void)&has_ext;\n') # suppress unused has_ext warnings
f.write('\tfree_exts();\n')
f.write('\treturn 1;\n')
f.write('}\n\n')
if api == 'glx':
f.write('static void find_core{}(Display *dpy, int screen) {{\n'.format(api.upper()))
elif api == 'wgl':
f.write('static void find_core{}(HDC hdc) {{\n'.format(api.upper()))
else:
f.write('static void find_core{}(void) {{\n'.format(api.upper()))
self.loader.write_find_core(f)
if self.spec.NAME in ('gl', 'glx', 'wgl'):
for feature in features[api]:
f.write('\tGLAD_{} = (major == {num[0]} && minor >= {num[1]}) ||'
' major > {num[0]};\n'.format(feature.name, num=feature.number))
if self.spec.NAME == 'gl':
f.write('\tif (GLVersion.major > {0} || (GLVersion.major >= {0} && GLVersion.minor >= {1})) {{\n'.format(version[0], version[1]))
f.write('\t\tmax_loaded_major = {0};\n'.format(version[0]))
f.write('\t\tmax_loaded_minor = {0};\n'.format(version[1]))
f.write('\t}\n')
f.write('}\n\n')
if api == 'glx':
f.write('int gladLoad{}Loader(GLADloadproc load, Display *dpy, int screen) {{\n'.format(api.upper()))
elif api == 'wgl':
f.write('int gladLoad{}Loader(GLADloadproc load, HDC hdc) {{\n'.format(api.upper()))
else:
f.write('int gladLoad{}Loader(GLADloadproc load) {{\n'.format(api.upper()))
self.loader.write_begin_load(f)
if api == 'glx':
f.write('\tfind_core{}(dpy, screen);\n'.format(api.upper()))
elif api == 'wgl':
f.write('\tfind_core{}(hdc);\n'.format(api.upper()))
else:
f.write('\tfind_core{}();\n'.format(api.upper()))
for feature in features[api]:
f.write('\tload_{}(load);\n'.format(feature.name))
f.write('\n\tif (!find_extensions{}()) return 0;\n'.format(api.upper()))
for ext in extensions[api]:
if len(list(ext.functions)) == 0:
continue
f.write('\tload_{}(load);\n'.format(ext.name))
self.loader.write_end_load(f)
f.write('}\n\n')
self.loader.write_header_end(self._f_h)
def generate_types(self, types):
f = self._f_h
self.loader.write_header(f)
self.write_api_header(f)
for type in types:
output_string = (type.raw + '\n').lstrip().replace(' ', ' ')
if output_string == '#include <KHR/khrplatform.h>\n':
if self.omit_khrplatform:
continue
elif self.local_files:
output_string = '#include "khrplatform.h"\n'
if not self.spec.NAME in ('egl',) and 'khronos' in type.raw:
continue
if type.name in ('GLsizeiptr', 'GLintptr', 'GLsizeiptrARB', 'GLintptrARB'):
# 10.6 is the last version supporting more than 64 bit (>1060)
output_string = \
'#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) ' +\
'&& (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060)\n' +\
output_string.replace('ptrdiff_t', 'long') + '#else\n' + output_string + '#endif\n'
f.write(output_string)
def generate_features(self, features):
f = self._f_h
write = set()
if self.spec.NAME in ('wgl',):
# These are already defined in windows.h
pass
elif self.spec.NAME in ('egl',):
self.write_enums(f, set(), features)
for feature in features:
for func in feature.functions:
self.write_function_def(f, func)
else:
self.write_functions(f, write, set(), features)
f = self._f_c
self.write_code_head(f)
self.loader.write(f)
self.loader.write_has_ext(f)
if self.spec.NAME in ('gl', 'glx', 'wgl'):
for feature in features:
f.write('int GLAD_{};\n'.format(feature.name))
for func in write:
self.write_function(f, func)
def generate_extensions(self, extensions, enums, functions):
write = set()
written = set(enum.name for enum in enums) | \
set(function.proto.name for function in functions)
f = self._f_h
self.write_functions(f, write, written, extensions)
f = self._f_c
if self.spec.NAME in ('gl', 'glx', 'wgl'):
for ext in set(ext.name for ext in extensions):
f.write('int GLAD_{};\n'.format(ext))
written = set()
for ext in extensions:
if ext.name == 'GLX_SGIX_video_source': f.write('#ifdef _VL_H_\n')
if ext.name == 'GLX_SGIX_dmbuffer': f.write('#ifdef _DM_BUFFER_H_\n')
for func in ext.functions:
if func in write and func not in written:
self.write_function(f, func)
written.add(func)
if ext.name in ('GLX_SGIX_video_source', 'GLX_SGIX_dmbuffer'): f.write('#endif\n')
def write_functions(self, f, write, written, extensions):
self.write_enums(f, written, extensions)
for ext in extensions:
f.write('#ifndef {0}\n#define {0} 1\n'.format(ext.name))
if self.spec.NAME in ('gl', 'glx', 'wgl'):
f.write('GLAPI int GLAD_{};\n'.format(ext.name))
if ext.name == 'GLX_SGIX_video_source': f.write('#ifdef _VL_H_\n')
if ext.name == 'GLX_SGIX_dmbuffer': f.write('#ifdef _DM_BUFFER_H_\n')
for func in ext.functions:
if not func.proto.name in written:
self.write_function_prototype(f, func)
write.add(func)
written.add(func.proto.name)
if ext.name in ('GLX_SGIX_video_source', 'GLX_SGIX_dmbuffer'): f.write('#endif\n')
f.write('#endif\n')
def write_enums(self, f, written, extensions):
for ext in extensions:
for enum in ext.enums:
if not enum.name in written:
f.write('#define {} {}\n'.format(enum.name, enum.value))
written.add(enum.name)
def write_api_header(self, f):
for api in self.api:
if api == 'glx':
f.write('GLAPI int gladLoad{}Loader(GLADloadproc, Display *dpy, int screen);\n\n'.format(api.upper()))
elif api == 'wgl':
f.write('GLAPI int gladLoad{}Loader(GLADloadproc, HDC hdc);\n\n'.format(api.upper()))
else:
f.write('GLAPI int gladLoad{}Loader(GLADloadproc);\n\n'.format(api.upper()))
def write_code_head(self, f):
f.write('#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include {}\n'.format(self.h_include))
def write_extern(self, fobj):
fobj.write('#ifdef __cplusplus\nextern "C" {\n#endif\n')
def write_extern_end(self, fobj):
fobj.write('#ifdef __cplusplus\n}\n#endif\n')
def write_function_def(self, fobj, func):
# write a function definition instead of a prototype.
# e.g. egl uses that, since the main functions get linked in and not loaded through a function.
fobj.write('{}('.format(func.proto.ret.raw))
fobj.write(', '.join(param.type.raw for param in func.params))
fobj.write(');\n')
def write_function_prototype(self, fobj, func):
fobj.write('typedef {} (APIENTRYP PFN{}PROC)({});\n'.format(
func.proto.ret.to_c(), func.proto.name.upper(),
', '.join(param.type.raw for param in func.params))
)
fobj.write('GLAPI PFN{}PROC glad_{};\n'.format(func.proto.name.upper(),
func.proto.name))
fobj.write('#define {0} glad_{0}\n'.format(func.proto.name))
def write_function(self, fobj, func):
fobj.write('PFN{}PROC glad_{};\n'.format(func.proto.name.upper(),
func.proto.name))
def make_path(path, *args):
path = os.path.join(path, *args)
makefiledir(path)
return path

View file

@ -0,0 +1,132 @@
LOAD_OPENGL_DLL = '''
%(pre)s void* %(proc)s(const char *namez);
#ifdef _WIN32
#include <windows.h>
static HMODULE libGL;
typedef void* (APIENTRYP PFNWGLGETPROCADDRESSPROC_PRIVATE)(const char*);
static PFNWGLGETPROCADDRESSPROC_PRIVATE gladGetProcAddressPtr;
%(pre)s
int %(init)s(void) {
libGL = LoadLibraryW(L"opengl32.dll");
if(libGL != NULL) {
gladGetProcAddressPtr = (PFNWGLGETPROCADDRESSPROC_PRIVATE)GetProcAddress(
libGL, "wglGetProcAddress");
return gladGetProcAddressPtr != NULL;
}
return 0;
}
%(pre)s
void %(terminate)s(void) {
if(libGL != NULL) {
FreeLibrary(libGL);
libGL = NULL;
}
}
#else
#include <dlfcn.h>
static void* libGL;
#ifndef __APPLE__
typedef void* (APIENTRYP PFNGLXGETPROCADDRESSPROC_PRIVATE)(const char*);
static PFNGLXGETPROCADDRESSPROC_PRIVATE gladGetProcAddressPtr;
#endif
%(pre)s
int %(init)s(void) {
#ifdef __APPLE__
static const char *NAMES[] = {
"../Frameworks/OpenGL.framework/OpenGL",
"/Library/Frameworks/OpenGL.framework/OpenGL",
"/System/Library/Frameworks/OpenGL.framework/OpenGL",
"/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL"
};
#else
static const char *NAMES[] = {"libGL.so.1", "libGL.so"};
#endif
unsigned int index = 0;
for(index = 0; index < (sizeof(NAMES) / sizeof(NAMES[0])); index++) {
libGL = dlopen(NAMES[index], RTLD_NOW | RTLD_GLOBAL);
if(libGL != NULL) {
#ifdef __APPLE__
return 1;
#else
gladGetProcAddressPtr = (PFNGLXGETPROCADDRESSPROC_PRIVATE)dlsym(libGL,
"glXGetProcAddressARB");
return gladGetProcAddressPtr != NULL;
#endif
}
}
return 0;
}
%(pre)s
void %(terminate)s() {
if(libGL != NULL) {
dlclose(libGL);
libGL = NULL;
}
}
#endif
%(pre)s
void* %(proc)s(const char *namez) {
void* result = NULL;
if(libGL == NULL) return NULL;
#ifndef __APPLE__
if(gladGetProcAddressPtr != NULL) {
result = gladGetProcAddressPtr(namez);
}
#endif
if(result == NULL) {
#ifdef _WIN32
result = (void*)GetProcAddress(libGL, namez);
#else
result = dlsym(libGL, namez);
#endif
}
return result;
}
'''
LOAD_OPENGL_DLL_H = '''
'''
LOAD_OPENGL_GLAPI_H = '''
#ifndef GLAPI
# if defined(GLAD_GLAPI_EXPORT)
# if defined(_WIN32) || defined(__CYGWIN__)
# if defined(GLAD_GLAPI_EXPORT_BUILD)
# if defined(__GNUC__)
# define GLAPI __attribute__ ((dllexport)) extern
# else
# define GLAPI __declspec(dllexport) extern
# endif
# else
# if defined(__GNUC__)
# define GLAPI __attribute__ ((dllimport)) extern
# else
# define GLAPI __declspec(dllimport) extern
# endif
# endif
# elif defined(__GNUC__) && defined(GLAD_GLAPI_EXPORT_BUILD)
# define GLAPI __attribute__ ((visibility ("default"))) extern
# else
# define GLAPI extern
# endif
# else
# define GLAPI extern
# endif
#endif
'''

View file

@ -0,0 +1,85 @@
from glad.lang.common.loader import BaseLoader
_EGL_LOADER = '''
int gladLoadEGL(void) {
return gladLoadEGLLoader((GLADloadproc)eglGetProcAddress);
}
'''
_EGL_HEADER = '''
#ifndef __glad_egl_h_
#ifdef __egl_h_
#error EGL header already included, remove this include, glad already provides it
#endif
#define __glad_egl_h_
#define __egl_h_
#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
#include <windows.h>
#endif
#ifndef APIENTRY
#define APIENTRY
#endif
#ifndef APIENTRYP
#define APIENTRYP APIENTRY *
#endif
#ifndef GLAPI
#define GLAPI extern
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef void* (* GLADloadproc)(const char *name);
'''
_EGL_HEADER_LOADER = '''
GLAPI int gladLoadEGL(void);
'''
_EGL_HEADER_END = '''
#ifdef __cplusplus
}
#endif
#endif
'''
_EGL_HAS_EXT = '''
'''
class EGLCLoader(BaseLoader):
def write(self, fobj):
if not self.disabled:
fobj.write(_EGL_LOADER)
def write_begin_load(self, fobj):
# suppress unused warnings
fobj.write('\t(void) load;\n')
def write_end_load(self, fobj):
fobj.write('\treturn 1;\n')
def write_find_core(self, fobj):
pass
def write_has_ext(self, fobj):
fobj.write(_EGL_HAS_EXT)
def write_header(self, fobj):
fobj.write(_EGL_HEADER)
if not self.disabled:
fobj.write(_EGL_HEADER_LOADER)
def write_header_end(self, fobj):
fobj.write(_EGL_HEADER_END)

View file

@ -0,0 +1,242 @@
from glad.lang.common.loader import BaseLoader
from glad.lang.c.loader import LOAD_OPENGL_DLL, LOAD_OPENGL_DLL_H, LOAD_OPENGL_GLAPI_H
_OPENGL_LOADER = \
LOAD_OPENGL_DLL % {'pre':'static', 'init':'open_gl',
'proc':'get_proc', 'terminate':'close_gl'} + '''
int gladLoadGL(void) {
int status = 0;
if(open_gl()) {
status = gladLoadGLLoader(&get_proc);
close_gl();
}
return status;
}
'''
_OPENGL_HAS_EXT = '''
struct gladGLversionStruct GLVersion;
#if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0)
#define _GLAD_IS_SOME_NEW_VERSION 1
#endif
static int max_loaded_major;
static int max_loaded_minor;
static const char *exts = NULL;
static int num_exts_i = 0;
static const char **exts_i = NULL;
static int get_exts(void) {
#ifdef _GLAD_IS_SOME_NEW_VERSION
if(max_loaded_major < 3) {
#endif
exts = (const char *)glGetString(GL_EXTENSIONS);
#ifdef _GLAD_IS_SOME_NEW_VERSION
} else {
unsigned int index;
num_exts_i = 0;
glGetIntegerv(GL_NUM_EXTENSIONS, &num_exts_i);
if (num_exts_i > 0) {
exts_i = (const char **)realloc((void *)exts_i, (size_t)num_exts_i * (sizeof *exts_i));
}
if (exts_i == NULL) {
return 0;
}
for(index = 0; index < (unsigned)num_exts_i; index++) {
exts_i[index] = (const char*)glGetStringi(GL_EXTENSIONS, index);
}
}
#endif
return 1;
}
static void free_exts(void) {
if (exts_i != NULL) {
free(exts_i);
exts_i = NULL;
}
}
static int has_ext(const char *ext) {
#ifdef _GLAD_IS_SOME_NEW_VERSION
if(max_loaded_major < 3) {
#endif
const char *extensions;
const char *loc;
const char *terminator;
extensions = exts;
if(extensions == NULL || ext == NULL) {
return 0;
}
while(1) {
loc = strstr(extensions, ext);
if(loc == NULL) {
return 0;
}
terminator = loc + strlen(ext);
if((loc == extensions || *(loc - 1) == ' ') &&
(*terminator == ' ' || *terminator == '\\0')) {
return 1;
}
extensions = terminator;
}
#ifdef _GLAD_IS_SOME_NEW_VERSION
} else {
int index;
for(index = 0; index < num_exts_i; index++) {
const char *e = exts_i[index];
if(strcmp(e, ext) == 0) {
return 1;
}
}
}
#endif
return 0;
}
'''
_OPENGL_HEADER_START = '''
#ifndef __glad_h_
#define __glad_h_
'''
_OPENGL_HEADER_INCLUDE_ERROR = '''
#ifdef __{0}_h_
#error {1} header already included, remove this include, glad already provides it
#endif
#define __{0}_h_
'''
_OPENGL_HEADER = '''
#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
#include <windows.h>
#endif
#ifndef APIENTRY
#define APIENTRY
#endif
#ifndef APIENTRYP
#define APIENTRYP APIENTRY *
#endif
#ifdef __cplusplus
extern "C" {
#endif
struct gladGLversionStruct {
int major;
int minor;
};
typedef void* (* GLADloadproc)(const char *name);
''' + LOAD_OPENGL_GLAPI_H + '''
GLAPI struct gladGLversionStruct GLVersion;
'''
_OPENGL_HEADER_LOADER = '''
GLAPI int gladLoadGL(void);
''' + LOAD_OPENGL_DLL_H
_OPENGL_HEADER_END = '''
#ifdef __cplusplus
}
#endif
#endif
'''
_FIND_VERSION = '''
/* Thank you @elmindreda
* https://github.com/elmindreda/greg/blob/master/templates/greg.c.in#L176
* https://github.com/glfw/glfw/blob/master/src/context.c#L36
*/
int i, major, minor;
const char* version;
const char* prefixes[] = {
"OpenGL ES-CM ",
"OpenGL ES-CL ",
"OpenGL ES ",
NULL
};
version = (const char*) glGetString(GL_VERSION);
if (!version) return;
for (i = 0; prefixes[i]; i++) {
const size_t length = strlen(prefixes[i]);
if (strncmp(version, prefixes[i], length) == 0) {
version += length;
break;
}
}
/* PR #18 */
#ifdef _MSC_VER
sscanf_s(version, "%d.%d", &major, &minor);
#else
sscanf(version, "%d.%d", &major, &minor);
#endif
GLVersion.major = major; GLVersion.minor = minor;
max_loaded_major = major; max_loaded_minor = minor;
'''
class OpenGLCLoader(BaseLoader):
def write(self, fobj):
if not self.disabled and 'gl' in self.apis:
fobj.write(_OPENGL_LOADER)
def write_begin_load(self, fobj):
fobj.write('\tGLVersion.major = 0; GLVersion.minor = 0;\n')
fobj.write('\tglGetString = (PFNGLGETSTRINGPROC)load("glGetString");\n')
fobj.write('\tif(glGetString == NULL) return 0;\n')
fobj.write('\tif(glGetString(GL_VERSION) == NULL) return 0;\n')
def write_end_load(self, fobj):
fobj.write('\treturn GLVersion.major != 0 || GLVersion.minor != 0;\n')
def write_find_core(self, fobj):
fobj.write(_FIND_VERSION)
def write_find_core_end(self, fobj):
fobj.write(_FIND_VERSION)
def write_has_ext(self, fobj):
fobj.write(_OPENGL_HAS_EXT)
def write_header(self, fobj):
fobj.write(_OPENGL_HEADER_START)
written = set()
for api, hname, name in [
('gl', 'gl', 'OpenGL'), ('gles1', 'gl', 'OpenGL ES 1'),
('gles2', 'gl2', 'OpenGL ES 2'), ('gles2', 'gl3', 'OpenGL ES 3')
]:
if api in self.apis and hname not in written:
fobj.write(_OPENGL_HEADER_INCLUDE_ERROR.format(hname, name))
written.add(hname)
fobj.write(_OPENGL_HEADER)
if not self.disabled and 'gl' in self.apis:
fobj.write(_OPENGL_HEADER_LOADER)
def write_header_end(self, fobj):
fobj.write(_OPENGL_HEADER_END)

View file

@ -0,0 +1,148 @@
from glad.lang.common.loader import BaseLoader
from glad.lang.c.loader import LOAD_OPENGL_DLL, LOAD_OPENGL_DLL_H, LOAD_OPENGL_GLAPI_H
_GLX_LOADER = \
LOAD_OPENGL_DLL % {'pre':'static', 'init':'open_gl',
'proc':'get_proc', 'terminate':'close_gl'} + '''
int gladLoadGLX(Display *dpy, int screen) {
int status = 0;
if(open_gl()) {
status = gladLoadGLXLoader((GLADloadproc)get_proc, dpy, screen);
close_gl();
}
return status;
}
'''
_GLX_HEADER_START = '''
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
'''
#include <glad/glad.h>
_WGL_HEADER_MID = '''
#ifndef __glad_glxext_h_
#ifdef __glxext_h_
#error GLX header already included, remove this include, glad already provides it
#endif
#define __glad_glxext_h_
#define __glxext_h_
#ifndef APIENTRY
#define APIENTRY
#endif
#ifndef APIENTRYP
#define APIENTRYP APIENTRY *
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef void* (* GLADloadproc)(const char *name);
''' + LOAD_OPENGL_GLAPI_H
_GLX_HEADER_LOADER = '''
GLAPI int gladLoadGLX(Display *dpy, int screen);
''' + LOAD_OPENGL_DLL_H
_GLX_HEADER_END = '''
#ifdef __cplusplus
}
#endif
#endif
'''
_GLX_HAS_EXT = '''
static Display *GLADGLXDisplay = 0;
static int GLADGLXscreen = 0;
static int get_exts(void) {
return 1;
}
static void free_exts(void) {
return;
}
static int has_ext(const char *ext) {
const char *terminator;
const char *loc;
const char *extensions;
if(!GLAD_GLX_VERSION_1_1)
return 0;
extensions = glXQueryExtensionsString(GLADGLXDisplay, GLADGLXscreen);
if(extensions == NULL || ext == NULL)
return 0;
while(1) {
loc = strstr(extensions, ext);
if(loc == NULL)
break;
terminator = loc + strlen(ext);
if((loc == extensions || *(loc - 1) == ' ') &&
(*terminator == ' ' || *terminator == '\\0'))
{
return 1;
}
extensions = terminator;
}
return 0;
}
'''
class GLXCLoader(BaseLoader):
def write(self, fobj):
if not self.disabled:
fobj.write(_GLX_LOADER)
def write_begin_load(self, fobj):
fobj.write('\tglXQueryVersion = (PFNGLXQUERYVERSIONPROC)load("glXQueryVersion");\n')
fobj.write('\tif(glXQueryVersion == NULL) return 0;\n')
def write_end_load(self, fobj):
fobj.write('\treturn 1;\n')
def write_find_core(self, fobj):
fobj.write('\tint major = 0, minor = 0;\n')
fobj.write('\tif(dpy == 0 && GLADGLXDisplay == 0) {\n')
fobj.write('\t\tdpy = XOpenDisplay(0);\n')
fobj.write('\t\tscreen = XScreenNumberOfScreen(XDefaultScreenOfDisplay(dpy));\n')
fobj.write('\t} else if(dpy == 0) {\n')
fobj.write('\t\tdpy = GLADGLXDisplay;\n')
fobj.write('\t\tscreen = GLADGLXscreen;\n')
fobj.write('\t}\n')
fobj.write('\tglXQueryVersion(dpy, &major, &minor);\n')
fobj.write('\tGLADGLXDisplay = dpy;\n')
fobj.write('\tGLADGLXscreen = screen;\n')
def write_has_ext(self, fobj):
fobj.write(_GLX_HAS_EXT)
def write_header(self, fobj):
fobj.write(_GLX_HEADER_START)
if self.local_files:
fobj.write('#include "glad.h"\n')
else:
fobj.write('#include <glad/glad.h>\n')
fobj.write(_WGL_HEADER_MID)
if not self.disabled:
fobj.write(_GLX_HEADER_LOADER)
def write_header_end(self, fobj):
fobj.write(_GLX_HEADER_END)

View file

@ -0,0 +1,142 @@
from glad.lang.common.loader import BaseLoader
from glad.lang.c.loader import LOAD_OPENGL_DLL, LOAD_OPENGL_DLL_H, LOAD_OPENGL_GLAPI_H
_WGL_LOADER = \
LOAD_OPENGL_DLL % {'pre':'static', 'init':'open_gl',
'proc':'get_proc', 'terminate':'close_gl'} + '''
int gladLoadWGL(HDC hdc) {
int status = 0;
if(open_gl()) {
status = gladLoadWGLLoader((GLADloadproc)get_proc, hdc);
close_gl();
}
return status;
}
'''
_WGL_HEADER_START = '''
#ifndef WINAPI
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN 1
# endif
# include <windows.h>
#endif
'''
#include <glad/glad.h>
_WGL_HEADER_MID = '''
#ifndef __glad_wglext_h_
#ifdef __wglext_h_
#error WGL header already included, remove this include, glad already provides it
#endif
#define __glad_wglext_h_
#define __wglext_h_
#ifndef APIENTRY
#define APIENTRY
#endif
#ifndef APIENTRYP
#define APIENTRYP APIENTRY *
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef void* (* GLADloadproc)(const char *name);
''' + LOAD_OPENGL_GLAPI_H
_WGL_HEADER_LOADER = '''
GLAPI int gladLoadWGL(HDC hdc);
''' + LOAD_OPENGL_DLL_H
_WGL_HEADER_END = '''
#ifdef __cplusplus
}
#endif
#endif
'''
_WGL_HAS_EXT = '''
static HDC GLADWGLhdc = (HDC)INVALID_HANDLE_VALUE;
static int get_exts(void) {
return 1;
}
static void free_exts(void) {
return;
}
static int has_ext(const char *ext) {
const char *terminator;
const char *loc;
const char *extensions;
if(wglGetExtensionsStringEXT == NULL && wglGetExtensionsStringARB == NULL)
return 0;
if(wglGetExtensionsStringARB == NULL || GLADWGLhdc == INVALID_HANDLE_VALUE)
extensions = wglGetExtensionsStringEXT();
else
extensions = wglGetExtensionsStringARB(GLADWGLhdc);
if(extensions == NULL || ext == NULL)
return 0;
while(1) {
loc = strstr(extensions, ext);
if(loc == NULL)
break;
terminator = loc + strlen(ext);
if((loc == extensions || *(loc - 1) == ' ') &&
(*terminator == ' ' || *terminator == '\\0'))
{
return 1;
}
extensions = terminator;
}
return 0;
}
'''
class WGLCLoader(BaseLoader):
def write(self, fobj):
if not self.disabled:
fobj.write(_WGL_LOADER)
def write_begin_load(self, fobj):
fobj.write('\twglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)load("wglGetExtensionsStringARB");\n')
fobj.write('\twglGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)load("wglGetExtensionsStringEXT");\n')
fobj.write('\tif(wglGetExtensionsStringARB == NULL && wglGetExtensionsStringEXT == NULL) return 0;\n')
def write_end_load(self, fobj):
fobj.write('\treturn 1;\n')
def write_find_core(self, fobj):
fobj.write('\tGLADWGLhdc = hdc;\n')
def write_has_ext(self, fobj):
fobj.write(_WGL_HAS_EXT)
def write_header(self, fobj):
fobj.write(_WGL_HEADER_START)
if self.local_files:
fobj.write('#include "glad.h"\n')
else:
fobj.write('#include <glad/glad.h>\n')
fobj.write(_WGL_HEADER_MID)
if not self.disabled:
fobj.write(_WGL_HEADER_LOADER)
def write_header_end(self, fobj):
fobj.write(_WGL_HEADER_END)

View file

@ -0,0 +1,242 @@
from collections import defaultdict
from datetime import datetime
from itertools import chain
import os.path
import sys
from glad.lang.common.loader import NullLoader
from glad.opener import URLOpener
from glad.util import api_name
import glad
if sys.version_info >= (3, 0):
from urllib.parse import urlencode
else:
from urllib import urlencode
HEADER_TEMPLATE = '''
{apis_named} loader generated by glad {version} on {date}.
Language/Generator: {language}
Specification: {specification}
APIs: {apis}
Profile: {profile}
Extensions:
{extensions}
Loader: {loader}
Local files: {local_files}
Omit khrplatform: {omit_khrplatform}
Commandline:
{commandline}
Online:
{online}
'''
class Generator(object):
NAME = None
NAME_LONG = None
URL = 'http://glad.dav1d.de'
def __init__(self, path, spec, api, extension_names=None, loader=None,
opener=None, local_files=False, omit_khrplatform=False,
header_template=HEADER_TEMPLATE):
self.path = os.path.abspath(path)
self.spec = spec
for a in api:
if a not in self.spec.features:
raise ValueError(
'Unknown API "{0}" for specification "{1}"'
.format(a, self.spec.NAME)
)
self.api = api
self.extension_names = extension_names
self.has_loader = not loader.disabled
self.loader = loader
if self.loader is None:
self.loader = NullLoader
self.opener = opener
if self.opener is None:
self.opener = URLOpener.default()
self.local_files = local_files
self.omit_khrplatform = omit_khrplatform
self._header_template = header_template
def open(self):
raise NotImplementedError
def close(self):
raise NotImplementedError
def __enter__(self):
self.open()
return self
def __exit__(self, exc_type, exc_value, traceback):
self.close()
def generate(self):
features = list()
for api, version in self.api.items():
features.extend(self.spec.features[api])
if version is None:
version = list(self.spec.features[api].keys())[-1]
self.api[api] = version
if version not in self.spec.features[api]:
raise ValueError(
'Unknown version "{0}" for specification "{1}"'
.format(version, self.spec.NAME)
)
if self.extension_names is None:
self.extension_names = list(chain.from_iterable(self.spec.extensions[a]
for a in self.api))
# sort and eliminate duplicates
self.extension_names = list(sorted(set(self.extension_names)))
e = list(chain.from_iterable(self.spec.extensions[a] for a in self.api))
for ext in self.extension_names:
if ext not in e:
raise ValueError(
'Invalid extension "{0}" for specification "{1}"'
.format(ext, self.spec.NAME)
)
self.generate_header()
types = [t for t in self.spec.types if t.api is None or t.api in self.api]
self.generate_types(types)
f = list()
for api, version in self.api.items():
f.extend([value for key, value in self.spec.features[api].items()
if key <= version])
enums, functions = merge(f)
self.generate_features(f)
extensions = list()
for api in self.api:
extensions.extend(self.spec.extensions[api][ext]
for ext in self.extension_names if ext
in self.spec.extensions[api])
self.generate_extensions(extensions, enums, functions)
fs = defaultdict(list)
es = defaultdict(list)
for api, version in self.api.items():
fs[api].extend(
[value for key, value in
self.spec.features[api].items() if key <= version]
)
es[api].extend(self.spec.extensions[api][ext]
for ext in self.extension_names if ext
in self.spec.extensions[api])
self.generate_loader(fs, es)
@property
def header(self):
apis_named = ', '.join(sorted(set(api_name(api) for api in self.api)))
date = datetime.now().strftime('%c')
language = self.NAME_LONG
specification = self.spec.NAME
apis = ', '.join('{}={}'.format(api, '.'.join(map(str, version))) for api, version in self.api.items())
profile = getattr(self.spec, 'profile', '-')
extensions = ',\n '.join(self.extension_names)
online = self.online
if len(online) > 2000:
online = 'Too many extensions'
return self._header_template.format(
apis_named=apis_named,
version=glad.__version__,
date=date,
language=language,
specification=specification,
apis=apis,
profile=profile,
extensions=extensions,
loader=self.has_loader,
local_files=self.local_files,
omit_khrplatform=self.omit_khrplatform,
commandline=self.commandline,
online=online
)
@property
def commandline(self):
profile = getattr(self.spec, 'profile', None)
if profile is not None:
profile = '--profile="{}"'.format(profile)
api = '--api="{}"'.format(','.join(
'{}={}'.format(api, '.'.join(map(str, version))) for api, version in self.api.items())
)
generator = '--generator="{}"'.format(self.NAME)
specification = '--spec="{}"'.format(self.spec.NAME)
loader = '' if self.has_loader else '--no-loader'
extensions = '--extensions="{}"'.format(','.join(self.extension_names))
local_files = '--local-files' if self.local_files else ''
omit_khrplatform = '--omit-khrplatform' if self.omit_khrplatform else ''
return ' '.join(filter(None, [
profile, api, generator, specification,
loader, local_files, omit_khrplatform, extensions
]))
@property
def online(self):
profile = getattr(self.spec, 'profile', None)
if profile is not None:
profile = ('profile', profile)
api = [('api', s) for s in ('{}={}'.format(api, '.'.join(map(str, version))) for api, version in self.api.items())]
generator = ('language', self.NAME)
specification = ('specification', self.spec.NAME)
loader = ('loader', 'on') if self.has_loader else None
extensions = [('extensions', ext) for ext in self.extension_names]
data = [profile, generator, specification, loader]
data.extend(api)
data.extend(extensions)
data = list(filter(None, data))
serialized = urlencode(data)
# TODO: --local-files, --omit-khrplatform
return '{}/#{}'.format(self.URL, serialized)
def generate_header(self):
raise NotImplementedError
def generate_loader(self, features, extensions):
raise NotImplementedError
def generate_types(self, types):
raise NotImplementedError
def generate_features(self, features):
raise NotImplementedError
def generate_extensions(self, extensions, enums, functions):
raise NotImplementedError
def merge(features):
enums = set()
functions = set()
for feature in features:
enums |= set(feature.enums)
functions |= set(feature.functions)
return enums, functions

View file

@ -0,0 +1,60 @@
class BaseLoader(object):
def __init__(self, apis, disabled=False, local_files=False):
self.apis = apis
self.disabled = disabled
self.local_files = local_files
def write(self, fobj):
raise NotImplementedError
def write_begin_load(self, fobj):
raise NotImplementedError
def write_end_load(self, fobj):
raise NotImplementedError
def write_find_core(self, fobj):
raise NotImplementedError
def write_has_ext(self, fobj):
raise NotImplementedError
def write_header(self, fobj):
raise NotImplementedError
def write_header_end(self, fobj):
raise NotImplementedError
class NullLoader(BaseLoader):
def write_begin_load(self, fobj):
pass
def write_end_load(self, fobj):
pass
def write_header_end(self, fobj):
pass
def write_has_ext(self, fobj):
pass
def write(self, fobj):
pass
def write_header(self, fobj):
pass
def write_find_core(self, fobj):
pass
def __getattr__(self, name):
try:
return self.__getattribute__(name)
except AttributeError:
pass
def dummy(*args, **kwargs):
pass
return dummy

View file

@ -0,0 +1,13 @@
import os.path
import os
def enforce(exp, message, exc):
if not exp:
raise exc(message)
def makefiledir(path):
dir = os.path.split(path)[0]
if not os.path.exists(dir):
os.makedirs(dir)

View file

@ -0,0 +1,25 @@
from glad.lang.d.loader.egl import EGLDLoader
from glad.lang.d.loader.gl import OpenGLDLoader
from glad.lang.d.loader.glx import GLXDLoader
from glad.lang.d.loader.wgl import WGLDLoader
from glad.lang.d.generator import DGenerator
_specs = {
'egl': EGLDLoader,
'gl': OpenGLDLoader,
'glx': GLXDLoader,
'wgl': WGLDLoader
}
_generators = {
'd': DGenerator,
}
def get_generator(name, spec):
gen = _generators.get(name)
loader = _specs.get(spec)
return gen, loader

View file

@ -0,0 +1,861 @@
from itertools import chain
import os.path
import sys
from glad.lang.common.generator import Generator
from glad.lang.common.util import makefiledir
if sys.version_info >= (3, 0):
from io import StringIO
basestring = str
else:
from StringIO import StringIO
def _gl_types(gen, f):
gen.write_opaque_struct(f, '__GLsync')
gen.write_alias(f, 'GLsync', '__GLsync*')
gen.write_opaque_struct(f, '_cl_context')
gen.write_opaque_struct(f, '_cl_event')
gen.write_extern(f)
gen.write_alias(
f,
'GLDEBUGPROC', 'void function(GLenum, GLenum, '
'GLuint, GLenum, GLsizei, in GLchar*, GLvoid*)'
)
gen.write_alias(f, 'GLDEBUGPROCARB', 'GLDEBUGPROC')
gen.write_alias(f, 'GLDEBUGPROCKHR', 'GLDEBUGPROC')
gen.write_alias(
f,
'GLDEBUGPROCAMD', 'void function(GLuint, GLenum, '
'GLenum, GLsizei, in GLchar*, GLvoid*)'
)
gen.write_extern_end(f)
def _egl_types(gen, f):
io = StringIO()
gen.write_opaque_struct(io, 'egl_native_pixmap_t')
f.write('''
// Thanks to @jpf91 (github) for these declarations
version(Windows) {
import core.sys.windows.windows;
alias EGLNativeDisplayType = HDC;
alias EGLNativePixmapType = HBITMAP;
alias EGLNativeWindowType = HWND;
} else version(Symbian) {
alias EGLNativeDisplayType = int;
alias EGLNativeWindowType = void*;
alias EGLNativePixmapType = void*;
} else version(Android) {
//import android.native_window;
//struct egl_native_pixmap_t;
''' + io.getvalue() + '''
//alias ANativeWindow* EGLNativeWindowType;
//alias egl_native_pixmap_t* EGLNativePixmapType;
alias EGLNativeWindowType = void*;
alias EGLNativePixmapType = void*;
alias EGLNativeDisplayType = void*;
} else version(linux) {
version(Xlib) {
import X11.Xlib;
import X11.Xutil;
alias EGLNativeDisplayType = Display*;
alias EGLNativePixmapType = Pixmap;
alias EGLNativeWindowType = Window;
} else {
alias EGLNativeDisplayType = void*;
alias EGLNativePixmapType = uint;
alias EGLNativeWindowType = uint;
}
}
alias EGLObjectKHR = void*;
alias EGLLabelKHR = void*;
extern(System) {
alias EGLSetBlobFuncANDROID = void function(const(void)*, EGLsizeiANDROID, const(void)*, EGLsizeiANDROID);
alias EGLGetBlobFuncANDROID = EGLsizeiANDROID function(const(void)*, EGLsizeiANDROID, const(void)* EGLsizeiANDROID);
struct EGLClientPixmapHI {
void *pData;
EGLint iWidth;
EGLint iHeight;
EGLint iStride;
}
alias EGLDEBUGPROCKHR = void function(EGLenum error,const char *command,EGLint messageType,EGLLabelKHR threadLabel,EGLLabelKHR objectLabel,const char* message);
}
''')
gen.write_extern(f)
gen.write_opaque_struct(f, '_cl_event')
gen.write_extern_end(f)
def _glx_types(gen, f):
f.write('''
version(Xlib) {
import X11.Xlib;
import X11.Xutil;
} else {
alias Bool = int;
alias Status = int;
alias VisualID = uint;
alias XPointer = byte*;
alias XID = uint;
alias Colormap = XID;
alias Display = void;
alias Font = XID;
alias Window = XID;
alias Drawable = XID;
alias Pixmap = XID;
alias Cursor = XID;
alias GContext = XID;
alias KeySym = XID;
extern(System) {
// Borrowed from derelict
struct XExtData {
int number;
XExtData* next;
extern(C) int function(XExtData*) free_private;
XPointer private_data;
}
struct Visual {
XExtData* ext_data;
VisualID visualid;
int _class;
uint red_mask, green_mask, blue_mask;
int bits_per_rgb;
int map_entries;
}
struct XVisualInfo {
Visual *visual;
VisualID visualid;
int screen;
int depth;
int _class;
uint red_mask;
uint green_mask;
uint blue_mask;
int colormap_size;
int bits_per_rgb;
}
}
}
alias DMbuffer = void*;
alias DMparams = void*;
alias VLNode = void*;
alias VLPath = void*;
alias VLServer = void*;
alias int64_t = long;
alias uint64_t = ulong;
alias int32_t = int;
alias GLXContextID = uint;
alias GLXPixmap = uint;
alias GLXDrawable = uint;
alias GLXPbuffer = uint;
alias GLXWindow = uint;
alias GLXFBConfigID = uint;
alias GLXVideoCaptureDeviceNV = XID;
alias GLXPbufferSGIX = XID;
alias GLXVideoSourceSGIX = XID;
alias GLXVideoDeviceNV = uint;
extern(System) {
alias __GLXextFuncPtr = void function();
struct GLXPbufferClobberEvent {
int event_type; /* GLX_DAMAGED or GLX_SAVED */
int draw_type; /* GLX_WINDOW or GLX_PBUFFER */
ulong serial; /* # of last request processed by server */
Bool send_event; /* true if this came for SendEvent request */
Display *display; /* display the event was read from */
GLXDrawable drawable; /* XID of Drawable */
uint buffer_mask; /* mask indicating which buffers are affected */
uint aux_buffer; /* which aux buffer was affected */
int x, y;
int width, height;
int count; /* if nonzero, at least this many more */
}
struct GLXBufferSwapComplete {
int type;
ulong serial; /* # of last request processed by server */
Bool send_event; /* true if this came from a SendEvent request */
Display *display; /* Display the event was read from */
GLXDrawable drawable; /* drawable on which event was requested in event mask */
int event_type;
long ust;
long msc;
long sbc;
}
union GLXEvent {
GLXPbufferClobberEvent glxpbufferclobber;
GLXBufferSwapComplete glxbufferswapcomplete;
int[24] pad;
}
struct GLXBufferClobberEventSGIX {
int type;
ulong serial; /* # of last request processed by server */
Bool send_event; /* true if this came for SendEvent request */
Display *display; /* display the event was read from */
GLXDrawable drawable; /* i.d. of Drawable */
int event_type; /* GLX_DAMAGED_SGIX or GLX_SAVED_SGIX */
int draw_type; /* GLX_WINDOW_SGIX or GLX_PBUFFER_SGIX */
uint mask; /* mask indicating which buffers are affected*/
int x, y;
int width, height;
int count; /* if nonzero, at least this many more */
}
struct GLXHyperpipeNetworkSGIX {
char[80] pipeName; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */
int networkId;
}
struct GLXHyperpipeConfigSGIX {
char[80] pipeName; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */
int channel;
uint participationType;
int timeSlice;
}
struct GLXPipeRect {
char[80] pipeName; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */
int srcXOrigin, srcYOrigin, srcWidth, srcHeight;
int destXOrigin, destYOrigin, destWidth, destHeight;
}
struct GLXPipeRectLimits {
char[80] pipeName; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */
int XOrigin, YOrigin, maxHeight, maxWidth;
}
}
''')
gen.write_extern(f)
gen.write_opaque_struct(f, '__GLXcontextRec')
gen.write_alias(f, 'GLXContext', '__GLXcontextRec*')
gen.write_opaque_struct(f, '__GLXFBConfigRec')
gen.write_alias(f, 'GLXFBConfig', '__GLXFBConfigRec*')
gen.write_alias(f, 'GLXFBConfigSGIX', '__GLXFBConfigRec*')
gen.write_extern_end(f)
def _wgl_types(gen, f):
f.write('''
version(Windows) {
public import core.sys.windows.windows;
} else {
alias BOOL = int;
alias CHAR = char;
alias WORD = ushort;
alias DWORD = uint;
alias FLOAT = float;
alias HANDLE = void*;
alias HDC = HANDLE;
alias HGLRC = HANDLE;
alias INT = int;
alias LPCSTR = const(CHAR)*;
alias LPVOID = void*;
alias UINT = uint;
alias USHORT = ushort;
alias VOID = void;
alias COLORREF = DWORD;
alias HENHMETAFILE = HANDLE;
alias BYTE = byte;
}
alias PROC = HANDLE;
extern(System) {
struct RECT {
int left;
int top;
int right;
int bottom;
}
struct LAYERPLANEDESCRIPTOR {
WORD nSize;
WORD nVersion;
DWORD dwFlags;
BYTE iPixelType;
BYTE cColorBits;
BYTE cRedBits;
BYTE cRedShift;
BYTE cGreenBits;
BYTE cGreenShift;
BYTE cBlueBits;
BYTE cBlueShift;
BYTE cAlphaBits;
BYTE cAlphaShift;
BYTE cAccumBits;
BYTE cAccumRedBits;
BYTE cAccumGreenBits;
BYTE cAccumBlueBits;
BYTE cAccumAlphaBits;
BYTE cDepthBits;
BYTE cStencilBits;
BYTE cAuxBuffers;
BYTE iLayerType;
BYTE bReserved;
COLORREF crTransparent;
}
struct PIXELFORMATDESCRIPTOR {
WORD nSize;
WORD nVersion;
DWORD dwFlags;
BYTE iPixelType;
BYTE cColorBits;
BYTE cRedBits;
BYTE cRedShift;
BYTE cGreenBits;
BYTE cGreenShift;
BYTE cBlueBits;
BYTE cBlueShift;
BYTE cAlphaBits;
BYTE cAlphaShift;
BYTE cAccumBits;
BYTE cAccumRedBits;
BYTE cAccumGreenBits;
BYTE cAccumBlueBits;
BYTE cAccumAlphaBits;
BYTE cDepthBits;
BYTE cStencilBits;
BYTE cAuxBuffers;
BYTE iLayerType;
BYTE bReserved;
DWORD dwLayerMask;
DWORD dwVisibleMask;
DWORD dwDamageMask;
}
struct POINTFLOAT {
FLOAT x;
FLOAT y;
}
struct GLYPHMETRICSFLOAT {
FLOAT gmfBlackBoxX;
FLOAT gmfBlackBoxY;
POINTFLOAT gmfptGlyphOrigin;
FLOAT gmfCellIncX;
FLOAT gmfCellIncY;
}
alias PGLYPHMETRICSFLOAT = GLYPHMETRICSFLOAT*;
alias LPGLYPHMETRICSFLOAT = GLYPHMETRICSFLOAT;
struct GPU_DEVICE {
DWORD cb;
CHAR[32] DeviceName;
CHAR[128] DeviceString;
DWORD Flags;
RECT rcVirtualScreen;
}
alias PGPU_DEVICE = GPU_DEVICE;
}
''')
gen.write_opaque_struct(f, 'HPBUFFERARB')
gen.write_opaque_struct(f, 'HPBUFFEREXT')
gen.write_opaque_struct(f, 'HVIDEOOUTPUTDEVICENV')
gen.write_opaque_struct(f, 'HPVIDEODEV')
gen.write_opaque_struct(f, 'HPGPUNV')
gen.write_opaque_struct(f, 'HGPUNV')
gen.write_opaque_struct(f, 'HVIDEOINPUTDEVICENV')
DTYPES = {
'__pre': {
'egl': 'import core.stdc.stdint : intptr_t;\n\n'
},
'__other': {
'gl': _gl_types,
'egl': _egl_types,
'glx': _glx_types,
'wgl': _wgl_types
},
'gl': {
'GLenum': 'uint', 'GLvoid': 'void', 'GLboolean': 'ubyte',
'GLbitfield': 'uint', 'GLchar': 'char', 'GLbyte': 'byte',
'GLshort': 'short', 'GLint': 'int', 'GLclampx': 'int',
'GLsizei': 'int', 'GLubyte': 'ubyte', 'GLushort': 'ushort',
'GLuint': 'uint', 'GLhalf': 'ushort', 'GLfloat': 'float',
'GLclampf': 'float', 'GLdouble': 'double', 'GLclampd': 'double',
'GLfixed': 'int', 'GLintptr': 'ptrdiff_t', 'GLsizeiptr': 'ptrdiff_t',
'GLintptrARB': 'ptrdiff_t', 'GLsizeiptrARB': 'ptrdiff_t',
'GLcharARB': 'byte', 'GLhandleARB': 'uint', 'GLhalfARB': 'ushort',
'GLhalfNV': 'ushort', 'GLint64EXT': 'long', 'GLuint64EXT': 'ulong',
'GLint64': 'long', 'GLuint64': 'ulong',
'GLvdpauSurfaceNV': 'ptrdiff_t', 'GLeglImageOES': 'void*'
},
'egl': {
'EGLBoolean': 'uint', 'EGLenum': 'uint', 'EGLAttribKHR': 'intptr_t',
'EGLAttrib': 'intptr_t', 'EGLClientBuffer': 'void*', 'EGLConfig': 'void*',
'EGLContext': 'void*', 'EGLDeviceEXT': 'void*', 'EGLDisplay': 'void*',
'EGLImage': 'void*', 'EGLImageKHR': 'void*', 'EGLOutputLayerEXT': 'void*',
'EGLOutputPortEXT': 'void*', 'EGLStreamKHR': 'void*', 'EGLSurface': 'void*',
'EGLSync': 'void*', 'EGLSyncKHR': 'void*', 'EGLSyncNV': 'void*',
'__eglMustCastToProperFunctionPointerType': 'void function()',
'EGLint': 'int', 'EGLTimeKHR': 'ulong', 'EGLTime': 'ulong',
'EGLTimeNV': 'ulong', 'EGLuint64NV': 'ulong',
'EGLuint64KHR': 'ulong', 'EGLuint64MESA': 'ulong',
'EGLsizeiANDROID': 'ptrdiff_t', 'EGLNativeFileDescriptorKHR': 'int'
},
'glx': {
'GLboolean': 'ubyte', 'GLenum': 'uint', 'GLint': 'int',
'GLsizei': 'int', 'GLubyte': 'ubyte', 'GLuint': 'uint',
'GLfloat': 'float', 'GLbitfield': 'uint', 'GLintptr': 'ptrdiff_t',
'GLsizeiptr': 'ptrdiff_t'
},
'wgl': {
'GLbitfield': 'uint', 'GLenum': 'uint', 'GLfloat': 'float',
'GLint': 'int', 'GLsizei': 'int', 'GLuint': 'uint',
'GLushort': 'ushort', 'INT32': 'int', 'INT64': 'long',
'GLboolean': 'ubyte'
},
'SpecialNumbers': {
'gl': [
('GL_FALSE', '0', 'ubyte'), ('GL_TRUE', '1', 'ubyte'),
('GL_NO_ERROR', '0', 'uint'), ('GL_NONE', '0', 'uint'),
('GL_ZERO', '0', 'uint'), ('GL_ONE', '1', 'uint'),
('GL_NONE_OES', '0', 'uint'),
('GL_INVALID_INDEX', '0xFFFFFFFF', 'uint'),
('GL_TIMEOUT_IGNORED', '0xFFFFFFFFFFFFFFFF', 'ulong'),
('GL_TIMEOUT_IGNORED_APPLE', '0xFFFFFFFFFFFFFFFF', 'ulong'),
('GL_VERSION_ES_CL_1_0', '1', 'uint'), ('GL_VERSION_ES_CM_1_1', '1', 'uint'),
('GL_VERSION_ES_CL_1_1', '1', 'uint')
],
'egl': [
('EGL_DONT_CARE', '-1', 'int'), ('EGL_UNKNOWN', '-1', 'int'),
('EGL_NO_NATIVE_FENCE_FD_ANDROID', '-1', 'uint'),
('EGL_DEPTH_ENCODING_NONE_NV', '0', 'uint'),
('EGL_NO_CONTEXT', 'cast(EGLContext)0', 'EGLContext'),
('EGL_NO_DEVICE_EXT', 'cast(EGLDeviceEXT)0', 'EGLDeviceEXT'),
('EGL_NO_DISPLAY', 'cast(EGLDisplay)0', 'EGLDisplay'),
('EGL_NO_IMAGE', 'cast(EGLImage)0', 'EGLImage'),
('EGL_NO_IMAGE_KHR', 'cast(EGLImageKHR)0', 'EGLImageKHR'),
('EGL_DEFAULT_DISPLAY', 'cast(EGLNativeDisplayType)0', 'EGLNativeDisplayType'),
('EGL_NO_FILE_DESCRIPTOR_KHR', 'cast(EGLNativeFileDescriptorKHR)-1', 'EGLNativeFileDescriptorKHR'),
('EGL_NO_OUTPUT_LAYER_EXT', 'cast(EGLOutputLayerEXT)0', 'EGLOutputLayerEXT'),
('EGL_NO_OUTPUT_PORT_EXT', 'cast(EGLOutputPortEXT)0', 'EGLOutputPortEXT'),
('EGL_NO_STREAM_KHR', 'cast(EGLStreamKHR)0', 'EGLStreamKHR'),
('EGL_NO_SURFACE', 'cast(EGLSurface)0', 'EGLSurface'),
('EGL_NO_SYNC', 'cast(EGLSync)0', 'EGLSync'),
('EGL_NO_SYNC_KHR', 'cast(EGLSyncKHR)0', 'EGLSyncKHR'),
('EGL_NO_SYNC_NV', 'cast(EGLSyncNV)0', 'EGLSyncNV'),
('EGL_DISPLAY_SCALING', '10000', 'uint'),
('EGL_FOREVER', '0xFFFFFFFFFFFFFFFF', 'ulong'),
('EGL_FOREVER_KHR', '0xFFFFFFFFFFFFFFFF', 'ulong'),
('EGL_FOREVER_NV', '0xFFFFFFFFFFFFFFFF', 'ulong')
],
'glx': [
('GLX_DONT_CARE', '0xFFFFFFFF', 'uint'),
('GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB', '0', 'uint')
],
'wgl': [
('WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB', '0', 'uint'),
('WGL_FONT_LINES', '0', 'uint'),
('WGL_FONT_POLYGONS', 1, 'uint')
]
}
}
class BaseDGenerator(Generator):
NAME = 'd'
NAME_LONG = 'D'
def open(self):
self._f_loader = open(self.make_path(self.LOADER), 'w')
self._f_gl = open(self.make_path(self.PACKAGE), 'w')
self._f_types = open(self.make_path(self.TYPES), 'w')
self._f_enums = open(self.make_path(self.ENUMS), 'w')
self._f_funcs = open(self.make_path(self.FUNCS), 'w')
self._f_exts = open(self.make_path(self.EXT), 'w')
def close(self):
self._f_loader.close()
self._f_gl.close()
self._f_types.close()
self._f_enums.close()
self._f_funcs.close()
self._f_exts.close()
@property
def PACKAGE(self):
return 'all'
def generate_header(self):
self._f_gl.write('/*\n')
self._f_gl.write(self.header)
self._f_gl.write('*/\n\n')
def generate_loader(self, features, extensions):
f = self._f_loader
rfeatures = features
if self.spec.NAME in ('egl', 'wgl'):
features = {'egl': [], 'wgl': []}
self.write_module(f, self.LOADER)
self.write_imports(f, [self.FUNCS, self.EXT, self.ENUMS, self.TYPES])
self.loader.write(f)
self.loader.write_has_ext(f)
written = set()
for api, version in self.api.items():
loadername = 'Load' if self.LOAD_GL_PREFIX else 'load'
f.write('bool {}{}{}(Loader load) {{\n'
.format(self.LOAD_GL_PREFIX, loadername, api.upper()))
self.loader.write_begin_load(f)
f.write('\tfind_core{}();\n'.format(api.upper()))
for feature in features[api]:
f.write('\tload_{}(load);\n'.format(feature.name))
f.write('\n\tfind_extensions{}();\n'.format(api.upper()))
for ext in extensions[api]:
if len(list(ext.functions)) == 0:
continue
f.write('\tload_{}(load);\n'.format(ext.name))
self.loader.write_end_load(f)
f.write('}\n\n')
f.write('private {\n\n')
f.write('void find_core{}() {{\n'.format(api.upper()))
self.loader.write_find_core(f)
if self.spec.NAME == 'gl':
for feature in features[api]:
f.write('\t{} = (major == {num[0]} && minor >= {num[1]}) ||'
' major > {num[0]};\n'.format(feature.name, num=feature.number))
f.write('\treturn;\n')
f.write('}\n\n')
f.write('void find_extensions{}() {{\n'.format(api.upper()))
if self.spec.NAME == 'gl':
for ext in extensions[api]:
f.write('\t{0} = has_ext("{0}");\n'.format(ext.name))
f.write('\treturn;\n')
f.write('}\n\n')
for feature in features[api]:
f.write('void load_{}(Loader load) {{\n'
.format(feature.name))
if self.spec.NAME == 'gl':
f.write('\tif(!{}) return;\n'.format(feature.name))
for func in feature.functions:
f.write('\t{name} = cast(typeof({name}))load("{name}");\n'
.format(name=func.proto.name))
f.write('\treturn;\n}\n\n')
for ext in extensions[api]:
if len(list(ext.functions)) == 0 or ext.name in written:
continue
f.write('void load_{}(Loader load) {{\n'
.format(ext.name))
if self.spec.NAME == 'gl':
f.write('\tif(!{}) return;\n'.format(ext.name))
for func in ext.functions:
# even if they were in written we need to load it
f.write('\t{name} = cast(typeof({name}))load("{name}");\n'
.format(name=func.proto.name))
f.write('\treturn;\n')
f.write('}\n')
written.add(ext.name)
f.write('\n} /* private */\n\n')
self.write_packages(rfeatures, extensions)
def write_packages(self, allfeatures, allextensions):
f = self._f_gl
self.write_module(f, self.PACKAGE)
self.write_imports(f, [self.FUNCS, self.EXT, self.ENUMS, self.TYPES], False)
for api, features in allfeatures.items():
extensions = allextensions[api]
with open(self.make_path(api), 'w') as f:
self.write_module(f, api)
self.write_imports(f, [self.TYPES], False)
extenums = chain.from_iterable(ext.enums for ext in extensions)
funcenums = chain.from_iterable(ext.enums for ext in extensions)
enums = set(enum.name for enum in extenums) | \
set(enum.name for enum in funcenums)
featfuncs = set(func.proto.name for func in
chain.from_iterable(feat.functions for feat in features))
extfuncs = set(func.proto.name for func in
chain.from_iterable(ext.functions for ext in extensions))
extfuncs = extfuncs - featfuncs
enums |= set(enum.name for enum in
chain.from_iterable(feat.enums for feat in features))
self.write_selective_import(f, self.FUNCS, featfuncs)
self.write_selective_import(f, self.EXT, extfuncs)
self.write_selective_import(f, self.ENUMS, enums)
def generate_types(self, types):
f = self._f_types
self.write_module(f, self.TYPES)
f.write(self.TYPE_DICT.get('__pre', {}).get(self.spec.NAME,''))
for ogl, d in self.TYPE_DICT[self.spec.NAME].items():
self.write_alias(f, ogl, d)
self.TYPE_DICT['__other'][self.spec.NAME](self, f)
def generate_features(self, features):
self.write_enums(features)
self.write_funcs(features)
def write_enums(self, features):
e = self._f_enums
self.write_module(e, self.ENUMS)
self.write_imports(e, [self.TYPES])
for v in self.TYPE_DICT['SpecialNumbers'][self.spec.NAME]:
self.write_enum(e, *v)
written = set()
for feature in features:
for enum in feature.enums:
if enum.group == 'SpecialNumbers':
written.add(enum)
continue
if not enum in written:
self.write_enum(e, enum.name, enum.value)
written.add(enum)
def write_funcs(self, features):
f = self._f_funcs
self.write_module(f, self.FUNCS)
self.write_imports(f, [self.TYPES])
if self.spec.NAME == 'gl':
for feature in features:
self.write_boolean(f, feature.name)
if self.spec.NAME in ('egl', 'wgl'):
self.write_extern(f)
for feature in features:
for func in feature.functions:
self.write_function_def(f, func)
self.write_extern_end(f)
else:
self.write_functions(f, set(), set(), features)
def generate_extensions(self, extensions, enums, functions):
f = self._f_exts
self.write_module(f, self.EXT)
self.write_imports(f, [self.TYPES, self.ENUMS, self.FUNCS])
write = set()
written = set(enum.name for enum in enums) | \
set(function.proto.name for function in functions)
for ext in extensions:
if self.spec.NAME == 'gl' and not ext.name in written:
self.write_boolean(f, ext.name)
for enum in ext.enums:
if not enum.name in written and not enum.group == 'SpecialNumbers':
self.write_enum(self._f_enums, enum.name, enum.value)
written.add(enum.name)
written.add(ext.name)
self.write_functions(f, write, written, extensions)
def write_functions(self, f, write, written, extensions):
self.write_prototype_pre(f)
for ext in extensions:
for func in ext.functions:
if not func.proto.name in written:
self.write_function_prototype(f, func)
write.add(func)
written.add(func.proto.name)
self.write_prototype_post(f)
self.write_function_pre(f)
for func in write:
self.write_function(f, func)
self.write_function_post(f)
def make_path(self, name):
path = os.path.join(self.path, self.MODULE.split('.')[-1],
self.spec.NAME, name.split('.')[-1] + self.FILE_EXTENSION)
makefiledir(path)
return path
def write_imports(self, fobj, modules, private=True):
raise NotImplementedError
def write_selective_import(self, fobj, imports):
raise NotImplementedError
def write_module(self, fobj, name):
raise NotImplementedError
def write_prototype_pre(self, fobj):
raise NotImplementedError
def write_prototype_post(self, fobj):
raise NotImplementedError
def write_function_pre(self, fobj):
raise NotImplementedError
def write_function_post(self, fobj):
raise NotImplementedError
def write_extern(self, fobj):
raise NotImplementedError
def write_extern_end(self, fobj):
raise NotImplementedError
def write_shared(self, fobj):
raise NotImplementedError
def write_shared_end(self, fobj):
raise NotImplementedError
def write_function_def(self, fobj, func):
raise NotImplementedError
def write_function(self, fobj, func):
raise NotImplementedError
def write_function_prototype(self, fobj, func):
raise NotImplementedError
def write_boolean(self, fobj, name, value=False):
raise NotImplementedError
def write_enum(self, fobj, name, value, type='uint'):
raise NotImplementedError
def write_opaque_struct(self, fobj, name):
raise NotImplementedError
def write_alias(self, fobj, newn, decl):
raise NotImplementedError
class DGenerator(BaseDGenerator):
MODULE = 'glad'
LOADER = 'loader'
ENUMS = 'enums'
EXT = 'ext'
FUNCS = 'funcs'
TYPES = 'types'
FILE_EXTENSION = '.d'
TYPE_DICT = DTYPES
LOAD_GL_PREFIX = 'glad'
def write_imports(self, fobj, modules, private=True):
for mod in modules:
if private:
fobj.write('private ')
else:
fobj.write('public ')
fobj.write('import {}.{}.{};\n'.format(self.MODULE, self.spec.NAME, mod))
def write_selective_import(self, fobj, mod, imports):
if len(imports) == 0: return
fobj.write('public import {}.{}.{} :\n'.format(self.MODULE, self.spec.NAME, mod))
imports = set(imports)
last = len(imports)
for i, im in enumerate(imports, 1):
fobj.write(im)
if not i == last:
fobj.write(', ')
if (i % 5) == 0:
fobj.write('\n')
fobj.write(';\n\n')
def write_module(self, fobj, name):
fobj.write('module {}.{}.{};\n\n\n'.format(self.MODULE, self.spec.NAME, name))
def write_prototype_pre(self, fobj):
fobj.write('nothrow @nogc ')
self.write_extern(fobj)
def write_prototype_post(self, fobj):
self.write_extern_end(fobj)
def write_function_pre(self, fobj):
self.write_shared(fobj)
def write_function_post(self, fobj):
self.write_shared_end(fobj)
def write_extern(self, fobj):
fobj.write('extern(System) {\n')
def write_extern_end(self, fobj):
fobj.write('}\n')
def write_shared(self, fobj):
fobj.write('__gshared {\n')
def write_shared_end(self, fobj):
fobj.write('}\n')
def write_function_def(self, fobj, func):
fobj.write('{} {}('.format(func.proto.ret.to_d(), func.proto.name))
fobj.write(', '.join(param.type.to_d() for param in func.params))
fobj.write(');\n')
def write_function(self, fobj, func):
fobj.write('fp_{0} {0};\n'.format(func.proto.name))
def write_function_prototype(self, fobj, func):
fobj.write('alias fp_{} = {} function('
.format(func.proto.name, func.proto.ret.to_d()))
fobj.write(', '.join(param.type.to_d() for param in func.params))
fobj.write(');\n')
def write_boolean(self, fobj, name, value=False):
if value:
fobj.write('bool {} = true;\n'.format(name))
else:
fobj.write('bool {};\n'.format(name))
def write_enum(self, fobj, name, value, type='uint'):
if isinstance(value, basestring) and '"' in value:
type = 'const(char)*'
fobj.write('enum {} {} = {};\n'.format(type, name, value))
def write_opaque_struct(self, fobj, name):
fobj.write('struct _{name}; alias {name} = _{name}*;\n'.format(name=name))
def write_alias(self, fobj, newn, decl):
fobj.write('alias {} = {};\n'.format(newn, decl))

View file

@ -0,0 +1,90 @@
LOAD_OPENGL_DLL = '''
version(Windows) {
private import core.sys.windows.windows;
} else {
private import core.sys.posix.dlfcn;
}
version(Windows) {
private __gshared HMODULE libGL;
} else {
private __gshared void* libGL;
}
extern(System) private @nogc alias gladGetProcAddressPtrType = void* function(const(char)*);
private __gshared gladGetProcAddressPtrType gladGetProcAddressPtr;
%(pre)s
bool %(init)s() @nogc {
version(Windows) {
libGL = LoadLibraryA("opengl32.dll");
if(libGL !is null) {
gladGetProcAddressPtr = cast(typeof(gladGetProcAddressPtr))GetProcAddress(
libGL, "wglGetProcAddress");
return gladGetProcAddressPtr !is null;
}
return false;
} else {
version(OSX) {
enum const(char)*[] NAMES = [
"../Frameworks/OpenGL.framework/OpenGL",
"/Library/Frameworks/OpenGL.framework/OpenGL",
"/System/Library/Frameworks/OpenGL.framework/OpenGL",
"/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL"
];
} else {
enum const(char)*[] NAMES = ["libGL.so.1", "libGL.so"];
}
foreach(name; NAMES) {
libGL = dlopen(name, RTLD_NOW | RTLD_GLOBAL);
if(libGL !is null) {
version(OSX) {
return true;
} else {
gladGetProcAddressPtr = cast(typeof(gladGetProcAddressPtr))dlsym(libGL,
"glXGetProcAddressARB");
return gladGetProcAddressPtr !is null;
}
}
}
return false;
}
}
%(pre)s
void* %(proc)s(const(char)* namez) @nogc {
if(libGL is null) return null;
void* result;
if(gladGetProcAddressPtr !is null) {
result = gladGetProcAddressPtr(namez);
}
if(result is null) {
version(Windows) {
result = GetProcAddress(libGL, namez);
} else {
result = dlsym(libGL, namez);
}
}
return result;
}
%(pre)s
void %(terminate)s() @nogc {
version(Windows) {
if(libGL !is null) {
FreeLibrary(libGL);
libGL = null;
}
} else {
if(libGL !is null) {
dlclose(libGL);
libGL = null;
}
}
}
'''

View file

@ -0,0 +1,39 @@
from glad.lang.common.loader import BaseLoader
_EGL_LOADER = '''
bool gladLoadEGL() {
return gladLoadEGL(x => eglGetProcAddress(x));
}
'''
_EGL_HAS_EXT = '''
private bool has_ext(const(char)* ext) @nogc {
return true;
}
'''
class EGLDLoader(BaseLoader):
def write_header_end(self, fobj):
pass
def write_header(self, fobj):
pass
def write(self, fobj):
fobj.write('alias Loader = void* delegate(const(char)*);\n')
if not self.disabled:
fobj.write(_EGL_LOADER)
def write_begin_load(self, fobj):
pass
def write_end_load(self, fobj):
fobj.write('\treturn true;\n')
def write_find_core(self, fobj):
pass
def write_has_ext(self, fobj):
fobj.write(_EGL_HAS_EXT)

View file

@ -0,0 +1,118 @@
from glad.lang.common.loader import BaseLoader
from glad.lang.d.loader import LOAD_OPENGL_DLL
_OPENGL_LOADER = \
LOAD_OPENGL_DLL % {'pre':'private', 'init':'open_gl',
'proc':'get_proc', 'terminate':'close_gl'} + '''
bool gladLoadGL() {
bool status = false;
if(open_gl()) {
status = gladLoadGL(x => get_proc(x));
close_gl();
}
return status;
}
'''
_OPENGL_HAS_EXT = '''
static struct GLVersion { static int major = 0; static int minor = 0; }
private extern(C) char* strstr(const(char)*, const(char)*) @nogc;
private extern(C) int strcmp(const(char)*, const(char)*) @nogc;
private extern(C) int strncmp(const(char)*, const(char)*, size_t) @nogc;
private extern(C) size_t strlen(const(char)*) @nogc;
private bool has_ext(const(char)* ext) @nogc {
if(GLVersion.major < 3) {
const(char)* extensions = cast(const(char)*)glGetString(GL_EXTENSIONS);
const(char)* loc;
const(char)* terminator;
if(extensions is null || ext is null) {
return false;
}
while(1) {
loc = strstr(extensions, ext);
if(loc is null) {
return false;
}
terminator = loc + strlen(ext);
if((loc is extensions || *(loc - 1) == ' ') &&
(*terminator == ' ' || *terminator == '\\0')) {
return true;
}
extensions = terminator;
}
} else {
int num;
glGetIntegerv(GL_NUM_EXTENSIONS, &num);
for(uint i=0; i < cast(uint)num; i++) {
if(strcmp(cast(const(char)*)glGetStringi(GL_EXTENSIONS, i), ext) == 0) {
return true;
}
}
}
return false;
}
'''
_FIND_VERSION = '''
// Thank you @elmindreda
// https://github.com/elmindreda/greg/blob/master/templates/greg.c.in#L176
// https://github.com/glfw/glfw/blob/master/src/context.c#L36
int i;
const(char)* glversion;
const(char)*[] prefixes = [
"OpenGL ES-CM ".ptr,
"OpenGL ES-CL ".ptr,
"OpenGL ES ".ptr,
];
glversion = cast(const(char)*)glGetString(GL_VERSION);
if (glversion is null) return;
foreach(prefix; prefixes) {
size_t length = strlen(prefix);
if (strncmp(glversion, prefix, length) == 0) {
glversion += length;
break;
}
}
int major = glversion[0] - \'0\';
int minor = glversion[2] - \'0\';
GLVersion.major = major; GLVersion.minor = minor;
'''
class OpenGLDLoader(BaseLoader):
def write_header_end(self, fobj):
pass
def write_header(self, fobj):
pass
def write(self, fobj):
fobj.write('alias Loader = void* delegate(const(char)*);\n')
if not self.disabled and 'gl' in self.apis:
fobj.write(_OPENGL_LOADER)
def write_begin_load(self, fobj):
fobj.write('\tglGetString = cast(typeof(glGetString))load("glGetString");\n')
fobj.write('\tif(glGetString is null) { return false; }\n')
fobj.write('\tif(glGetString(GL_VERSION) is null) { return false; }\n\n')
def write_end_load(self, fobj):
fobj.write('\treturn GLVersion.major != 0 || GLVersion.minor != 0;\n')
def write_find_core(self, fobj):
fobj.write(_FIND_VERSION)
def write_has_ext(self, fobj):
fobj.write(_OPENGL_HAS_EXT)

View file

@ -0,0 +1,49 @@
from glad.lang.common.loader import BaseLoader
from glad.lang.d.loader import LOAD_OPENGL_DLL
_GLX_LOADER = \
LOAD_OPENGL_DLL % {'pre':'private', 'init':'open_gl',
'proc':'get_proc', 'terminate':'close_gl'} + '''
bool gladLoadGLX() {
bool status = false;
if(open_gl()) {
status = gladLoadGLX(x => get_proc(x));
close_gl();
}
return status;
}
'''
_GLX_HAS_EXT = '''
private bool has_ext(const(char)* name) @nogc {
return true;
}
'''
class GLXDLoader(BaseLoader):
def write_header_end(self, fobj):
pass
def write_header(self, fobj):
pass
def write(self, fobj):
fobj.write('alias Loader = void* delegate(const(char)*);\n')
if not self.disabled:
fobj.write(_GLX_LOADER)
def write_begin_load(self, fobj):
pass
def write_end_load(self, fobj):
fobj.write('\treturn true;\n')
def write_find_core(self, fobj):
pass
def write_has_ext(self, fobj):
fobj.write(_GLX_HAS_EXT)

View file

@ -0,0 +1,36 @@
from glad.lang.common.loader import BaseLoader
from glad.lang.d.loader.glx import _GLX_LOADER
_WGL_LOADER = _GLX_LOADER.replace('GLX', 'WGL')
_WGL_HAS_EXT = '''
private bool has_ext(const(char)* name) @nogc {
return true;
}
'''
class WGLDLoader(BaseLoader):
def write_header_end(self, fobj):
pass
def write_header(self, fobj):
pass
def write(self, fobj):
fobj.write('alias Loader = void* delegate(const(char)*);\n')
if not self.disabled:
fobj.write(_WGL_LOADER)
def write_begin_load(self, fobj):
pass
def write_end_load(self, fobj):
fobj.write('\treturn true;\n')
def write_find_core(self, fobj):
pass
def write_has_ext(self, fobj):
fobj.write(_WGL_HAS_EXT)

View file

@ -0,0 +1,27 @@
from glad.lang.nim.loader.egl import EGLNimLoader
from glad.lang.nim.loader.gl import OpenGLNimLoader
from glad.lang.nim.loader.glx import GLXNimLoader
from glad.lang.nim.loader.wgl import WGLNimLoader
from glad.lang.nim.generator import NimGenerator
# TODO finish converting the egl, glx & wgl loaders to Nim
_specs = {
# 'egl': EGLNimLoader,
'gl': OpenGLNimLoader
# 'glx': GLXNimLoader,
# 'wgl': WGLNimLoader
}
_generators = {
'nim': NimGenerator,
}
def get_generator(name, spec):
gen = _generators.get(name)
loader = _specs.get(spec)
return gen, loader

View file

@ -0,0 +1,530 @@
from itertools import chain
import os.path
import sys
from glad.lang.common.generator import Generator
from glad.lang.common.util import makefiledir
if sys.version_info >= (3, 0):
from io import StringIO
basestring = str
else:
from StringIO import StringIO
def _gl_types(gen, f):
f.write('''
GLdebugProc* = proc (
source: GLenum,
typ: GLenum,
id: GLuint,
severity: GLenum,
length: GLsizei,
message: ptr GLchar,
userParam: pointer) {.stdcall.}
GLdebugProcArb* = proc (
source: GLenum,
typ: GLenum,
id: GLuint,
severity: GLenum,
len: GLsizei,
message: ptr GLchar,
userParam: pointer) {.stdcall.}
GLdebugProcAmd* = proc (
id: GLuint,
category: GLenum,
severity: GLenum,
len: GLsizei,
message: ptr GLchar,
userParam: pointer) {.stdcall.}
GLdebugProcKhr* = proc (
source, typ: GLenum,
id: GLuint,
severity: GLenum,
length: GLsizei,
message: ptr GLchar,
userParam: pointer) {.stdcall.}
''')
# TODO finish converting the egl, glx & wgl loaders to Nim
# def _egl_types(gen, f):
# def _glx_types(gen, f):
# def _wgl_types(gen, f):
NIMTYPES = {
'__other': {
'gl': _gl_types
# 'egl': _egl_types,
# 'glx': _glx_types,
# 'wgl': _wgl_types
},
'gl': {
'GLbitfield': 'uint32',
'GLboolean': 'bool',
'GLbyte': 'int8',
'GLchar': 'char',
'GLcharARB': 'byte',
'GLclampd': 'float64',
'GLclampf': 'float32',
'GLclampx': 'int32',
'GLdouble': 'float64',
'GLeglImageOES': 'distinct pointer',
'GLenum': 'uint32',
'GLfixed': 'int32',
'GLfloat': 'float32',
'GLhalf': 'uint16',
'GLhalfARB': 'uint16',
'GLhalfNV': 'uint16',
'GLhandleARB': 'uint32',
'GLint': 'int32',
'GLint64': 'int64',
'GLint64EXT': 'int64',
'GLintptr': 'int32',
'GLintptrARB': 'int32',
'GLshort': 'int16',
'GLsizei': 'int32',
'GLsizeiptr': 'int32',
'GLsizeiptrARB': 'int32',
'GLubyte': 'uint8',
'GLuint': 'uint32',
'GLuint64': 'uint64',
'GLuint64EXT': 'uint64',
'GLushort': 'uint16',
'GLvdpauSurfaceNV': 'int32',
'GLvoid': 'pointer',
'GLsync': 'distinct pointer',
'ClContext': 'distinct pointer',
'ClEvent': 'distinct pointer'
},
'egl': {
'EGLAttrib': 'int32',
'EGLAttribKHR': 'int32',
'EGLBoolean': 'bool',
'EGLClientBuffer': 'distinct pointer',
'EGLConfig': 'distinct pointer',
'EGLContext': 'distinct pointer',
'EGLDeviceEXT': 'distinct pointer',
'EGLDisplay': 'distinct pointer',
'EGLImage': 'distinct pointer',
'EGLImageKHR': 'distinct pointer',
'EGLNativeFileDescriptorKHR': 'int32',
'EGLOutputLayerEXT': 'distinct pointer',
'EGLOutputPortEXT': 'distinct pointer',
'EGLStreamKHR': 'distinct pointer',
'EGLSurface': 'distinct pointer',
'EGLSync': 'distinct pointer',
'EGLSyncKHR': 'distinct pointer',
'EGLSyncNV': 'distinct pointer',
'EGLTimeKHR': 'uint64',
'EGLTime': 'uint64',
'EGLTimeNV': 'uint64',
'EGLenum': 'uint32',
'EGLint': 'int32',
'EGLsizeiANDROID': 'distinct pointer',
'EGLuint64KHR': 'uint64',
'EGLuint64MESA': 'uint64',
'EGLuint64NV': 'uint64',
# '__eglMustCastToProperFunctionPointerType': 'void function()'
},
'glx': {
'GLbitfield': 'uint32',
'GLboolean': 'uint8',
'GLenum': 'uint32',
'GLfloat': 'float32',
'GLint': 'int32',
'GLintptr': 'int32',
'GLsizei': 'int32',
'GLsizeiptr': 'int32',
'GLubyte': 'uint8',
'GLuint': 'uint32'
},
'wgl': {
'GLbitfield': 'uint32',
'GLboolean': 'uint8',
'GLenum': 'uint32',
'GLfloat': 'float32',
'GLint': 'int32',
'GLsizei': 'int32',
'GLuint': 'uint32',
'GLushort': 'uint16',
'INT32': 'int32',
'INT64': 'int64'
},
'SpecialNumbers': {
'gl': [
('GL_FALSE', '0', None),
('GL_INVALID_INDEX', '0xFFFFFFFF', 'uint32'),
('GL_NONE', '0', None),
('GL_NONE_OES', '0', None),
('GL_NO_ERROR', '0', None),
('GL_ONE', '1', None),
('GL_TIMEOUT_IGNORED', '0xFFFFFFFFFFFFFFFF', 'uint64'),
('GL_TIMEOUT_IGNORED_APPLE', '0xFFFFFFFFFFFFFFFF', 'uint64'),
('GL_TRUE', '1', None),
('GL_VERSION_ES_CL_1_0', '1', None),
('GL_VERSION_ES_CL_1_1', '1', None),
('GL_VERSION_ES_CM_1_1', '1', None),
('GL_ZERO', '0', None),
],
'egl': [
# ('EGL_DONT_CARE', '-1', 'int'), ('EGL_UNKNOWN', '-1', 'int'),
# ('EGL_NO_NATIVE_FENCE_FD_ANDROID', '-1', 'uint'),
# ('EGL_DEPTH_ENCODING_NONE_NV', '0', 'uint'),
# ('EGL_NO_CONTEXT', 'cast(EGLContext)0', 'EGLContext'),
# ('EGL_NO_DEVICE_EXT', 'cast(EGLDeviceEXT)0', 'EGLDeviceEXT'),
# ('EGL_NO_DISPLAY', 'cast(EGLDisplay)0', 'EGLDisplay'),
# ('EGL_NO_IMAGE', 'cast(EGLImage)0', 'EGLImage'),
# ('EGL_NO_IMAGE_KHR', 'cast(EGLImageKHR)0', 'EGLImageKHR'),
# ('EGL_DEFAULT_DISPLAY', 'cast(EGLNativeDisplayType)0', 'EGLNativeDisplayType'),
# ('EGL_NO_FILE_DESCRIPTOR_KHR', 'cast(EGLNativeFileDescriptorKHR)-1', 'EGLNativeFileDescriptorKHR'),
# ('EGL_NO_OUTPUT_LAYER_EXT', 'cast(EGLOutputLayerEXT)0', 'EGLOutputLayerEXT'),
# ('EGL_NO_OUTPUT_PORT_EXT', 'cast(EGLOutputPortEXT)0', 'EGLOutputPortEXT'),
# ('EGL_NO_STREAM_KHR', 'cast(EGLStreamKHR)0', 'EGLStreamKHR'),
# ('EGL_NO_SURFACE', 'cast(EGLSurface)0', 'EGLSurface'),
# ('EGL_NO_SYNC', 'cast(EGLSync)0', 'EGLSync'),
# ('EGL_NO_SYNC_KHR', 'cast(EGLSyncKHR)0', 'EGLSyncKHR'),
# ('EGL_NO_SYNC_NV', 'cast(EGLSyncNV)0', 'EGLSyncNV'),
# ('EGL_DISPLAY_SCALING', '10000', 'uint'),
# ('EGL_FOREVER', '0xFFFFFFFFFFFFFFFF', 'ulong'),
# ('EGL_FOREVER_KHR', '0xFFFFFFFFFFFFFFFF', 'ulong'),
# ('EGL_FOREVER_NV', '0xFFFFFFFFFFFFFFFF', 'ulong')
],
'glx': [
# ('GLX_DONT_CARE', '0xFFFFFFFF', 'uint'),
# ('GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB', '0', 'uint')
],
'wgl': [
# ('WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB', '0', 'uint'),
# ('WGL_FONT_LINES', '0', 'uint'),
# ('WGL_FONT_POLYGONS', 1, 'uint')
]
},
'SpecialEnumNames': {
'gl': {
'GL_BYTE': 'cGL_BYTE',
'GL_SHORT': 'cGL_SHORT',
'GL_INT': 'cGL_INT',
'GL_FLOAT': 'cGL_FLOAT',
'GL_DOUBLE': 'cGL_DOUBLE',
'GL_FIXED': 'cGL_FIXED'
},
'egl': {},
'glx': {},
'wgl': {}
},
'SpecialFuncNames': {
'gl': {
'glGetTransformFeedbacki_v': 'glGetTransformFeedbacki_v2'
},
'egl': {},
'glx': {},
'wgl': {}
}
}
class NimGenerator(Generator):
NAME = 'nim'
NAME_LONG = 'Nim'
MODULE = 'glad'
FILE_EXTENSION = '.nim'
TYPE_DICT = NIMTYPES
LOAD_GL_PREFIX = 'glad'
EXT_PREFIX = 'GLAD_'
def open(self):
self._f_gl = open(self.make_path(self.spec.NAME), 'w')
def close(self):
self._f_gl.close()
def generate_header(self):
self._f_gl.write('#[')
self._f_gl.write(self.header)
self._f_gl.write(']#\n\n')
self._f_gl.write('import strutils\n\n')
self._f_gl.write('var glVersionMajor, glVersionMinor: int\n\n')
def generate_loader(self, features, extensions):
f = self._f_gl
rfeatures = features
if self.spec.NAME in ('egl', 'wgl'):
features = {'egl': [], 'wgl': []}
self.loader.write(f)
self.loader.write_has_ext(f, self.get_version())
written = set()
for api, version in self.api.items():
# core load procs
for feature in features[api]:
f.write('proc load_{}(load: proc) =\n'
.format(feature.name))
if self.spec.NAME == 'gl':
f.write(' if not {}{}: return\n\n'.format(self.EXT_PREFIX,
feature.name))
for func in feature.functions:
self.write_func_definition(f, func)
f.write('\n\n')
# extension load procs
for ext in extensions[api]:
if len(list(ext.functions)) == 0 or ext.name in written:
continue
f.write('proc load_{}(load: proc) =\n'
.format(ext.name))
if self.spec.NAME == 'gl':
f.write(' if not {}{}: return\n'.format(self.EXT_PREFIX,
ext.name))
for func in ext.functions:
# even if they were in written we need to load it
self.write_func_definition(f, func)
f.write('\n\n')
written.add(ext.name)
# findExtensions proc
f.write('proc findExtensions{}() =\n'.format(api.upper()))
if self.spec.NAME == 'gl':
for ext in extensions[api]:
f.write(' {0}{1} = hasExt("{1}")\n'.format(self.EXT_PREFIX,
ext.name))
f.write('\n\n')
# findCore proc
f.write('proc findCore{}(glVersion: string) =\n'.format(api.upper()))
self.loader.write_find_core(f)
if self.spec.NAME == 'gl':
for feature in features[api]:
f.write(' {}{} = (major == {num[0]} and minor >= {num[1]}) or'
' major > {num[0]}\n'.format(self.EXT_PREFIX, feature.name,
num=feature.number))
f.write('\n\n')
# main loader proc
loadername = 'Load' if self.LOAD_GL_PREFIX else 'load'
f.write('proc {}{}{}*(load: proc): bool =\n'
.format(self.LOAD_GL_PREFIX, loadername, api.upper()))
self.loader.write_begin_load(f)
f.write(' findCore{}($glVersion)\n\n'.format(api.upper()))
for feature in features[api]:
f.write(' load_{}(load)\n'.format(feature.name))
f.write('\n findExtensions{}()\n\n'.format(api.upper()))
for ext in extensions[api]:
if len(list(ext.functions)) == 0:
continue
f.write(' load_{}(load);\n'.format(ext.name))
self.loader.write_end_load(f)
f.write('\n')
def write_func_definition(self, fobj, func):
func_name = self.map_func_name(func)
fobj.write(' {} = cast['.format(func_name))
self.write_function_declaration(fobj, func)
fobj.write('](load("{}"))\n'.format(func_name))
def map_func_name(self, func):
name = func.proto.name
m = self.TYPE_DICT['SpecialFuncNames'][self.spec.NAME]
return m[name] if name in m else name
def generate_types(self, types):
f = self._f_gl
f.write('# Types\ntype\n')
for ogl, d in sorted(self.TYPE_DICT[self.spec.NAME].items()):
f.write(' {}* = {}\n'.format(ogl, d))
self.TYPE_DICT['__other'][self.spec.NAME](self, f)
f.write('\n')
def generate_features(self, features):
self.write_enums(features)
self.write_funcs(features)
def write_enums(self, features):
f = self._f_gl
f.write('\n# Enums\nconst\n')
for v in sorted(self.TYPE_DICT['SpecialNumbers'][self.spec.NAME]):
self.write_enum(f, *v)
f.write('\n')
written = set()
for feature in features:
for enum in feature.enums:
if enum.group == 'SpecialNumbers':
written.add(enum)
continue
if not enum in written:
self.write_enum(f, enum.name, enum.value)
written.add(enum)
f.write('\n')
def write_funcs(self, features):
f = self._f_gl
f.write('\n# Functions\nvar\n')
if self.spec.NAME == 'gl':
for feature in features:
self.write_boolean(f, feature.name)
f.write('\n')
# TODO
if self.spec.NAME in ('egl', 'wgl'):
for feature in features:
for func in feature.functions:
self.write_function_def(f, func) # TODO
f.write('\n')
else:
self.write_functions(f, set(), set(), features)
f.write('\n\n')
# TODO
def write_function_def(self, fobj, func):
fobj.write('{} {}('.format(func.proto.ret.to_nim(), self.map_func_name(func)))
fobj.write(', '.join(param.type.to_nim() for param in func.params))
fobj.write(');\n')
def generate_extensions(self, extensions, enums, functions):
f = self._f_gl
write = set()
written = set(enum.name for enum in enums) | \
set(function.proto.name for function in functions)
f.write('# Extensions\nvar\n')
for ext in extensions:
if self.spec.NAME == 'gl' and not ext.name in written:
self.write_boolean(f, ext.name)
for enum in ext.enums:
if not enum.name in written and not enum.group == 'SpecialNumbers':
type = (None if enum.group == 'TransformFeedbackTokenNV'
else 'GLenum')
self.write_enum(f, enum.name, enum.value, type)
written.add(enum.name)
written.add(ext.name)
f.write('\n')
self.write_functions(f, write, written, extensions)
f.write('\n\n')
def write_functions(self, f, write, written, extensions):
for ext in extensions:
for func in ext.functions:
if not func.proto.name in written:
self.write_function_var(f, func)
write.add(func)
written.add(func.proto.name)
def write_function_var(self, fobj, func):
fobj.write(' {}*: '.format(self.map_func_name(func)))
self.write_function_declaration(fobj, func)
fobj.write('\n')
def write_function_declaration(self, fobj, func):
fobj.write('proc ('.format(self.map_func_name(func)))
fobj.write(', '.join('{}: {}'.format(self.to_nim_param_name(param.name),
param.type.to_nim())
for param in func.params))
fobj.write(')')
ret = func.proto.ret.to_nim()
if (ret != 'void'):
fobj.write(': {}'.format(ret))
fobj.write(' {.cdecl.}')
# TODO
# def write_function_var(self, fobj, func):
# fobj.write(' {} = cast[proc ('.format(func.proto.name))
# fobj.write(', '.join('{}: {}'.format(self.to_nim_param_name(param.name),
# param.type.to_nim())
# for param in func.params))
# fobj.write(')')
#
# ret = func.proto.ret.to_nim()
# if (ret != 'void'):
# fobj.write(': {}'.format(ret))
#
# fobj.write(' {.cdecl.}]')
# fobj.write(' (getProcAddress("{}"))\n'.format(func.proto.name))
NIM_KEYWORDS = [ # as of Nim 0.13.0
'addr', 'and', 'as', 'asm', 'atomic',
'bind', 'block', 'break',
'case', 'cast', 'concept', 'const', 'continue', 'converter',
'defer', 'discard', 'distinct', 'div', 'do',
'elif', 'else', 'end', 'enum', 'except', 'export',
'finally', 'for', 'from', 'func',
'generic',
'if', 'import', 'in', 'include', 'interface', 'is', 'isnot', 'iterator',
'let',
'macro', 'method', 'mixin', 'mod',
'nil', 'not', 'notin',
'object', 'of', 'or', 'out',
'proc', 'ptr',
'raise', 'ref', 'return',
'shl', 'shr', 'static',
'template', 'try', 'tuple', 'type',
'using',
'var',
'when', 'while', 'with', 'without',
'xor',
'yield'
]
def to_nim_param_name(self, name):
return '`{}`'.format(name) if name in self.NIM_KEYWORDS else name
def make_path(self, name):
path = os.path.join(self.path, self.MODULE.split('.')[-1],
name.split('.')[-1] + self.FILE_EXTENSION)
makefiledir(path)
return path
def write_boolean(self, fobj, name):
fobj.write(' {}{}*: bool\n'.format(self.EXT_PREFIX, name))
def write_enum(self, fobj, name, value, type='GLenum'):
fobj.write(' {}*'.format(self.map_enum_name(name)))
if type:
fobj.write(': {0} = {0}({1})'.format(type, value))
else:
fobj.write(' = {}'.format(value))
fobj.write('\n')
def map_enum_name(self, name):
m = self.TYPE_DICT['SpecialEnumNames'][self.spec.NAME]
return m[name] if name in m else name
def get_version(self):
return self.api[self.spec.NAME]

View file

@ -0,0 +1,90 @@
LOAD_OPENGL_DLL = '''
version(Windows) {
private import std.c.windows.windows;
} else {
private import core.sys.posix.dlfcn;
}
version(Windows) {
private __gshared HMODULE libGL;
} else {
private __gshared void* libGL;
}
extern(System) private @nogc alias gladGetProcAddressPtrType = void* function(const(char)*);
private __gshared gladGetProcAddressPtrType gladGetProcAddressPtr;
%(pre)s
bool %(init)s() @nogc {
version(Windows) {
libGL = LoadLibraryA("opengl32.dll");
if(libGL !is null) {
gladGetProcAddressPtr = cast(typeof(gladGetProcAddressPtr))GetProcAddress(
libGL, "wglGetProcAddress");
return gladGetProcAddressPtr !is null;
}
return false;
} else {
version(OSX) {
enum const(char)*[] NAMES = [
"../Frameworks/OpenGL.framework/OpenGL",
"/Library/Frameworks/OpenGL.framework/OpenGL",
"/System/Library/Frameworks/OpenGL.framework/OpenGL",
"/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL"
];
} else {
enum const(char)*[] NAMES = ["libGL.so.1", "libGL.so"];
}
foreach(name; NAMES) {
libGL = dlopen(name, RTLD_NOW | RTLD_GLOBAL);
if(libGL !is null) {
version(OSX) {
return true;
} else {
gladGetProcAddressPtr = cast(typeof(gladGetProcAddressPtr))dlsym(libGL,
"glXGetProcAddressARB");
return gladGetProcAddressPtr !is null;
}
}
}
return false;
}
}
%(pre)s
void* %(proc)s(const(char)* namez) @nogc {
if(libGL is null) return null;
void* result;
if(gladGetProcAddressPtr !is null) {
result = gladGetProcAddressPtr(namez);
}
if(result is null) {
version(Windows) {
result = GetProcAddress(libGL, namez);
} else {
result = dlsym(libGL, namez);
}
}
return result;
}
%(pre)s
void %(terminate)s() @nogc {
version(Windows) {
if(libGL !is null) {
FreeLibrary(libGL);
libGL = null;
}
} else {
if(libGL !is null) {
dlclose(libGL);
libGL = null;
}
}
}
'''

View file

@ -0,0 +1,40 @@
from glad.lang.common.loader import BaseLoader
# TODO this is just a quick initial conversion of the D loader
_EGL_LOADER = '''
bool gladLoadEGL() {
return gladLoadEGL(x => eglGetProcAddress(x))
}
'''
_EGL_HAS_EXT = '''
private bool has_ext(const(char)* ext) @nogc {
return true
}
'''
class EGLNimLoader(BaseLoader):
def write_header_end(self, fobj):
pass
def write_header(self, fobj):
pass
def write(self, fobj):
if not self.disabled:
fobj.write(_EGL_LOADER)
def write_begin_load(self, fobj):
pass
def write_end_load(self, fobj):
fobj.write(' return true\n')
def write_find_core(self, fobj):
pass
def write_has_ext(self, fobj):
fobj.write(_EGL_HAS_EXT)

View file

@ -0,0 +1,147 @@
from glad.lang.common.loader import BaseLoader
from glad.lang.nim.loader import LOAD_OPENGL_DLL
_OPENGL_LOADER = \
LOAD_OPENGL_DLL % {'pre':'private', 'init':'open_gl',
'proc':'get_proc', 'terminate':'close_gl'} + '''
bool gladLoadGL()
bool status = false
if(open_gl())
status = gladLoadGL(x => get_proc(x))
close_gl()
return status
'''
_OPENGL_HAS_EXT_LT3 = '''proc hasExt(extname: string): bool =
if extname == nil:
return false
var extensions = $cast[cstring](glGetString(GL_EXTENSIONS))
if extensions == nil:
return false
var
loc, terminatorLoc: int
terminator: char
while true:
loc = extensions.find(extname)
if loc < 0:
return false
terminatorLoc = loc + extname.len
terminator = extensions[terminatorLoc]
if (loc == 0 or extensions[loc - 1] == ' ') and
(terminator == ' ' or terminator == '\\0'):
return true
extensions = extensions[terminatorLoc..^1]
'''
_OPENGL_HAS_EXT_GTE3 = '''proc hasExt(extname: string): bool =
if extname == nil:
return false
if glVersionMajor < 3:
var extensions = $cast[cstring](glGetString(GL_EXTENSIONS))
if extensions == nil:
return false
var
loc, terminatorLoc: int
terminator: char
while true:
loc = extensions.find(extname)
if loc < 0:
return false
terminatorLoc = loc + extname.len
terminator = extensions[terminatorLoc]
if (loc == 0 or extensions[loc - 1] == ' ') and
(terminator == ' ' or terminator == '\\0'):
return true
extensions = extensions[terminatorLoc..^1]
else:
var
num: GLint
s: cstring
glGetIntegerv(GL_NUM_EXTENSIONS, num.addr)
for i in 0..num-1:
s = cast[cstring](glGetStringi(GL_EXTENSIONS, GLuint(i)))
if s == extname:
return true
'''
_FIND_VERSION = ''' # Thank you @elmindreda
# https://github.com/elmindreda/greg/blob/master/templates/greg.c.in#L176
# https://github.com/glfw/glfw/blob/master/src/context.c#L36
var prefixes = ["OpenGL ES-CM ", "OpenGL ES-CL ", "OpenGL ES "]
var version = glVersion
for p in prefixes:
if version.startsWith(p):
version = version.replace(p)
break
var major = ord(glVersion[0]) - ord('0')
var minor = ord(glVersion[2]) - ord('0')
glVersionMajor = major
glVersionMinor = minor
'''
_BEGIN_LOAD = ''' glGetString = cast[proc (name: GLenum): ptr GLubyte {.cdecl.}](load("glGetString"))
if glGetString == nil: return false
var glVersion = cast[cstring](glGetString(GL_VERSION))
if glVersion == nil: return false
'''
class OpenGLNimLoader(BaseLoader):
def write_header_end(self, fobj):
pass
def write_header(self, fobj):
pass
def write(self, fobj):
pass
# TODO
# if not self.disabled and 'gl' in self.apis:
# fobj.write(_OPENGL_LOADER)
def write_begin_load(self, fobj):
fobj.write(_BEGIN_LOAD)
def write_end_load(self, fobj):
fobj.write('\n return glVersionMajor != 0 or glVersionMinor != 0\n')
def write_find_core(self, fobj):
fobj.write(_FIND_VERSION)
def write_has_ext(self, fobj, apiversion):
if apiversion.major == 1 and apiversion.minor == 0:
return
if apiversion.major < 3:
fobj.write(_OPENGL_HAS_EXT_LT3)
else:
fobj.write(_OPENGL_HAS_EXT_GTE3)

View file

@ -0,0 +1,51 @@
from glad.lang.common.loader import BaseLoader
from glad.lang.nim.loader import LOAD_OPENGL_DLL
# TODO this is just a quick initial conversion of the D loader
_GLX_LOADER = \
LOAD_OPENGL_DLL % {'pre':'private', 'init':'open_gl',
'proc':'get_proc', 'terminate':'close_gl'} + '''
bool gladLoadGLX() {
bool status = false
if(open_gl()) {
status = gladLoadGLX(x => get_proc(x))
close_gl()
}
return status
}
'''
_GLX_HAS_EXT = '''
private bool has_ext(const(char)* name) @nogc {
return true
}
'''
class GLXNimLoader(BaseLoader):
def write_header_end(self, fobj):
pass
def write_header(self, fobj):
pass
def write(self, fobj):
fobj.write('alias Loader = void* delegate(const(char)*)\n')
if not self.disabled:
fobj.write(_GLX_LOADER)
def write_begin_load(self, fobj):
pass
def write_end_load(self, fobj):
fobj.write(' return true\n')
def write_find_core(self, fobj):
pass
def write_has_ext(self, fobj):
fobj.write(_GLX_HAS_EXT)

View file

@ -0,0 +1,38 @@
from glad.lang.common.loader import BaseLoader
from glad.lang.nim.loader.glx import _GLX_LOADER
# TODO this is just a quick initial conversion of the D loader
_WGL_LOADER = _GLX_LOADER.replace('GLX', 'WGL')
_WGL_HAS_EXT = '''
private bool has_ext(const(char)* name) @nogc {
return true;
}
'''
class WGLNimLoader(BaseLoader):
def write_header_end(self, fobj):
pass
def write_header(self, fobj):
pass
def write(self, fobj):
fobj.write('alias Loader = void* delegate(const(char)*);\n')
if not self.disabled:
fobj.write(_WGL_LOADER)
def write_begin_load(self, fobj):
pass
def write_end_load(self, fobj):
fobj.write(' return true\n')
def write_find_core(self, fobj):
pass
def write_has_ext(self, fobj):
fobj.write(_WGL_HAS_EXT)

View file

@ -0,0 +1,25 @@
from glad.lang.volt.loader.egl import EGLVoltLoader
from glad.lang.volt.loader.gl import OpenGLVoltLoader
from glad.lang.volt.loader.glx import GLXVoltLoader
from glad.lang.volt.loader.wgl import WGLVoltLoader
from glad.lang.volt.generator import VoltGenerator
_specs = {
'egl': EGLVoltLoader,
'gl': OpenGLVoltLoader,
'glx': GLXVoltLoader,
'wgl': WGLVoltLoader
}
_generators = {
'volt': VoltGenerator,
}
def get_generator(name, spec):
gen = _generators.get(name)
loader = _specs.get(spec)
return gen, loader

View file

@ -0,0 +1,86 @@
import sys
from glad.lang.d.generator import DGenerator
if sys.version_info >= (3, 0):
basestring = str
class VoltGenerator(DGenerator):
NAME = 'volt'
NAME_LONG = 'Volt'
MODULE = 'amp'
LOADER = 'loader'
ENUMS = 'enums'
EXT = 'ext'
FUNCS = 'funcs'
TYPES = 'types'
FILE_EXTENSION = '.volt'
API = ''
LOAD_GL_NAME = 'load'
@property
def PACKAGE(self):
return 'package'
def write_module(self, fobj, name):
if name == 'package':
fobj.write('module {}.{};\n\n'.format(self.MODULE, self.spec.NAME))
else:
DGenerator.write_module(self, fobj, name)
def write_prototype_pre(self, fobj):
fobj.write('extern(System) @loadDynamic {\n')
def write_prototype_post(self, fobj):
fobj.write('}\n')
def write_function_pre(self, fobj):
pass
def write_function_post(self, fobj):
pass
def write_shared(self, fobj):
fobj.write('global {\n')
def write_shared_end(self, fobj):
fobj.write('}\n')
def write_function(self, fobj, func):
pass
def write_function_prototype(self, fobj, func):
fobj.write('{} {}('
.format(func.proto.ret.to_volt(), func.proto.name))
fobj.write(', '.join(param.type.to_volt() for param in func.params))
fobj.write(');\n')
def write_boolean(self, fobj, name, **kwargs):
fobj.write('global bool {};\n'.format(name))
def write_enum(self, fobj, name, value, type_='uint'):
if isinstance(value, basestring):
if value.startswith('0x') and type_.startswith('u'):
value += 'U'
if len(value) > 12 and type_.startswith('u'):
value += 'L'
try:
v = int(value)
if v < 0:
type_ = 'int'
except ValueError:
pass
if isinstance(value, basestring) and '"' in value:
type_ = 'const(char)*'
fobj.write('enum {} {} = {};\n'.format(type_, name, value))
def write_opaque_struct(self, fobj, name):
fobj.write('struct _{name} {{}}\nalias {name} = _{name}*;\n'.format(name=name))

View file

@ -0,0 +1,64 @@
LOAD_OPENGL_DLL = '''
private global Library libGL;
extern(System) private alias gladGetProcAddressPtrType = void* function(const(char)*);
private global gladGetProcAddressPtrType gladGetProcAddressPtr;
%(pre)s
bool %(init)s() {
version(Windows) {
libGL = Library.load("opengl32.dll");
} else version(OSX) {
libGL = Library.loads([
"../Frameworks/OpenGL.framework/OpenGL",
"/Library/Frameworks/OpenGL.framework/OpenGL",
"/System/Library/Frameworks/OpenGL.framework/OpenGL",
"/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL"
]);
} else {
libGL = Library.loads(["libGL.so.1", "libGL.so"]);
}
if(libGL !is null) {
version(Windows) {
string sym = "wglGetProcAddress";
} else {
string sym = "glXGetProcAddressARB";
}
// returns null on OSX, but that's fine
gladGetProcAddressPtr = cast(typeof(gladGetProcAddressPtr))libGL.symbol(sym);
return true;
}
return false;
}
private struct StructToDg {
void* instance;
void* func;
}
%(pre)s
void* %(proc)s(string name) {
if(libGL is null) return null;
void* result;
if(gladGetProcAddressPtr !is null) {
// TODO: name.ptr
result = gladGetProcAddressPtr(name.ptr);
}
if(result is null) {
result = libGL.symbol(name);
}
return result;
}
%(pre)s
void %(terminate)s() {
if(libGL !is null) {
libGL.free();
}
return;
}
'''

View file

@ -0,0 +1,48 @@
from glad.lang.common.loader import BaseLoader
from glad.lang.d.loader.egl import _EGL_HAS_EXT as _D_EGL_HAS_EXT
_EGL_LOADER = '''
private struct StructToDg {
void* instance;
void* func;
}
private void* get_proc(string name) {
return eglGetProcAddress(arg.ptr);
}
bool gladLoadEGL() {
StructToDg structToDg;
structToDg.func = cast(void*)get_proc;
auto dg = *cast(Loader*)&structToDg;
return gladLoadEGL(dg);
}
'''
_EGL_HAS_EXT = _D_EGL_HAS_EXT
class EGLVoltLoader(BaseLoader):
def write_header_end(self, fobj):
pass
def write_header(self, fobj):
pass
def write(self, fobj):
fobj.write('import watt.library;\n')
if not self.disabled:
fobj.write(_EGL_LOADER)
def write_begin_load(self, fobj):
pass
def write_end_load(self, fobj):
fobj.write('\treturn true;')
def write_find_core(self, fobj):
pass
def write_has_ext(self, fobj):
fobj.write(_EGL_HAS_EXT)

View file

@ -0,0 +1,60 @@
from glad.lang.common.loader import BaseLoader
from glad.lang.volt.loader import LOAD_OPENGL_DLL
from glad.lang.d.loader.gl import _OPENGL_HAS_EXT as _D_OPENGL_HAS_EXT
_OPENGL_LOADER = \
LOAD_OPENGL_DLL % {'pre':'private', 'init':'open_gl',
'proc':'get_proc', 'terminate':'close_gl'} + '''
bool gladLoadGL() {
StructToDg structToDg;
structToDg.func = cast(void*)get_proc;
auto dg = *cast(Loader*)&structToDg;
bool status = false;
if(open_gl()) {
status = gladLoadGL(dg);
close_gl();
}
return status;
}
'''
_OPENGL_HAS_EXT = (
'global int GL_MAJOR = 0;\nglobal int GL_MINOR = 0;' +
'\n'.join(l for l in _D_OPENGL_HAS_EXT.replace('@nogc', '').splitlines() if 'struct' not in l)
.replace('GLVersion.major', 'GL_MAJOR') +
'\n\n'
)
class OpenGLVoltLoader(BaseLoader):
def write_header_end(self, fobj):
pass
def write_header(self, fobj):
pass
def write(self, fobj):
fobj.write('import watt.library;\n')
if not self.disabled and 'gl' in self.apis:
fobj.write(_OPENGL_LOADER)
def write_begin_load(self, fobj):
fobj.write('\tglGetString = cast(typeof(glGetString))load("glGetString");\n')
fobj.write('\tif(glGetString is null) { return false; }\n')
fobj.write('\tif(glGetString(GL_VERSION) is null) { return false; }\n\n')
def write_end_load(self, fobj):
fobj.write('\treturn GL_MAJOR != 0 || GL_MINOR != 0;\n')
def write_find_core(self, fobj):
fobj.write('\tconst(char)* v = cast(const(char)*)glGetString(GL_VERSION);\n')
fobj.write('\tint major = v[0] - \'0\';\n')
fobj.write('\tint minor = v[2] - \'0\';\n')
fobj.write('\tGL_MAJOR = major; GL_MINOR = minor;\n')
def write_has_ext(self, fobj):
fobj.write(_OPENGL_HAS_EXT)

View file

@ -0,0 +1,47 @@
from glad.lang.common.loader import BaseLoader
from glad.lang.volt.loader import LOAD_OPENGL_DLL
_GLX_LOADER = \
LOAD_OPENGL_DLL % {'pre':'private', 'init':'open_gl',
'proc':'get_proc', 'terminate':'close_gl'} + '''
bool gladLoadGLX() {
StructToDg structToDg;
structToDg.func = cast(void*)get_proc;
auto dg = *cast(Loader*)&structToDg;
bool status = false;
if(open_gl()) {
status = gladLoadGLX(dg);
close_gl();
}
return status;
}
'''
_GLX_HAS_EXT = '''
private bool has_ext(const(char)* name) {
return true;
}
'''
class GLXVoltLoader(BaseLoader):
def write(self, fobj):
fobj.write('import watt.library;\n')
if not self.disabled:
fobj.write(_GLX_LOADER)
def write_begin_load(self, fobj):
pass
def write_end_load(self, fobj):
fobj.write('\treturn true;\n')
def write_find_core(self, fobj):
pass
def write_has_ext(self, fobj):
fobj.write(_GLX_HAS_EXT)

View file

@ -0,0 +1,35 @@
from glad.lang.common.loader import BaseLoader
from glad.lang.volt.loader.glx import _GLX_LOADER
_WGL_LOADER = _GLX_LOADER.replace('GLX', 'WGL')
_WGL_HAS_EXT = '''
private bool has_ext(const(char)* name) {
return true;
}
'''
class WGLVoltLoader(BaseLoader):
def write_header_end(self, fobj):
pass
def write_header(self, fobj):
pass
def write(self, fobj):
fobj.write('import watt.library;\n')
if not self.disabled:
fobj.write(_WGL_LOADER)
def write_begin_load(self, fobj):
pass
def write_end_load(self, fobj):
fobj.write('\treturn true;\n')
def write_find_core(self, fobj):
pass
def write_has_ext(self, fobj):
fobj.write(_WGL_HAS_EXT)

View file

@ -0,0 +1,112 @@
from contextlib import closing
import logging
import sys
if sys.version_info >= (3, 0):
_is_py3 = True
from urllib.request import build_opener, ContentTooShortError
else:
_is_py3 = False
from urllib2 import build_opener
from urllib import FancyURLopener
logger = logging.getLogger('glad.opener')
def build_urllib_opener(user_agent, *args, **kwargs):
if _is_py3:
return None
class UrllibURLOpener(FancyURLopener):
version = user_agent
return UrllibURLOpener(*args, **kwargs)
def _urlretrieve_with_opener(opener, url, filename, data=None):
if not _is_py3:
raise SyntaxError('Only call this in Python 3 code.')
# borrowed from the original implementation at urllib.request.urlretrieve.
with closing(opener.open(url, data=data)) as src:
headers = src.info()
with open(filename, 'wb') as dest:
result = filename, headers
bs = 1024*8
size = -1
read = 0
blocknum = 0
if "content-length" in headers:
size = int(headers["Content-Length"])
while True:
block = src.read(bs)
if not block:
break
read += len(block)
dest.write(block)
blocknum += 1
if size >= 0 and read < size:
raise ContentTooShortError(
'retrieval incomplete: got only %i out of %i bytes'
% (read, size), result)
return result
class URLOpener(object):
"""
Class to download/find Khronos related files, like
the official specs and khrplatform.h.
Can also be used to download files, exists mainly because of
Python 2 and Python 3 incompatibilities.
"""
def __init__(self, user_agent='Mozilla/5.0'):
# the urllib2/urllib.request opener
self.opener = build_opener()
self.opener.addheaders = [('User-agent', user_agent)]
# the urllib opener (Python 2 only)
self.opener2 = build_urllib_opener(user_agent)
def urlopen(self, url, data=None, *args, **kwargs):
"""
Same as urllib2.urlopen or urllib.request.urlopen,
the only difference is that it links to the internal opener.
"""
logger.info('opening: \'%s\'', url)
if data is None:
return self.opener.open(url)
return self.opener.open(url, data)
def urlretrieve(self, url, filename, data=None):
"""
Similar to urllib.urlretrieve or urllib.request.urlretrieve
only that *filname* is required.
:param url: URL to download.
:param filename: Filename to save the content to.
:param data: Valid URL-encoded data.
:return: Tuple containing path and headers.
"""
logger.info('saving: \'%s\' to \'%s\'', url, filename)
if _is_py3:
return _urlretrieve_with_opener(self.opener, url, filename, data=data)
return self.opener2.retrieve(url, filename, data=data)
# just a singleton helper:
_default = None
@classmethod
def default(cls):
if cls._default is None:
cls._default = cls()
return cls._default

View file

@ -0,0 +1,356 @@
try:
from lxml import etree
from lxml.etree import ETCompatXMLParser as parser
def xml_fromstring(argument):
return etree.fromstring(argument, parser=parser())
def xml_frompath(path):
return etree.parse(path, parser=parser()).getroot()
except ImportError:
try:
import xml.etree.cElementTree as etree
except ImportError:
import xml.etree.ElementTree as etree
def xml_fromstring(argument):
return etree.fromstring(argument)
def xml_frompath(path):
return etree.parse(path).getroot()
from collections import defaultdict, OrderedDict
from contextlib import closing
from itertools import chain
import re
from glad.opener import URLOpener
_ARRAY_RE = re.compile(r'\[\d*\]')
class Spec(object):
API = 'https://cvs.khronos.org/svn/repos/ogl/trunk/doc/registry/public/api/'
NAME = ''
def __init__(self, root):
self.root = root
self._types = None
self._groups = None
self._enums = None
self._commands = None
self._features = None
self._extensions = None
@classmethod
def from_url(cls, url, opener=None):
if opener is None:
opener = URLOpener.default()
with closing(opener.urlopen(url)) as f:
raw = f.read()
return cls(xml_fromstring(raw))
@classmethod
def from_svn(cls, opener=None):
return cls.from_url(cls.API + cls.NAME + '.xml', opener=opener)
@classmethod
def fromstring(cls, string):
return cls(xml_fromstring(string))
@classmethod
def from_file(cls, path):
return cls(xml_frompath(path))
@property
def comment(self):
return self.root.find('comment').text
@property
def types(self):
if self._types is None:
self._types = [Type(element) for element in
self.root.find('types').iter('type')]
return self._types
@property
def groups(self):
if self._groups is None:
self._groups = dict([(element.attrib['name'], Group(element))
for element in self.root.find('groups')])
return self._groups
@property
def commands(self):
if self._commands is None:
self._commands = dict([(element.find('proto').find('name').text,
Command(element, self))
for element in self.root.find('commands')])
return self._commands
@property
def enums(self):
if self._enums is not None:
return self._enums
self._enums = dict()
for element in self.root.iter('enums'):
namespace = element.attrib['namespace']
type_ = element.get('type')
group = element.get('group')
vendor = element.get('vendor')
comment = element.get('comment', '')
for enum in element:
if enum.tag == 'unused':
continue
assert enum.tag == 'enum'
name = enum.attrib['name']
self._enums[name] = Enum(name, enum.attrib['value'], namespace,
type_, group, vendor, comment)
return self._enums
@property
def features(self):
if self._features is not None:
return self._features
self._features = defaultdict(OrderedDict)
for element in self.root.iter('feature'):
num = tuple(map(int, element.attrib['number'].split('.')))
self._features[element.attrib['api']][num] = Feature(element, self)
return self._features
@property
def extensions(self):
if self._extensions is not None:
return self._extensions
self._extensions = defaultdict(dict)
for element in self.root.find('extensions'):
for api in element.attrib['supported'].split('|'):
self._extensions[api][element.attrib['name']] = Extension(element, self)
return self._extensions
class Type(object):
def __init__(self, element):
apientry = element.find('apientry')
if apientry is not None:
apientry.text = 'APIENTRY'
self.raw = ''.join(element.itertext())
self.api = element.get('api')
self.name = element.get('name') or element.find('name').text
@property
def is_preprocessor(self):
return '#' in self.raw
class Group(object):
def __init__(self, element):
self.name = element.attrib['name']
self.enums = [enum.attrib['name'] for enum in element]
class Enum(object):
def __init__(self, name, value, namespace, type_=None,
group=None, vendor=None, comment=''):
self.name = name
self.value = value
self.namespace = namespace
self.type = type_
self.group = group
self.vendor = vendor
self.comment = comment
def __hash__(self):
return hash(self.name)
def __str__(self):
return self.name
__repr__ = __str__
class Command(object):
def __init__(self, element, spec):
self.proto = Proto(element.find('proto'))
self.params = [Param(ele, spec) for ele in element.iter('param')]
def __hash__(self):
return hash(self.proto.name)
def __str__(self):
return '{self.proto.name}'.format(self=self)
__repr__ = __str__
class Proto(object):
def __init__(self, element):
self.name = element.find('name').text
self.ret = OGLType(element)
def __str__(self):
return '{self.ret} {self.name}'.format(self=self)
class Param(object):
def __init__(self, element, spec):
self.group = element.get('group')
self.type = OGLType(element)
self.name = element.find('name').text.strip('*')
def __str__(self):
return '{0!r} {1}'.format(self.type, self.name)
class OGLType(object):
def __init__(self, element):
self.element = element
self.raw = ''.join(element.itertext()).strip()
self.name = element.find('name').text
self.type = (self.raw.replace('const', '').replace('unsigned', '')
.replace('struct', '').strip().split(None, 1)[0]
if element.find('ptype') is None else element.find('ptype').text)
# 0 if no pointer, 1 if *, 2 if **
self.is_pointer = 0 if self.raw is None else self.raw.count('*')
# it can be a pointer to an array, or just an array
self.is_pointer += len(_ARRAY_RE.findall(self.raw))
self.is_const = False if self.raw is None else 'const' in self.raw
self.is_unsigned = False if self.raw is None else 'unsigned' in self.raw
if 'struct' in self.raw and 'struct' not in self.type:
self.type = 'struct {}'.format(self.type)
ptype = element.find('ptype')
self.ptype = ptype.text if ptype is not None else None
def to_d(self):
if self.is_pointer > 1 and self.is_const:
s = 'const({}{}*)'.format('u' if self.is_unsigned else '', self.type)
s += '*' * (self.is_pointer - 1)
else:
t = '{}{}'.format('u' if self.is_unsigned else '', self.type)
s = 'const({})'.format(t) if self.is_const else t
s += '*' * self.is_pointer
return s.replace('struct ', '')
to_volt = to_d
def to_c(self):
result = ''
for text in self.element.itertext():
if text == self.name:
# yup * is sometimes part of the name
result += '*' * text.count('*')
else:
result += text
result = _ARRAY_RE.sub('*', result)
return result.strip()
NIM_POINTER_MAP = {
'void': 'pointer',
'GLchar': 'cstring',
'struct _cl_context': 'ClContext',
'struct _cl_event': 'ClEvent'
}
def to_nim(self):
if self.is_pointer == 2:
s = 'cstringArray' if self.type == 'GLchar' else 'ptr pointer'
else:
s = self.type
if self.is_pointer == 1:
default = 'ptr ' + s
s = self.NIM_POINTER_MAP.get(s, default)
return s
__str__ = to_d
__repr__ = __str__
class Extension(object):
def __init__(self, element, spec):
self.name = element.attrib['name']
self.require = []
for required in chain.from_iterable(element.findall('require')):
if required.tag == 'type':
continue
data = {'enum': spec.enums, 'command': spec.commands}[required.tag]
try:
self.require.append(data[required.attrib['name']])
except KeyError:
pass # TODO
@property
def enums(self):
for r in self.require:
if isinstance(r, Enum):
yield r
@property
def functions(self):
for r in self.require:
if isinstance(r, Command):
yield r
def __hash__(self):
return hash(self.name)
def __str__(self):
return self.name
__repr__ = __str__
class Feature(Extension):
def __init__(self, element, spec):
Extension.__init__(self, element, spec)
self.spec = spec
# not every spec has a ._remove member, but there shouldn't be a remove
# tag without that member, if there is, blame me!
for removed in chain.from_iterable(element.findall('remove')):
if removed.tag == 'type':
continue
data = {'enum': spec.enums, 'command': spec.commands}[removed.tag]
try:
spec._remove.add(data[removed.attrib['name']])
except KeyError:
pass # TODO
self.number = tuple(map(int, element.attrib['number'].split('.')))
self.api = element.attrib['api']
def __str__(self):
return '{self.name}@{self.number!r}'.format(self=self)
@property
def enums(self):
for enum in super(Feature, self).enums:
if enum not in getattr(self.spec, 'removed', []):
yield enum
@property
def functions(self):
for func in super(Feature, self).functions:
if func not in getattr(self.spec, 'removed', []):
yield func
__repr__ = __str__

View file

@ -0,0 +1,54 @@
from glad.parse import Spec
class EGLSpec(Spec):
API = 'https://raw.githubusercontent.com/KhronosGroup/EGL-Registry/master/api/'
NAME = 'egl'
class GLSpec(Spec):
API = 'https://raw.githubusercontent.com/KhronosGroup/OpenGL-Registry/master/xml/'
NAME = 'gl'
def __init__(self, root):
Spec.__init__(self, root)
self._profile = 'compatibility'
self._remove = set()
@property
def profile(self):
return self._profile
@profile.setter
def profile(self, value):
if value not in ('core', 'compatibility'):
raise ValueError('profile must either be core or compatibility')
self._profile = value
@property
def removed(self):
if self._profile == 'core':
return frozenset(self._remove)
return frozenset()
class GLXSpec(Spec):
API = 'https://raw.githubusercontent.com/KhronosGroup/OpenGL-Registry/master/xml/'
NAME = 'glx'
class WGLSpec(Spec):
API = 'https://raw.githubusercontent.com/KhronosGroup/OpenGL-Registry/master/xml/'
NAME = 'wgl'
SPECS = dict()
# reflection to fill SPECS
import sys
import inspect
for name, cls in inspect.getmembers(sys.modules[__name__], inspect.isclass):
if issubclass(cls, Spec):
SPECS[cls.NAME] = cls

View file

@ -0,0 +1,14 @@
_API_NAMES = {
'egl': 'EGL',
'gl': 'OpenGL',
'gles1': 'OpenGL ES',
'gles2': 'OpenGL ES',
'glx': 'GLX',
'wgl': 'WGL',
}
def api_name(api):
api = api.lower()
return _API_NAMES[api]

9
tools/glad-0.1.14a0/main.py Executable file
View file

@ -0,0 +1,9 @@
from glad.__main__ import main
import warnings
warnings.simplefilter('always', DeprecationWarning)
_message = 'main.py is deprecated, use "python -m glad" instead ' \
'or install glad via pip, see README.md for more information.'
warnings.warn(_message, DeprecationWarning, stacklevel=1)
main()

View file

@ -0,0 +1,65 @@
#!/usr/bin/env python
"""
Glad
----
Glad uses the official Khronos-XML specs to generate a
GL/GLES/EGL/GLX/WGL Loader made for your needs.
Checkout the GitHub repository: https://github.com/Dav1dde/glad
"""
from setuptools import setup, find_packages
import ast
import re
# Thanks flask: https://github.com/mitsuhiko/flask/blob/master/setup.py
_version_re = re.compile(r'__version__\s+=\s+(.*)')
with open('glad/__init__.py', 'rb') as f:
version = str(ast.literal_eval(_version_re.search(
f.read().decode('utf-8')).group(1)))
if __name__ == '__main__':
setup(
name='glad',
version=version,
description='Multi-Language GL/GLES/EGL/GLX/WGL Loader-Generator based on the official specs.',
long_description=__doc__,
packages=find_packages(),
install_requires=[],
entry_points={
'console_scripts': [
'glad = glad.__main__:main'
]
},
classifiers=[
'Development Status :: 5 - Production/Stable',
'Environment :: Console',
'Intended Audience :: Developers',
'Intended Audience :: Education',
'Intended Audience :: Science/Research',
'License :: OSI Approved :: MIT License',
'Natural Language :: English',
'Operating System :: OS Independent',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Topic :: Games/Entertainment',
'Topic :: Multimedia :: Graphics',
'Topic :: Multimedia :: Graphics :: 3D Rendering',
'Topic :: Software Development',
'Topic :: Software Development :: Build Tools',
'Topic :: Utilities'
],
keywords='opengl glad generator gl wgl egl gles glx',
author='David Herberth',
author_email='admin@dav1d.de',
url='https://github.com/Dav1dde/glad',
license='MIT',
platforms='any'
)

View file

@ -0,0 +1,156 @@
#!/bin/bash -xe
if [ -z ${PYTHON+x} ]; then
PYTHON="/usr/bin/env python"
fi
echo "Using python \"$PYTHON\""
if [ "$1" != "no-download" ]; then
./utility/download.sh
fi
GCC_FLAGS="-o build/tmp.o -Wall -Wextra -Wsign-conversion -Wcast-qual -Werror -ansi -c"
GPP_FLAGS="-o build/tmp.o -Wall -Wextra -Wsign-conversion -Wcast-qual -Werror -c"
function mingwc_compile {
i686-w64-mingw32-gcc $@
x86_64-w64-mingw32-gcc $@
}
function c_compile {
gcc $@ -ldl
mingwc_compile $@
}
function mingwcpp_compile {
i686-w64-mingw32-g++ $@
x86_64-w64-mingw32-g++ $@
}
function cpp_compile {
g++ $@ -ldl
mingwcpp_compile $@
}
function download_if_required {
if [ ! -f $1 ]; then
mkdir -p $(dirname "${1}")
filename=$(basename "${1}")
if [ ! -f ${filename} ]; then
wget -O ${filename} $2
fi
cp ${filename} $1
fi
}
# C
echo -e "====================== Generating and compiling C/C++: ======================"
function c_egl {
rm -rf build
${PYTHON} -m glad --spec=egl --out-path=build $@
download_if_required build/include/EGL/eglplatform.h "https://raw.githubusercontent.com/KhronosGroup/EGL-Registry/master/api/EGL/eglplatform.h"
download_if_required build/include/KHR/khrplatform.h "https://raw.githubusercontent.com/KhronosGroup/EGL-Registry/master/api/KHR/khrplatform.h"
c_compile -Ibuild/include build/src/glad_egl.c ${GCC_FLAGS}
cpp_compile -Ibuild/include build/src/glad_egl.c ${GPP_FLAGS}
}
function c_gl {
rm -rf build
${PYTHON} -m glad --spec=gl --out-path=build $@
c_compile -Ibuild/include build/src/glad.c ${GCC_FLAGS}
cpp_compile -Ibuild/include build/src/glad.c ${GPP_FLAGS}
}
function c_glx {
rm -rf build
${PYTHON} -m glad --spec=gl --out-path=build $@
${PYTHON} -m glad --spec=glx --out-path=build $@
gcc -Ibuild/include build/src/glad_glx.c ${GCC_FLAGS}
g++ -Ibuild/include build/src/glad_glx.c ${GPP_FLAGS}
}
function c_wgl {
rm -rf build
${PYTHON} -m glad --spec=gl --out-path=build $1
${PYTHON} -m glad --spec=wgl --out-path=build $@
mingwc_compile -Ibuild/include build/src/glad_wgl.c ${GCC_FLAGS}
mingwcpp_compile -Ibuild/include build/src/glad_wgl.c ${GPP_FLAGS}
}
function c_example {
${PYTHON} -m glad --spec=gl --out-path=build $@
gcc example/c/simple.c -o build/simple -Ibuild/include build/src/glad.c -lglut -ldl
mingwc_compile example/c/simple.c -o build/simple -Ibuild/include build/src/glad.c -lfreeglut
g++ example/c++/hellowindow2.cpp -o build/hellowindow2 -Ibuild/include build/src/glad.c -lglfw -ldl
mingwcpp_compile example/c++/hellowindow2.cpp -o build/hellowindow2 -Ibuild/include build/src/glad.c -lglfw3 -luser32 -lgdi32
}
c_egl --generator=c
c_egl --generator=c --extensions=
c_glx --generator=c
c_glx --generator=c --extensions=
c_wgl --generator=c
c_wgl --generator=c --extensions=WGL_ARB_extensions_string,WGL_EXT_extensions_string
c_example --generator=c
c_example --generator=c --extensions=
# C-Debug
echo -e "====================== Generating and compiling C/C++ Debug: ======================"
c_egl --generator=c-debug
c_egl --generator=c-debug --extensions=
c_glx --generator=c-debug
c_glx --generator=c-debug --extensions=
c_wgl --generator=c-debug
c_wgl --generator=c-debug --extensions=WGL_ARB_extensions_string,WGL_EXT_extensions_string
c_example --generator=c-debug
c_example --generator=c-debug --extensions=
# D
echo -e "\n====================== Generating and compiling D: ======================"
rm -rf build
${PYTHON} -m glad --generator=d --spec=egl --out-path=build
dmd -o- build/glad/egl/*.d -c
rm -rf build
${PYTHON} -m glad --generator=d --spec=gl --api="gl=,gles1=,gles2=" --out-path=build
dmd -o- build/glad/gl/*.d -c
rm -rf build
${PYTHON} -m glad --generator=d --spec=gl --out-path=build
${PYTHON} -m glad --generator=d --spec=glx --out-path=build
dmd -o- build/glad/glx/*.d -c
rm -rf build
${PYTHON} -m glad --generator=d --spec=gl --out-path=build
${PYTHON} -m glad --generator=d --spec=wgl --out-path=build
dmd -o- build/glad/wgl/*.d -c
# Volt TODO
echo -e "\n====================== Generating Volt: ======================"
rm -rf build
${PYTHON} -m glad --generator=volt --spec=egl --out-path=build
${PYTHON} -m glad --generator=volt --spec=gl --out-path=build
${PYTHON} -m glad --generator=volt --spec=glx --out-path=build
${PYTHON} -m glad --generator=volt --spec=wgl --out-path=build
rm -rf build

View file

@ -0,0 +1,18 @@
#!/usr/bin/env bash
set -e
rm -f egl.xml
wget -O egl.xml https://raw.githubusercontent.com/KhronosGroup/EGL-Registry/master/api/egl.xml
rm -f gl.xml
wget -O gl.xml https://raw.githubusercontent.com/KhronosGroup/OpenGL-Registry/master/xml/gl.xml
rm -f glx.xml
wget -O glx.xml https://raw.githubusercontent.com/KhronosGroup/OpenGL-Registry/master/xml/glx.xml
rm -f wgl.xml
wget -O wgl.xml https://raw.githubusercontent.com/KhronosGroup/OpenGL-Registry/master/xml/wgl.xml
rm -f khrplatform.h
wget -O khrplatform.h https://raw.githubusercontent.com/KhronosGroup/EGL-Registry/master/api/KHR/khrplatform.h

View file

@ -0,0 +1,31 @@
#!/usr/bin/env bash
set -e
if [ -z ${PYTHON+x} ]; then
PYTHON="/usr/bin/env python"
fi
echo "Using python \"$PYTHON\""
if [ "$1" != "no-download" ]; then
./utility/download.sh
fi
rm -rf build
echo "Generating C"
$PYTHON -m glad --out-path=build --spec=egl --generator=c
$PYTHON -m glad --out-path=build --spec=gl --api="gl=,gles1=,gles2=" --generator=c
$PYTHON -m glad --out-path=build --spec=glx --generator=c
$PYTHON -m glad --out-path=build --spec=wgl --generator=c
echo "Generating D"
$PYTHON -m glad --out-path=build --spec=egl --generator=d
$PYTHON -m glad --out-path=build --spec=gl --api="gl=,gles1=,gles2=" --generator=d
$PYTHON -m glad --out-path=build --spec=glx --generator=d
$PYTHON -m glad --out-path=build --spec=wgl --generator=d
echo "Generating Volt"
$PYTHON -m glad --out-path=build --spec=egl --generator=volt
$PYTHON -m glad --out-path=build --spec=gl --api="gl=,gles1=,gles2=" --generator=volt
$PYTHON -m glad --out-path=build --spec=glx --generator=volt
$PYTHON -m glad --out-path=build --spec=wgl --generator=volt

View file

@ -0,0 +1,35 @@
#!/usr/bin/env bash
set -e
git checkout master
./utility/generateall.sh
echo "Updating C"
git checkout c
git rm -rf include
git rm -rf src
mv build/include include/
mv build/src src/
git add --all include
git add --all src
git commit -am "automatically updated"
git push origin c:c
echo "Updating D"
git checkout d
git rm -rf glad
mv build/glad glad/
git add --all glad
git commit -am "automatically updated"
git push origin d:d
echo "Updating Volt"
git checkout volt
git rm -rf amp
mv build/amp amp/
git add --all amp
git commit -am "automatically updated"
git push origin volt:volt
git checkout master