JOGL v2.6.0-rc-20250706
JOGL, High-Performance Graphics Binding for Java™ (public API).
BuildStaticGLInfo.java
Go to the documentation of this file.
1/*
2 * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
3 * Copyright (c) 2010 JogAmp Community. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * - Redistribution of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * - Redistribution in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * Neither the name of Sun Microsystems, Inc. or the names of
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * This software is provided "AS IS," without a warranty of any kind. ALL
21 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
22 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
23 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
24 * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
25 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
26 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
27 * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
28 * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
29 * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
30 * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
31 * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
32 *
33 * You acknowledge that this software is not designed or intended for use
34 * in the design, construction, operation or maintenance of any nuclear
35 * facility.
36 *
37 * Sun gratefully acknowledges that this software was originally authored
38 * and developed by Kenneth Bradley Russell and Christopher John Kline.
39 */
40
41package com.jogamp.gluegen.opengl;
42
43import java.io.BufferedReader;
44import java.io.BufferedWriter;
45import java.io.File;
46import java.io.FileReader;
47import java.io.FileWriter;
48import java.io.IOException;
49import java.io.PrintWriter;
50import java.util.ArrayList;
51import java.util.Collections;
52import java.util.HashMap;
53import java.util.HashSet;
54import java.util.Iterator;
55import java.util.List;
56import java.util.Map;
57import java.util.Set;
58import java.util.regex.Matcher;
59import java.util.regex.Pattern;
60
61 /**
62 * Builds the StaticGLInfo class from the OpenGL header files (i.e., gl.h
63 * and glext.h) whose paths were passed as arguments to {@link
64 * #main(String[])}.
65 *
66 * It relies upon the assumption that a function's membership is scoped by
67 * preprocessor blocks in the header files that match the following pattern:
68 * <br>
69 *
70 * <pre>
71 *
72 * #ifndef GL_XXXX
73 * GLAPI <returnType> <APIENTRY|GLAPIENTRY> glFuncName(<params>)
74 * #endif GL_XXXX
75 *
76 * </pre>
77 *
78 * For example, if it parses the following data:
79 *
80 * <pre>
81 *
82 * #ifndef GL_VERSION_1_3
83 * GLAPI void APIENTRY glActiveTexture (GLenum);
84 * GLAPI void APIENTRY glMultiTexCoord1dv (GLenum, const GLdouble *);
85 * GLAPI void <APIENTRY|GLAPIENTRY> glFuncName(<params>)
86 * #endif GL_VERSION_1_3
87 *
88 * #ifndef GL_ARB_texture_compression
89 * GLAPI void APIENTRY glCompressedTexImage3DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *);
90 * GLAPI void APIENTRY glCompressedTexImage2DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *);
91 * #endif
92 *
93 * </pre>
94 *
95 * It will associate
96 * <code> glActiveTexture </code> and
97 * <code> glMultiTexCoord1dv </code>
98 * with the symbol
99 * <code> GL_VERSION_1_3 </code>,
100 * and associate
101 * <code> glCompressedTexImage2DARB </code> and
102 * <code> glCompressedTexImage3DARB </code>
103 * with the symbol
104 * <code> GL_ARB_texture_compression </code>.
105 * */
106public class BuildStaticGLInfo {
107
108 // Handles function pointer
109 protected static final int funcIdentifierGroup = 9;
110 protected static final Pattern funcPattern =
111 Pattern.compile("^(GLAPI|GL_API|GL_APICALL|EGLAPI|extern)?(\\s*)((unsigned|const)\\s+)?(\\w+)(\\s+\\*\\s*|\\s*\\*\\s+|\\s+)?(GLAPIENTRY|GL_APIENTRY|APIENTRY|EGLAPIENTRY|WINAPI)?(\\s*)([ew]?gl\\w+)\\s?(\\(.*)");
112
113 protected static final Pattern associationPattern =
114 Pattern.compile("\\#ifndef ([CEW]?GL[XU]?_[A-Za-z0-9_]+)(.*)");
115
116 protected static final Pattern ifPattern =
117 Pattern.compile("\\#if(.*)");
118 protected static final Pattern elsePattern =
119 Pattern.compile("\\#(elif|else)(.*)");
120 protected static final Pattern endifPattern =
121 Pattern.compile("\\#endif(.*)");
122
123 protected static final int defineIdentifierGroup = 1;
124 protected static final Pattern definePattern =
125 Pattern.compile("\\#define ([CEW]?GL[XU]?_[A-Za-z0-9_]+)\\s*([A-Za-z0-9_]+)(.*)");
126
127 // Maps function / #define names to Set of names of the extensions they're declared in
128 protected Map<String, Set<String>> declarationToExtensionMap = new HashMap<String, Set<String>>();
129
130 // Maps extension names to Set of identifiers (both #defines and
131 // function names) this extension declares
132 protected Map<String, Set<String>> extensionToDeclarationMap = new HashMap<String, Set<String>>();
133 protected boolean DEBUG = false;
134
135 /**
136 * The first argument is the package to which the StaticGLInfo class
137 * belongs, the second is the path to the directory in which that package's
138 * classes reside, and the remaining arguments are paths to the C header
139 * files that should be parsed
140 */
141 public static void main(final String[] args) throws IOException {
142 if (args.length > 0 && args[0].equals("-test")) {
143 final BuildStaticGLInfo builder = new BuildStaticGLInfo();
144 builder.setDebug(true);
145 final String[] newArgs = new String[args.length - 1];
146 System.arraycopy(args, 1, newArgs, 0, args.length - 1);
147 builder.parse(newArgs);
148 builder.dump();
149 System.exit(0);
150 }
151
152 final String packageName = args[0];
153 final String packageDir = args[1];
154
155 final String[] cHeaderFilePaths = new String[args.length - 2];
156 System.arraycopy(args, 2, cHeaderFilePaths, 0, cHeaderFilePaths.length);
157
158 final BuildStaticGLInfo builder = new BuildStaticGLInfo();
159 try {
160 builder.parse(cHeaderFilePaths);
161
162 final File file = new File(packageDir + File.separatorChar + "StaticGLInfo.java");
163 final String parentDir = file.getParent();
164 if (parentDir != null) {
165 final File pDirFile = new File(parentDir);
166 pDirFile.mkdirs();
167 }
168
169 final PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(file)));
170 builder.emitJavaCode(writer, packageName);
171
172 writer.flush();
173 writer.close();
174 } catch (final Exception e) {
175 final StringBuilder buf = new StringBuilder("{ ");
176 for (int i = 0; i < cHeaderFilePaths.length; ++i) {
177 buf.append(cHeaderFilePaths[i]);
178 buf.append(" ");
179 }
180 buf.append('}');
181 throw new RuntimeException(
182 "Error building StaticGLInfo.java from " + buf.toString(), e);
183 }
184 }
185
186 public void setDebug(final boolean v) {
187 DEBUG = v;
188 }
189
190 /** Parses the supplied C header files and adds the function
191 associations contained therein to the internal map. */
192 public void parse(final String[] cHeaderFilePaths) throws IOException {
193 for (int i = 0; i < cHeaderFilePaths.length; i++) {
194 parse(cHeaderFilePaths[i]);
195 }
196 }
197
198 /** Parses the supplied C header file and adds the function
199 associations contained therein to the internal map. */
200 public void parse(final String cHeaderFilePath) throws IOException {
201 final BufferedReader reader = new BufferedReader(new FileReader(cHeaderFilePath));
202 String line, activeAssociation = null;
203 Matcher m = null;
204 int block = 0;
205 while ((line = reader.readLine()) != null) {
206 int type = 0; // 1-define, 2-function
207 if ( 0 < block ) { // inside a #ifndef GL_XXX block and matching a function, if block > 0
208 String identifier = null;
209 if( 3 >= block ) { // not within sub-blocks > 3, i.e. further typedefs
210 if ((m = funcPattern.matcher(line)).matches()) {
211 identifier = m.group(funcIdentifierGroup).trim();
212 type = 2;
213 } else if ((m = definePattern.matcher(line)).matches()) {
214 identifier = m.group(defineIdentifierGroup).trim();
215 type = 1;
216 }
217 }
218 if ( identifier != null &&
219 activeAssociation != null &&
220 !identifier.equals(activeAssociation) // Handles #ifndef GL_... #define GL_...
221 )
222 {
223 addAssociation(identifier, activeAssociation);
224 if (DEBUG) {
225 System.err.println("<"+block+"> ADDING ASSOCIATION: <" + identifier + "> <" + activeAssociation + "> ; type " + type);
226 }
227 } else {
228 if ((m = ifPattern.matcher(line)).matches()) {
229 final String comment = m.group(1).trim();
230 block++;
231 if (DEBUG) {
232 System.err.println("<"+block+"> BEGIN IF BLOCK: <" + comment + ">");
233 }
234 } else if ((m = elsePattern.matcher(line)).matches()) {
235 final String comment = m.group(1).trim();
236 if (DEBUG) {
237 System.err.println("<"+block+"> ELSE BLOCK: <" + comment + ">");
238 }
239 } else if ((m = endifPattern.matcher(line)).matches()) {
240 final String comment = m.group(1).trim();
241 block--;
242 if( 0 == block ) {
243 if (DEBUG) {
244 System.err.println("<"+block+"> END ASSOCIATION BLOCK: <" + activeAssociation + " <-> " + comment + ">");
245 }
246 activeAssociation = null;
247 } else {
248 if (DEBUG) {
249 System.err.println("<"+block+"> END IF BLOCK: <" + comment + ">");
250 }
251 }
252 }
253 }
254 } else if ((m = associationPattern.matcher(line)).matches()) {
255 // found a new #ifndef GL_XXX block
256 activeAssociation = m.group(1).trim();
257 block++;
258 if (DEBUG) {
259 System.err.println("<"+block+"> BEGIN ASSOCIATION BLOCK: <" + activeAssociation + ">");
260 }
261 }
262 }
263 reader.close();
264 }
265
266 public void dump() {
267 System.err.println("BuildStaticGLInfo.dump():");
268 for (final String name : extensionToDeclarationMap.keySet()) {
269 final Set<String> decls = extensionToDeclarationMap.get(name);
270 System.err.println("<" + name + "> :");
271 final List<String> l = new ArrayList<String>();
272 l.addAll(decls);
273 Collections.sort(l);
274 for (final String str : l) {
275 System.err.println(" <" + str + ">");
276 }
277 }
278 }
279
280 public Set<String> getExtension(final String identifier) {
281 return declarationToExtensionMap.get(identifier);
282 }
283
284 public Set<String> getDeclarations(final String extension) {
285 return extensionToDeclarationMap.get(extension);
286 }
287
288 public Set<String> getExtensions() {
289 return extensionToDeclarationMap.keySet();
290 }
291
292 public void emitJavaCode(final PrintWriter output, final String packageName) {
293 output.println("package " + packageName + ";");
294 output.println();
295 output.println("import java.util.*;");
296 output.println();
297 output.println("public final class StaticGLInfo");
298 output.println("{");
299
300 output.println(" // maps function names to the extension string or OpenGL");
301 output.println(" // specification version string to which they correspond.");
302 output.println(" private static HashMap funcToAssocMap;");
303 output.println();
304
305 output.println(" /**");
306 output.println(" * Returns the OpenGL extension string or GL_VERSION string with which the");
307 output.println(" * given function is associated. <P>");
308 output.println(" *");
309 output.println(" * If the");
310 output.println(" * function is part of the OpenGL core, the returned value will be");
311 output.println(" * GL_VERSION_XXX where XXX represents the OpenGL version of which the");
312 output.println(" * function is a member (XXX will be of the form \"A\" or \"A_B\" or \"A_B_C\";");
313 output.println(" * e.g., GL_VERSION_1_2_1 for OpenGL version 1.2.1).");
314 output.println(" *");
315 output.println(" * If the function is an extension function, the returned value will the");
316 output.println(" * OpenGL extension string for the extension to which the function");
317 output.println(" * corresponds. For example, if glLoadTransposeMatrixfARB is the argument,");
318 output.println(" * GL_ARB_transpose_matrix will be the value returned.");
319 output.println(" * Please see http://oss.sgi.com/projects/ogl-sample/registry/index.html for");
320 output.println(" * a list of extension names and the functions they expose.");
321 output.println(" *");
322 output.println(" * If the function specified is not part of any known OpenGL core version or");
323 output.println(" * extension, then NULL will be returned.");
324 output.println(" */");
325 output.println(" public static String getFunctionAssociation(String glFunctionName)");
326 output.println(" {");
327 output.println(" String mappedName = null;");
328 output.println(" int funcNamePermNum = com.jogamp.gluegen.runtime.opengl.GLNameResolver.getFuncNamePermutationNumber(glFunctionName);");
329 output.println(" for(int i = 0; null==mappedName && i < funcNamePermNum; i++) {");
330 output.println(" String tmp = com.jogamp.gluegen.runtime.opengl.GLNameResolver.getFuncNamePermutation(glFunctionName, i);");
331 output.println(" try {");
332 output.println(" mappedName = (String)funcToAssocMap.get(tmp);");
333 output.println(" } catch (Exception e) { }");
334 output.println(" }");
335 output.println(" return mappedName;");
336 output.println(" }");
337 output.println();
338
339 output.println(" static");
340 output.println(" {");
341
342 // Compute max capacity
343 int maxCapacity = 0;
344 for (final String name : declarationToExtensionMap.keySet()) {
345 if (!name.startsWith("GL")) {
346 ++maxCapacity;
347 }
348 }
349
350 output.println(" funcToAssocMap = new HashMap(" + maxCapacity + "); // approximate max capacity");
351 output.println(" String group;");
352 final ArrayList<String> sets = new ArrayList<String>(extensionToDeclarationMap.keySet());
353 Collections.sort(sets);
354 for (final String groupName : sets) {
355 final Set<String> funcs = extensionToDeclarationMap.get(groupName);
356 final List<String> l = new ArrayList<String>();
357 l.addAll(funcs);
358 Collections.sort(l);
359 final Iterator<String> funcIter = l.iterator();
360 boolean printedHeader = false;
361 while (funcIter.hasNext()) {
362 final String funcName = funcIter.next();
363 if (!funcName.startsWith("GL")) {
364 if (!printedHeader) {
365 output.println();
366 output.println(" //----------------------------------------------------------------");
367 output.println(" // " + groupName);
368 output.println(" //----------------------------------------------------------------");
369 output.println(" group = \"" + groupName + "\";");
370 printedHeader = true;
371 }
372
373 output.println(" funcToAssocMap.put(\"" + funcName + "\", group);");
374 }
375 }
376 }
377 output.println(" }");
378 output.println("} // end class StaticGLInfo");
379 }
380
381 //----------------------------------------------------------------------
382 // Internals only below this point
383 //
384 protected void addAssociation(final String identifier, final String association) {
385 Set<String> extensions = declarationToExtensionMap.get(identifier);
386 if(null == extensions) {
387 extensions = new HashSet<String>();
388 declarationToExtensionMap.put(identifier, extensions);
389 }
390 extensions.add(association);
391
392 Set<String> identifiers = extensionToDeclarationMap.get(association);
393 if (identifiers == null) {
394 identifiers = new HashSet<String>();
395 extensionToDeclarationMap.put(association, identifiers);
396 }
397 identifiers.add(identifier);
398 }
399}
Builds the StaticGLInfo class from the OpenGL header files (i.e., gl.h and glext.h) whose paths were ...
Map< String, Set< String > > declarationToExtensionMap
void parse(final String[] cHeaderFilePaths)
Parses the supplied C header files and adds the function associations contained therein to the intern...
void emitJavaCode(final PrintWriter output, final String packageName)
Map< String, Set< String > > extensionToDeclarationMap
Set< String > getDeclarations(final String extension)
void parse(final String cHeaderFilePath)
Parses the supplied C header file and adds the function associations contained therein to the interna...
static void main(final String[] args)
The first argument is the package to which the StaticGLInfo class belongs, the second is the path to ...
Set< String > getExtension(final String identifier)
void addAssociation(final String identifier, final String association)