JOGL v2.6.0-rc-20250712
JOGL, High-Performance Graphics Binding for Java™ (public API).
CompileShader.java
Go to the documentation of this file.
1package com.jogamp.opengl.util.glsl.sdk;
2
3import com.jogamp.common.util.IOUtil;
4
5import com.jogamp.opengl.*;
6import com.jogamp.opengl.util.glsl.*;
7
8import java.io.*;
9import java.net.*;
10
11/**
12 * Precompiles a shader into a vendor binary format. Input is the
13 * resource name of the shader, such as
14 * "com/jogamp/opengl/impl/glsl/fixed/shader/a.fp".
15 * Output is "com/jogamp/opengl/impl/glsl/fixed/shader/bin/nvidia/a.bfp".
16 *
17 * All path and suffixes are determined by the ShaderCode class,
18 * which ensures runtime compatibility.
19 *
20 * @see com.jogamp.opengl.util.glsl.ShaderCode
21 */
22
23public abstract class CompileShader {
24
25 public abstract int getBinaryFormat();
26
27 public abstract File getSDKCompilerDir();
28
29 public abstract String getVertexShaderCompiler();
30
31 public abstract String getFragmentShaderCompiler();
32
33 public void processOneShader(final String resourceName)
34 throws IOException, UnsupportedEncodingException, InterruptedException
35 {
36 int type = -1;
37 String outName=null;
38 int suffixLen = -1;
39 if(resourceName.endsWith(ShaderCode.getFileSuffix(false, GL2ES2.GL_FRAGMENT_SHADER))) {
40 suffixLen = 2;
42 } else if(resourceName.endsWith(".frag")) {
43 suffixLen = 4;
45 } else if(resourceName.endsWith(ShaderCode.getFileSuffix(false, GL2ES2.GL_VERTEX_SHADER))) {
46 suffixLen = 2;
48 } else if(resourceName.endsWith(".vert")) {
49 suffixLen = 4;
51 }
52 final String justName = basename(resourceName);
53 outName = justName.substring(0, justName.length() - suffixLen) +
54 ShaderCode.getFileSuffix(true, type);
55 final URL resourceURL = IOUtil.getResource(resourceName, this.getClass().getClassLoader(), null).getURL();
56 final String dirName = dirname(resourceURL.getPath());
57
58 outName = dirName + File.separator + "bin" + File.separator +
59 ShaderCode.getBinarySubPath(getBinaryFormat()) + File.separator +
60 outName;
61 processOneShader(resourceName, outName, type);
62 }
63
64 public void processOneShader(final String resourceName, final String outName, final int type)
65 throws IOException, UnsupportedEncodingException, InterruptedException
66 {
67 final URL resourceURL = IOUtil.getResource(resourceName, this.getClass().getClassLoader(), null).getURL();
68 final String dirName = dirname(resourceURL.getPath());
69
70 final CharSequence shader = ShaderCode.readShaderSource(null, resourceName, false);
71 if(null==shader) {
72 System.err.println("Can't find shader source " + resourceName + " - ignored");
73 return;
74 }
75 System.err.println("Preprocessing: "+ resourceName+", in dir: "+dirName);
76 final String justName = basename(resourceName);
77 String processor;
78 switch (type) {
80 processor = getVertexShaderCompiler();
81 break;
83 processor = getFragmentShaderCompiler();
84 break;
85 default:
86 throw new GLException("Unknown shader type: "+type);
87 }
88 final File outputFile = new File(outName);
89
90 // Write shader to a file in java.io.tmpdir
91 final File tmpDir = new File(dirName+File.separator+"tmp");
92 tmpDir.mkdirs();
93 final File tmpFile = new File(tmpDir, justName);
94 final Writer writer = new BufferedWriter(new FileWriter(tmpFile));
95 writer.write(shader.toString(), 0, shader.length());
96 writer.flush();
97 writer.close();
98 System.err.println("Preprocessed: "+ tmpFile.getAbsolutePath());
99
100 final File processorDir = getSDKCompilerDir();
101
102 System.err.println("SDK: "+ processorDir.getAbsolutePath() + ", compiler: "+processor);
103
104 System.err.println("Output: "+ outputFile.getAbsolutePath());
105
106 // Run the tool
107 final Process process = Runtime.getRuntime().exec(new String[] {
108 processorDir.getAbsolutePath() + File.separator + processor,
109 tmpFile.getAbsolutePath(),
110 outputFile.getAbsolutePath()
111 }); // , null, processorDir);
112 new IOUtil.StreamMonitor( new InputStream[] { process.getInputStream(), process.getErrorStream() }, System.out, null );
113 process.waitFor();
114 // Delete the temporary file
115 // tmpFile.delete();
116 }
117
118 protected static String basename(final String path) {
119 int lastSlash = path.lastIndexOf("/");
120 if (lastSlash < 0) {
121 lastSlash = path.lastIndexOf("\\");
122 }
123 String basename;
124 if (lastSlash < 0) {
125 basename = path;
126 } else {
127 basename = path.substring(lastSlash + 1);
128 }
129 return basename;
130 }
131
132 protected static String dirname(final String path) {
133 int lastSlash = path.lastIndexOf("/");
134 if (lastSlash < 0) {
135 lastSlash = path.lastIndexOf("\\");
136 }
137 String dirname;
138 if (lastSlash < 0) {
139 dirname = "";
140 } else {
141 dirname = path.substring(0, lastSlash + 1);
142 }
143 return dirname;
144 }
145
146 public void run(final String[] args) {
147 try {
148 for (int i = 0; i < args.length; i++) {
149 processOneShader(args[i]);
150 }
151 } catch (final Exception e) {
152 e.printStackTrace();
153 }
154 }
155}
A generic exception for OpenGL errors used throughout the binding as a substitute for RuntimeExceptio...
Convenient shader code class to use and instantiate vertex or fragment programs.
Definition: ShaderCode.java:75
static String getFileSuffix(final boolean binary, final int type)
Returns a unique suffix for shader resources as follows:
static String getBinarySubPath(final int binFormat)
Returns a unique relative path for binary shader resources as follows:
Precompiles a shader into a vendor binary format.
static String dirname(final String path)
void processOneShader(final String resourceName)
void processOneShader(final String resourceName, final String outName, final int type)
static String basename(final String path)
static final int GL_VERTEX_SHADER
GL_ES_VERSION_2_0, GL_VERSION_2_0, GL_EXT_vertex_shader, GL_ARB_vertex_shader Alias for: GL_VERTEX_SH...
Definition: GL2ES2.java:39
static final int GL_FRAGMENT_SHADER
GL_ES_VERSION_2_0, GL_VERSION_2_0, GL_ATI_fragment_shader, GL_ARB_fragment_shader Alias for: GL_FRAGM...
Definition: GL2ES2.java:541