-
Notifications
You must be signed in to change notification settings - Fork 18
/
make-GL.py
executable file
·179 lines (152 loc) · 4.38 KB
/
make-GL.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#!/usr/bin/env python3
#create GL.hpp / GL.cpp by parsing everything from glcorearb.h (why not the regsistry xml, hmmmm?) and selecting only things that are core through version 3_3.
#get glcorearb.h from https://github.com/KhronosGroup/OpenGL-Registry/raw/master/api/GL/glcorearb.h
import re
filtered = []
lookups = []
fps = []
with open('glcorearb.h', 'r') as f:
in_version = None
in_notice = False
did_notice = False
for line in f:
line = line.strip()
if line == "/*" and not did_notice:
filtered.append(line)
in_notice = True
did_notice = True
continue
if in_notice:
filtered.append(line)
if line == "*/":
in_notice = False
continue
m = re.match(r"^#define (GL_VERSION_(\d)_(\d)) 1$", line)
if m != None:
assert(in_version == None)
in_version = m.group(1)
major = int(m.group(2))
minor = int(m.group(3))
if (major,minor) <= (1,1):
filtered.append("\n// from " + in_version + ":")
mode = "all_proto"
elif (major,minor) <= (3,3):
filtered.append("\n// from " + in_version + ":")
mode = "win_pointer"
else_block = []
else:
mode = "skip"
continue
if in_version:
#check for a "#define GL_SOMETHING_SOMETHING 0xABCD" sorts of lines:
m = re.match(r"^#define", line)
if m != None:
if mode != "skip":
filtered.append(line)
continue
#check for function pointer typedef lines:
m = re.match(r"^typedef.*APIENTRYP", line)
if m != None:
#it's a function pointer typedef line
#if mode == "win_pointer":
# filtered.append(line)
continue
#check for other typedef lines:
m = re.match(r"^typedef", line)
if m != None:
if mode != "skip":
m = re.match(r"^typedef khronos_([^\s]+) ([^\s]+)$", line)
if m == None:
filtered.append(line)
else:
ty = m.group(1)
if ty == "ssize_t":
ty = "khronos_ssize_t";
elif ty == "float_t":
ty = "float";
filtered.append("typedef " + ty + " " + m.group(2))
continue
#check for function prototype lines:
m = re.match(r"GLAPI(.*)APIENTRY ([^\s]+) (.*)$", line)
if m != None:
if mode == "all_proto":
filtered.append(line)
elif mode == "win_pointer":
rt = m.group(1)
fn = m.group(2)
ag = m.group(3)
filtered.append("GLAPI" + rt + "(APIENTRYFP " + fn + ") " + ag)
fps.append(rt + "(APIENTRYFP " + fn + ") " + ag)
lookups.append("DO(" + fn + ")")
#filtered.append("extern PFNGL" + uc + "PROC gl" + lc + ";")
#filtered.append("DO(" + uc + ", " + lc + ")\n")
continue
if line == "#ifdef GL_GLEXT_PROTOTYPES":
continue
if line == "#endif":
continue
#check for version endif line:
m = re.match(r"^#endif /\* " + in_version + " \*/$", line)
if m != None:
in_version = None
continue
print("ignoring: " + line)
with open("GL.hpp", "w") as f:
print("""#pragma once
/*
*
* Function prototypes/pointers for OpenGL 3.3 core, with minimal namespace pollution.
* Call init_GL() after you have created a context.
*
* On Windows, OpenGL 1.0 & 1.1 are prototypes, the rest are pointers
* initialized by init_GL(). This is because the 1.1/1.0 entries are
* the only ones provided directly by OpenGL32.dll
*
* On Linux, all are prototypes.
*
* On MacOS, all are prototypes.
*
* This file has been automatically generated from glcorearb.h by make-GL.py
*
*/
void init_GL(); //will throw on failure.
extern "C" {
#include <stdint.h>
#ifdef _WIN32
#define APIENTRY __stdcall //see: https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types
#define APIENTRYFP APIENTRY * //these are function pointers on windows
#else
#define APIENTRY
#define APIENTRYFP
#endif
//this is how khronos_ssize_t gets defined in khrplatform.h:
#ifdef _WIN64
typedef signed long long int khronos_ssize_t;
#else
typedef signed long int khronos_ssize_t;
#endif
#define GLAPI extern
""", file=f)
print("\n".join(filtered), file=f)
print("""
}""", file=f)
with open("GL.cpp", "w") as f:
print("""#include "GL.hpp"
#include <SDL.h>
#include <iostream>
#include <stdexcept>
#ifdef _WIN32
#define DO(fn) \\
fn = (decltype(fn))SDL_GL_GetProcAddress(#fn); \\
if (!fn) { \\
throw std::runtime_error("Error binding " #fn); \\
}
#else
#define DO(fn)
#endif
void init_GL() {""", file=f)
print("\t" + "\n\t".join(lookups),file=f)
print("""}
#ifdef _WIN32""", file=f)
print("\t" + "\n\t".join(fps),file=f)
print("""#endif""", file=f)