18 |
18 |
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA //
|
19 |
19 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
20 |
20 |
|
21 |
|
package org.distorted.library.program;
|
|
21 |
package org.distorted.library.program
|
22 |
22 |
|
23 |
|
import android.opengl.GLES30;
|
24 |
|
|
25 |
|
import org.distorted.library.main.DistortedLibrary;
|
26 |
|
|
27 |
|
import java.io.BufferedReader;
|
28 |
|
import java.io.IOException;
|
29 |
|
import java.io.InputStream;
|
30 |
|
import java.io.InputStreamReader;
|
|
23 |
import android.opengl.GLES30
|
|
24 |
import org.distorted.library.main.DistortedLibrary
|
|
25 |
import java.io.BufferedReader
|
|
26 |
import java.io.IOException
|
|
27 |
import java.io.InputStream
|
|
28 |
import java.io.InputStreamReader
|
31 |
29 |
|
32 |
30 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
33 |
|
/**
|
34 |
|
* An object which encapsulates a vertex/fragment shader combo, aka Shader Program.
|
35 |
|
*/
|
36 |
|
public class DistortedProgram
|
37 |
|
{
|
38 |
|
public static final int ATTR_LAYOUT_PNTC = 0;
|
39 |
|
public static final int ATTR_LAYOUT_PTC = 1;
|
40 |
|
public static final int ATTR_LAYOUT_PNT = 2;
|
41 |
|
public static final int ATTR_LAYOUT_PNC = 3;
|
42 |
|
public static final int ATTR_LAYOUT_PT = 4;
|
43 |
|
public static final int ATTR_LAYOUT_P = 5;
|
44 |
|
public static final int ATTR_LAYOUT_UNK = 6;
|
45 |
|
|
46 |
|
private String mAttributeStr, mUniformStr, mUniList;
|
47 |
|
private int mAttributeLen, mUniformLen;
|
48 |
|
private int mNumAttributes;
|
49 |
|
private int mNumUniforms;
|
50 |
|
private String[] mAttributeName;
|
51 |
|
private final int mProgramHandle;
|
52 |
|
|
53 |
|
/**
|
54 |
|
* Various programs have different attributes (because even if the source is the same, some of them might
|
55 |
|
* be unused).
|
56 |
|
* Main, Full have 4 attributes in the order (position,normal,texcoord, component)
|
57 |
|
* Pre has 3 attributes (position,texcoord,component)
|
58 |
|
* Maybe there are other possibilities (only position and normal? 3- position,normal,texcoord?)
|
59 |
|
*/
|
60 |
|
public int mAttributeLayout;
|
61 |
|
/**
|
62 |
|
* List of Attributes (OpenGL ES 3.0: 'in' variables), in the same order as declared in the shader source.
|
63 |
|
*/
|
64 |
|
public int[] mAttribute;
|
65 |
|
/**
|
66 |
|
* List of Uniforms, in the same order as declared in the shader source.
|
67 |
|
*/
|
68 |
|
public int[] mUniform;
|
69 |
|
|
70 |
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
71 |
|
|
72 |
|
private int createAndLinkProgram(final int vertexShaderHandle, final int fragmentShaderHandle, final String[] attributes, final String[] feedbackVaryings)
|
73 |
|
throws LinkingException
|
|
31 |
/** An object which encapsulates a vertex/fragment shader combo, aka Shader Program.
|
|
32 |
*/
|
|
33 |
class DistortedProgram
|
|
34 |
{
|
|
35 |
private var mAttributeStr: String? = null
|
|
36 |
private var mUniformStr: String? = null
|
|
37 |
private var mUniList: String? = null
|
|
38 |
private var mAttributeLen = 0
|
|
39 |
private var mUniformLen = 0
|
|
40 |
private var mNumAttributes = 0
|
|
41 |
private var mNumUniforms = 0
|
|
42 |
private lateinit var mAttributeName: Array<String>
|
|
43 |
val programHandle: Int
|
|
44 |
|
|
45 |
/**
|
|
46 |
* Various programs have different attributes (because even if the source is the same, some of them might
|
|
47 |
* be unused).
|
|
48 |
* Main, Full have 4 attributes in the order (position,normal,texcoord, component)
|
|
49 |
* Pre has 3 attributes (position,texcoord,component)
|
|
50 |
* Maybe there are other possibilities (only position and normal? 3- position,normal,texcoord?)
|
|
51 |
*/
|
|
52 |
@JvmField var mAttributeLayout: Int = 0
|
|
53 |
|
|
54 |
/**
|
|
55 |
* List of Attributes (OpenGL ES 3.0: 'in' variables), in the same order as declared in the shader source.
|
|
56 |
*/
|
|
57 |
@JvmField var mAttribute: IntArray? = null
|
|
58 |
|
|
59 |
/**
|
|
60 |
* List of Uniforms, in the same order as declared in the shader source.
|
|
61 |
*/
|
|
62 |
@JvmField var mUniform: IntArray? = null
|
|
63 |
|
|
64 |
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
65 |
@Throws(LinkingException::class)
|
|
66 |
private fun createAndLinkProgram(verHandle: Int, fraHandle: Int, attributes: Array<String>?, feedbackVaryings: Array<String?>?): Int
|
74 |
67 |
{
|
75 |
|
int programHandle = GLES30.glCreateProgram();
|
|
68 |
val programHandle = GLES30.glCreateProgram()
|
76 |
69 |
|
77 |
|
if (programHandle != 0)
|
78 |
|
{
|
79 |
|
GLES30.glAttachShader(programHandle, vertexShaderHandle);
|
80 |
|
GLES30.glAttachShader(programHandle, fragmentShaderHandle);
|
81 |
|
|
82 |
|
if( feedbackVaryings!=null )
|
|
70 |
if (programHandle != 0)
|
83 |
71 |
{
|
84 |
|
GLES30.glTransformFeedbackVaryings(programHandle, feedbackVaryings, GLES30.GL_INTERLEAVED_ATTRIBS);
|
85 |
|
}
|
|
72 |
GLES30.glAttachShader(programHandle, verHandle)
|
|
73 |
GLES30.glAttachShader(programHandle, fraHandle)
|
86 |
74 |
|
87 |
|
if (attributes != null)
|
88 |
|
{
|
89 |
|
final int size = attributes.length;
|
|
75 |
if (feedbackVaryings != null)
|
|
76 |
GLES30.glTransformFeedbackVaryings(programHandle, feedbackVaryings, GLES30.GL_INTERLEAVED_ATTRIBS)
|
90 |
77 |
|
91 |
|
for(int i=0; i<size; i++)
|
92 |
|
{
|
93 |
|
GLES30.glBindAttribLocation(programHandle, i, attributes[i]);
|
94 |
|
}
|
95 |
|
}
|
|
78 |
if (attributes != null)
|
|
79 |
{
|
|
80 |
val size = attributes.size
|
96 |
81 |
|
97 |
|
GLES30.glLinkProgram(programHandle);
|
|
82 |
for (i in 0..<size)
|
|
83 |
GLES30.glBindAttribLocation(programHandle, i, attributes[i])
|
|
84 |
}
|
98 |
85 |
|
99 |
|
final int[] linkStatus = new int[1];
|
100 |
|
GLES30.glGetProgramiv(programHandle, GLES30.GL_LINK_STATUS, linkStatus, 0);
|
|
86 |
GLES30.glLinkProgram(programHandle)
|
101 |
87 |
|
102 |
|
if (linkStatus[0] != GLES30.GL_TRUE )
|
103 |
|
{
|
104 |
|
String error = GLES30.glGetProgramInfoLog(programHandle);
|
105 |
|
GLES30.glDeleteProgram(programHandle);
|
106 |
|
throw new LinkingException(error);
|
107 |
|
}
|
|
88 |
val linkStatus = IntArray(1)
|
|
89 |
GLES30.glGetProgramiv(programHandle, GLES30.GL_LINK_STATUS, linkStatus, 0)
|
108 |
90 |
|
109 |
|
//final int[] numberOfUniforms = new int[1];
|
110 |
|
//GLES30.glGetProgramiv(programHandle, GLES30.GL_ACTIVE_UNIFORMS, numberOfUniforms, 0);
|
111 |
|
//DistortedLibrary.logMessage("DistortedProgram: number of active uniforms="+numberOfUniforms[0]);
|
112 |
|
}
|
|
91 |
if (linkStatus[0] != GLES30.GL_TRUE)
|
|
92 |
{
|
|
93 |
val error = GLES30.glGetProgramInfoLog(programHandle)
|
|
94 |
GLES30.glDeleteProgram(programHandle)
|
|
95 |
throw LinkingException(error)
|
|
96 |
}
|
113 |
97 |
|
114 |
|
return programHandle;
|
115 |
|
}
|
|
98 |
//final int[] numberOfUniforms = new int[1];
|
|
99 |
//GLES30.glGetProgramiv(programHandle, GLES30.GL_ACTIVE_UNIFORMS, numberOfUniforms, 0);
|
|
100 |
//DistortedLibrary.logMessage("DistortedProgram: number of active uniforms="+numberOfUniforms[0]);
|
|
101 |
}
|
116 |
102 |
|
117 |
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
103 |
return programHandle
|
|
104 |
}
|
118 |
105 |
|
119 |
|
private void init(int glslVersion)
|
|
106 |
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
107 |
private fun init(glslVersion: Int)
|
120 |
108 |
{
|
121 |
|
mAttributeStr = (glslVersion == 100 ? "attribute " : "in ");
|
122 |
|
mAttributeLen = mAttributeStr.length();
|
123 |
|
mNumAttributes = 0;
|
124 |
|
mUniformStr = "uniform ";
|
125 |
|
mUniformLen = mUniformStr.length();
|
126 |
|
mNumUniforms = 0;
|
127 |
|
mUniList = "";
|
|
109 |
mAttributeStr = (if (glslVersion==100) "attribute " else "in ")
|
|
110 |
mAttributeLen = mAttributeStr!!.length
|
|
111 |
mNumAttributes = 0
|
|
112 |
mUniformStr = "uniform "
|
|
113 |
mUniformLen = mUniformStr!!.length
|
|
114 |
mNumUniforms = 0
|
|
115 |
mUniList = ""
|
128 |
116 |
}
|
129 |
117 |
|
130 |
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
131 |
|
|
132 |
|
private String parseOutUniform(final String line)
|
|
118 |
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
119 |
private fun parseOutUniform(line: String): String?
|
133 |
120 |
{
|
134 |
|
int len = line.length();
|
135 |
|
int whiteSpace, semicolon, nameBegin;
|
136 |
|
char currChar;
|
137 |
|
|
138 |
|
for(whiteSpace=0; whiteSpace<len; whiteSpace++)
|
139 |
|
{
|
140 |
|
currChar = line.charAt(whiteSpace);
|
141 |
|
if( currChar!=' ' && currChar!='\t') break;
|
142 |
|
}
|
143 |
|
|
144 |
|
for(semicolon=whiteSpace; semicolon<len; semicolon++)
|
145 |
|
{
|
146 |
|
currChar = line.charAt(semicolon);
|
147 |
|
if( currChar==';') break;
|
148 |
|
}
|
149 |
|
|
150 |
|
if( semicolon<len && semicolon-whiteSpace>=mUniformLen+1 )
|
151 |
|
{
|
152 |
|
String subline = line.substring(whiteSpace,semicolon);
|
153 |
|
int subLen = semicolon-whiteSpace;
|
154 |
|
|
155 |
|
if( subline.startsWith(mUniformStr))
|
156 |
|
{
|
157 |
|
//DistortedLibrary.logMessage("DistortedProgram: GOOD LINE: " +subline+" subLen="+subLen);
|
|
121 |
val len = line.length
|
|
122 |
var semicolon: Int
|
|
123 |
var nameBegin: Int
|
|
124 |
var currChar: Char
|
|
125 |
var whiteSpace = 0
|
158 |
126 |
|
159 |
|
for(nameBegin=subLen-1; nameBegin>mUniformLen-2; nameBegin--)
|
160 |
|
{
|
161 |
|
currChar=subline.charAt(nameBegin);
|
162 |
|
|
163 |
|
if( currChar==' ' || currChar=='\t' )
|
164 |
|
{
|
165 |
|
mNumUniforms++;
|
166 |
|
String uniform = subline.substring(nameBegin+1,subLen);
|
167 |
|
int brace = uniform.indexOf("[");
|
168 |
|
|
169 |
|
return brace>=0 ? uniform.substring(0,brace) : uniform;
|
170 |
|
}
|
171 |
|
}
|
|
127 |
while (whiteSpace < len)
|
|
128 |
{
|
|
129 |
currChar = line[whiteSpace]
|
|
130 |
if (currChar != ' ' && currChar != '\t') break
|
|
131 |
whiteSpace++
|
172 |
132 |
}
|
173 |
|
}
|
174 |
133 |
|
175 |
|
return null;
|
176 |
|
}
|
|
134 |
semicolon = whiteSpace
|
177 |
135 |
|
178 |
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
136 |
while (semicolon < len)
|
|
137 |
{
|
|
138 |
currChar = line[semicolon]
|
|
139 |
if (currChar == ';') break
|
|
140 |
semicolon++
|
|
141 |
}
|
179 |
142 |
|
180 |
|
private String parseOutAttribute(final String line)
|
181 |
|
{
|
182 |
|
int len = line.length();
|
183 |
|
int whiteSpace, semicolon, nameBegin;
|
184 |
|
char currChar;
|
185 |
|
|
186 |
|
for(whiteSpace=0; whiteSpace<len; whiteSpace++)
|
187 |
|
{
|
188 |
|
currChar = line.charAt(whiteSpace);
|
189 |
|
if( currChar!=' ' && currChar!='\t') break;
|
190 |
|
}
|
191 |
|
|
192 |
|
for(semicolon=whiteSpace; semicolon<len; semicolon++)
|
193 |
|
{
|
194 |
|
currChar = line.charAt(semicolon);
|
195 |
|
if( currChar==';') break;
|
196 |
|
}
|
197 |
|
|
198 |
|
if( semicolon<len && semicolon-whiteSpace>=mAttributeLen+1 )
|
199 |
|
{
|
200 |
|
String subline = line.substring(whiteSpace,semicolon);
|
201 |
|
int subLen = semicolon-whiteSpace;
|
202 |
|
|
203 |
|
if( subline.startsWith(mAttributeStr))
|
|
143 |
if (semicolon < len && semicolon-whiteSpace >= mUniformLen+1)
|
204 |
144 |
{
|
205 |
|
for(nameBegin=subLen-1; nameBegin>mAttributeLen-2; nameBegin--)
|
206 |
|
{
|
207 |
|
currChar=subline.charAt(nameBegin);
|
|
145 |
val subline = line.substring(whiteSpace, semicolon)
|
|
146 |
val subLen = semicolon - whiteSpace
|
208 |
147 |
|
209 |
|
if( currChar==' ' || currChar=='\t' )
|
|
148 |
if (subline.startsWith(mUniformStr!!))
|
210 |
149 |
{
|
211 |
|
return subline.substring(nameBegin+1,subLen);
|
|
150 |
nameBegin = subLen-1
|
|
151 |
|
|
152 |
while (nameBegin > mUniformLen-2)
|
|
153 |
{
|
|
154 |
currChar = subline[nameBegin]
|
|
155 |
|
|
156 |
if (currChar == ' ' || currChar == '\t')
|
|
157 |
{
|
|
158 |
mNumUniforms++
|
|
159 |
val uniform = subline.substring(nameBegin+1, subLen)
|
|
160 |
val brace = uniform.indexOf("[")
|
|
161 |
return if (brace>=0) uniform.substring(0, brace) else uniform
|
|
162 |
}
|
|
163 |
nameBegin--
|
|
164 |
}
|
212 |
165 |
}
|
213 |
|
}
|
214 |
166 |
}
|
215 |
|
}
|
216 |
167 |
|
217 |
|
return null;
|
|
168 |
return null
|
218 |
169 |
}
|
219 |
170 |
|
220 |
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
221 |
|
|
222 |
|
private void doAttributes(final String shader, boolean doAttributes)
|
|
171 |
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
172 |
private fun parseOutAttribute(line: String): String?
|
223 |
173 |
{
|
224 |
|
String attribute, attrList="", uniform;
|
225 |
|
String[] lines = shader.split("\n");
|
|
174 |
val len = line.length
|
|
175 |
var semicolon: Int
|
|
176 |
var nameBegin: Int
|
|
177 |
var currChar: Char
|
|
178 |
var whiteSpace = 0
|
226 |
179 |
|
227 |
|
for (String line : lines)
|
228 |
|
{
|
229 |
|
if( doAttributes )
|
|
180 |
while (whiteSpace<len)
|
230 |
181 |
{
|
231 |
|
attribute = parseOutAttribute(line);
|
232 |
|
|
233 |
|
if (attribute != null)
|
234 |
|
{
|
235 |
|
if( !attrList.isEmpty() ) attrList += " ";
|
236 |
|
attrList += attribute;
|
237 |
|
}
|
|
182 |
currChar = line[whiteSpace]
|
|
183 |
if (currChar != ' ' && currChar != '\t') break
|
|
184 |
whiteSpace++
|
238 |
185 |
}
|
239 |
186 |
|
240 |
|
uniform = parseOutUniform(line);
|
|
187 |
semicolon = whiteSpace
|
241 |
188 |
|
242 |
|
if (uniform != null)
|
|
189 |
while (semicolon < len)
|
243 |
190 |
{
|
244 |
|
if( !mUniList.isEmpty() ) mUniList += " ";
|
245 |
|
mUniList += uniform;
|
|
191 |
currChar = line[semicolon]
|
|
192 |
if (currChar == ';') break
|
|
193 |
semicolon++
|
246 |
194 |
}
|
247 |
|
}
|
248 |
195 |
|
249 |
|
if( doAttributes )
|
250 |
|
{
|
251 |
|
mAttributeName = attrList.split(" ");
|
252 |
|
mNumAttributes = mAttributeName.length;
|
253 |
|
}
|
254 |
|
}
|
255 |
|
|
256 |
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
257 |
|
|
258 |
|
private String readTextFileFromRawResource(final InputStream inputStream, boolean doAttributes)
|
259 |
|
{
|
260 |
|
final InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
|
261 |
|
final BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
|
262 |
|
|
263 |
|
String nextLine, attribute, attrList="";
|
264 |
|
final StringBuilder body = new StringBuilder();
|
265 |
|
|
266 |
|
try
|
267 |
|
{
|
268 |
|
while ((nextLine = bufferedReader.readLine()) != null)
|
|
196 |
if (semicolon < len && semicolon-whiteSpace >= mAttributeLen+1)
|
269 |
197 |
{
|
270 |
|
body.append(nextLine);
|
271 |
|
body.append('\n');
|
|
198 |
val subline = line.substring(whiteSpace, semicolon)
|
|
199 |
val subLen = semicolon-whiteSpace
|
272 |
200 |
|
273 |
|
if( doAttributes )
|
274 |
|
{
|
275 |
|
attribute = parseOutAttribute(nextLine);
|
276 |
|
|
277 |
|
if( attribute!=null )
|
|
201 |
if (subline.startsWith(mAttributeStr!!))
|
278 |
202 |
{
|
279 |
|
//DistortedLibrary.logMessage("DistortedProgram: new attribute: "+attribute);
|
280 |
|
if( !attrList.isEmpty() ) attrList += " ";
|
281 |
|
attrList += attribute;
|
|
203 |
nameBegin = subLen-1
|
|
204 |
|
|
205 |
while (nameBegin > mAttributeLen-2)
|
|
206 |
{
|
|
207 |
currChar = subline[nameBegin]
|
|
208 |
if (currChar == ' ' || currChar == '\t') return subline.substring(nameBegin + 1, subLen)
|
|
209 |
nameBegin--
|
|
210 |
}
|
282 |
211 |
}
|
283 |
|
}
|
284 |
212 |
}
|
285 |
|
}
|
286 |
|
catch (IOException e)
|
287 |
|
{
|
288 |
|
return null;
|
289 |
|
}
|
290 |
|
|
291 |
|
if( doAttributes )
|
292 |
|
{
|
293 |
|
mAttributeName = attrList.split(" ");
|
294 |
|
mNumAttributes = mAttributeName.length;
|
295 |
|
}
|
296 |
|
|
297 |
|
return body.toString();
|
298 |
|
}
|
299 |
213 |
|
300 |
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
214 |
return null
|
|
215 |
}
|
301 |
216 |
|
302 |
|
private static int compileShader(final int shaderType, final String shaderSource)
|
303 |
|
throws FragmentCompilationException,VertexCompilationException
|
|
217 |
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
218 |
private fun doAttributes(shader: String, doAttributes: Boolean)
|
304 |
219 |
{
|
305 |
|
int shaderHandle = GLES30.glCreateShader(shaderType);
|
306 |
|
|
307 |
|
if (shaderHandle != 0)
|
308 |
|
{
|
309 |
|
GLES30.glShaderSource(shaderHandle, shaderSource);
|
310 |
|
GLES30.glCompileShader(shaderHandle);
|
311 |
|
final int[] compileStatus = new int[1];
|
312 |
|
GLES30.glGetShaderiv(shaderHandle, GLES30.GL_COMPILE_STATUS, compileStatus, 0);
|
|
220 |
var attribute: String?
|
|
221 |
var attrList: String? = ""
|
|
222 |
var uniform: String?
|
|
223 |
val lines = shader.split("\n")
|
313 |
224 |
|
314 |
|
if (compileStatus[0] != GLES30.GL_TRUE)
|
|
225 |
for (line in lines)
|
315 |
226 |
{
|
316 |
|
String error = GLES30.glGetShaderInfoLog(shaderHandle);
|
|
227 |
if (doAttributes)
|
|
228 |
{
|
|
229 |
attribute = parseOutAttribute(line)
|
317 |
230 |
|
318 |
|
GLES30.glDeleteShader(shaderHandle);
|
|
231 |
if (attribute != null)
|
|
232 |
{
|
|
233 |
if (!attrList!!.isEmpty()) attrList += " "
|
|
234 |
attrList += attribute
|
|
235 |
}
|
|
236 |
}
|
|
237 |
|
|
238 |
uniform = parseOutUniform(line)
|
319 |
239 |
|
320 |
|
switch (shaderType)
|
321 |
|
{
|
322 |
|
case GLES30.GL_VERTEX_SHADER: throw new VertexCompilationException(error);
|
323 |
|
case GLES30.GL_FRAGMENT_SHADER: throw new FragmentCompilationException(error);
|
324 |
|
default: throw new RuntimeException(error);
|
325 |
|
}
|
|
240 |
if (uniform != null)
|
|
241 |
{
|
|
242 |
if (!mUniList!!.isEmpty()) mUniList += " "
|
|
243 |
mUniList += uniform
|
|
244 |
}
|
326 |
245 |
}
|
327 |
|
}
|
328 |
246 |
|
329 |
|
return shaderHandle;
|
|
247 |
if (doAttributes)
|
|
248 |
{
|
|
249 |
mAttributeName = attrList!!.split(" ").toTypedArray()
|
|
250 |
mNumAttributes = mAttributeName.size
|
|
251 |
}
|
330 |
252 |
}
|
331 |
253 |
|
332 |
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
333 |
|
|
334 |
|
private static String insertEnabledEffects(String code, final String effects)
|
|
254 |
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
255 |
private fun readTextFileFromRawResource(inputStream: InputStream, doAttributes: Boolean): String?
|
335 |
256 |
{
|
336 |
|
final String marker = "// ENABLED EFFECTS WILL BE INSERTED HERE";
|
337 |
|
int length = marker.length();
|
|
257 |
val inputStreamReader = InputStreamReader(inputStream)
|
|
258 |
val bufferedReader = BufferedReader(inputStreamReader)
|
338 |
259 |
|
339 |
|
int place = code.indexOf(marker);
|
|
260 |
var nextLine: String?
|
|
261 |
var attribute: String?
|
|
262 |
var attrList: String? = ""
|
|
263 |
val body = StringBuilder()
|
340 |
264 |
|
341 |
|
if( place>=0 )
|
342 |
|
{
|
343 |
|
String begin = code.substring(0,place-1);
|
344 |
|
String end = code.substring(place+length);
|
|
265 |
try
|
|
266 |
{
|
|
267 |
while ((bufferedReader.readLine().also { nextLine = it }) != null)
|
|
268 |
{
|
|
269 |
body.append(nextLine)
|
|
270 |
body.append('\n')
|
345 |
271 |
|
346 |
|
return begin + effects + end;
|
347 |
|
}
|
348 |
|
else
|
349 |
|
{
|
350 |
|
DistortedLibrary.logMessage("DistortedProgram: Error: marker string not found in SHADER!");
|
351 |
|
}
|
|
272 |
if (doAttributes)
|
|
273 |
{
|
|
274 |
attribute = parseOutAttribute(nextLine!!)
|
352 |
275 |
|
353 |
|
return null;
|
354 |
|
}
|
|
276 |
if (attribute != null)
|
|
277 |
{
|
|
278 |
if (!attrList!!.isEmpty()) attrList += " "
|
|
279 |
attrList += attribute
|
|
280 |
}
|
|
281 |
}
|
|
282 |
}
|
|
283 |
}
|
|
284 |
catch (e: IOException) { return null }
|
355 |
285 |
|
356 |
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
286 |
if (doAttributes)
|
|
287 |
{
|
|
288 |
mAttributeName = attrList!!.split(" ").toTypedArray()
|
|
289 |
mNumAttributes = mAttributeName.size
|
|
290 |
}
|
|
291 |
|
|
292 |
return body.toString()
|
|
293 |
}
|
357 |
294 |
|
358 |
|
private void setUpAttributes()
|
|
295 |
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
296 |
private fun setUpAttributes()
|
359 |
297 |
{
|
360 |
|
int[] att = new int[mNumAttributes];
|
|
298 |
val att = IntArray(mNumAttributes)
|
361 |
299 |
|
362 |
|
for(int i=0; i<mNumAttributes; i++)
|
363 |
|
{
|
364 |
|
att[i] = GLES30.glGetAttribLocation( mProgramHandle, mAttributeName[i]);
|
365 |
|
}
|
|
300 |
for (i in 0..<mNumAttributes)
|
|
301 |
att[i] = GLES30.glGetAttribLocation(programHandle, mAttributeName[i])
|
366 |
302 |
|
367 |
|
int emptyAttrs = 0;
|
|
303 |
var emptyAttrs=0
|
|
304 |
var i=0
|
368 |
305 |
|
369 |
|
for(int i=0; i<mNumAttributes-emptyAttrs; i++)
|
370 |
|
{
|
371 |
|
if( att[i] < 0 )
|
|
306 |
while (i < mNumAttributes-emptyAttrs)
|
372 |
307 |
{
|
373 |
|
emptyAttrs++;
|
|
308 |
if (att[i] < 0)
|
|
309 |
{
|
|
310 |
emptyAttrs++
|
374 |
311 |
|
375 |
|
for(int j=i; j<mNumAttributes-emptyAttrs; j++)
|
376 |
|
{
|
377 |
|
att[j] = att[j+1];
|
378 |
|
mAttributeName[j] = mAttributeName[j+1];
|
379 |
|
}
|
|
312 |
for (j in i..<mNumAttributes - emptyAttrs)
|
|
313 |
{
|
|
314 |
att[j] = att[j+1]
|
|
315 |
mAttributeName[j] = mAttributeName[j+1]
|
|
316 |
}
|
|
317 |
}
|
|
318 |
i++
|
380 |
319 |
}
|
381 |
|
}
|
382 |
|
|
383 |
|
if( emptyAttrs>0 )
|
384 |
|
{
|
385 |
|
mNumAttributes -= emptyAttrs;
|
386 |
|
mAttribute = new int[mNumAttributes];
|
387 |
|
System.arraycopy(att, 0, mAttribute, 0, mNumAttributes);
|
388 |
|
}
|
389 |
|
else
|
390 |
|
{
|
391 |
|
mAttribute = att;
|
392 |
|
}
|
393 |
|
|
394 |
|
setUpAttributeLayout();
|
395 |
|
}
|
396 |
320 |
|
397 |
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
321 |
if (emptyAttrs > 0)
|
|
322 |
{
|
|
323 |
mNumAttributes -= emptyAttrs
|
|
324 |
mAttribute = IntArray(mNumAttributes)
|
|
325 |
att.copyInto(mAttribute!!, 0, 0, mNumAttributes)
|
|
326 |
}
|
|
327 |
else
|
|
328 |
{
|
|
329 |
mAttribute = att
|
|
330 |
}
|
|
331 |
|
|
332 |
setUpAttributeLayout()
|
|
333 |
}
|
398 |
334 |
|
399 |
|
private void setUpAttributeLayout()
|
|
335 |
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
336 |
private fun setUpAttributeLayout()
|
400 |
337 |
{
|
401 |
|
switch(mNumAttributes)
|
402 |
|
{
|
403 |
|
case 4: mAttributeLayout = ATTR_LAYOUT_PNTC;
|
404 |
|
break;
|
405 |
|
case 3: if( mAttributeName[2].equals("a_TexCoordinate") ) mAttributeLayout = ATTR_LAYOUT_PNT;
|
406 |
|
else if( mAttributeName[2].equals("a_Component") )
|
407 |
|
{
|
408 |
|
if( mAttributeName[1].equals("a_TexCoordinate") ) mAttributeLayout = ATTR_LAYOUT_PTC;
|
409 |
|
else if( mAttributeName[1].equals("a_Normal" ) ) mAttributeLayout = ATTR_LAYOUT_PNC;
|
410 |
|
else
|
|
338 |
when (mNumAttributes)
|
|
339 |
{
|
|
340 |
4 -> mAttributeLayout = ATTR_LAYOUT_PNTC
|
|
341 |
|
|
342 |
3 -> if (mAttributeName[2] == "a_TexCoordinate") mAttributeLayout = ATTR_LAYOUT_PNT
|
|
343 |
else if (mAttributeName[2] == "a_Component")
|
411 |
344 |
{
|
412 |
|
mAttributeLayout = ATTR_LAYOUT_UNK;
|
413 |
|
DistortedLibrary.logMessage("DistortedProgram: 1 Error in attribute layout: "+mAttributeName[1]);
|
|
345 |
if (mAttributeName[1] == "a_TexCoordinate") mAttributeLayout = ATTR_LAYOUT_PTC
|
|
346 |
else if (mAttributeName[1] == "a_Normal") mAttributeLayout = ATTR_LAYOUT_PNC
|
|
347 |
else
|
|
348 |
{
|
|
349 |
mAttributeLayout = ATTR_LAYOUT_UNK
|
|
350 |
DistortedLibrary.logMessage("DistortedProgram: 1 Error in attribute layout: " + mAttributeName[1])
|
|
351 |
}
|
|
352 |
}
|
|
353 |
else
|
|
354 |
{
|
|
355 |
mAttributeLayout = ATTR_LAYOUT_UNK
|
|
356 |
DistortedLibrary.logMessage("DistortedProgram: 2 Error in attribute layout: " + mAttributeName[2])
|
414 |
357 |
}
|
415 |
|
}
|
416 |
|
else
|
417 |
|
{
|
418 |
|
mAttributeLayout = ATTR_LAYOUT_UNK;
|
419 |
|
DistortedLibrary.logMessage("DistortedProgram: 2 Error in attribute layout: "+mAttributeName[2]);
|
420 |
|
}
|
421 |
|
break;
|
422 |
|
case 2: if( mAttributeName[1].equals("a_TexCoordinate") ) mAttributeLayout = ATTR_LAYOUT_PT;
|
423 |
|
else
|
424 |
|
{
|
425 |
|
mAttributeLayout = ATTR_LAYOUT_UNK;
|
426 |
|
DistortedLibrary.logMessage("DistortedProgram: 3 Error in attribute layout: "+mAttributeName[1]);
|
427 |
|
}
|
428 |
|
break;
|
429 |
|
case 1: if( mAttributeName[0].equals("a_Position") ) mAttributeLayout = ATTR_LAYOUT_P;
|
430 |
|
else
|
431 |
|
{
|
432 |
|
mAttributeLayout = ATTR_LAYOUT_UNK;
|
433 |
|
DistortedLibrary.logMessage("DistortedProgram: 4 Error in attribute layout: "+mAttributeName[0]);
|
434 |
|
}
|
435 |
|
break;
|
436 |
|
default:mAttributeLayout = ATTR_LAYOUT_UNK;
|
437 |
|
DistortedLibrary.logMessage("DistortedProgram: 5 Error in attribute layout: "+mNumAttributes);
|
438 |
|
}
|
439 |
|
}
|
440 |
358 |
|
441 |
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
359 |
2 -> if (mAttributeName[1] == "a_TexCoordinate") mAttributeLayout = ATTR_LAYOUT_PT
|
|
360 |
else
|
|
361 |
{
|
|
362 |
mAttributeLayout = ATTR_LAYOUT_UNK
|
|
363 |
DistortedLibrary.logMessage("DistortedProgram: 3 Error in attribute layout: " + mAttributeName[1])
|
|
364 |
}
|
|
365 |
|
|
366 |
1 -> if (mAttributeName[0] == "a_Position") mAttributeLayout = ATTR_LAYOUT_P
|
|
367 |
else
|
|
368 |
{
|
|
369 |
mAttributeLayout = ATTR_LAYOUT_UNK
|
|
370 |
DistortedLibrary.logMessage("DistortedProgram: 4 Error in attribute layout: " + mAttributeName[0])
|
|
371 |
}
|
|
372 |
|
|
373 |
else ->
|
|
374 |
{
|
|
375 |
mAttributeLayout = ATTR_LAYOUT_UNK
|
|
376 |
DistortedLibrary.logMessage("DistortedProgram: 5 Error in attribute layout: $mNumAttributes")
|
|
377 |
}
|
|
378 |
}
|
|
379 |
}
|
442 |
380 |
|
443 |
|
private void setUpUniforms()
|
|
381 |
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
382 |
private fun setUpUniforms()
|
444 |
383 |
{
|
445 |
|
if( mNumUniforms>0 )
|
446 |
|
{
|
447 |
|
mUniform = new int[mNumUniforms];
|
448 |
|
String[] uniformName = mUniList.split(" ");
|
449 |
|
|
450 |
|
for(int i=0; i<mNumUniforms; i++)
|
|
384 |
if (mNumUniforms>0)
|
451 |
385 |
{
|
452 |
|
mUniform[i] = GLES30.glGetUniformLocation( mProgramHandle, uniformName[i]);
|
|
386 |
mUniform = IntArray(mNumUniforms)
|
|
387 |
val uniformName = mUniList!!.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
|
388 |
|
|
389 |
for (i in 0..<mNumUniforms)
|
|
390 |
mUniform!![i] = GLES30.glGetUniformLocation(programHandle, uniformName[i])
|
453 |
391 |
}
|
454 |
|
}
|
455 |
|
else mUniform = null;
|
|
392 |
else mUniform = null
|
456 |
393 |
}
|
457 |
394 |
|
458 |
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
459 |
|
/**
|
460 |
|
* Only for use by the library itself.
|
461 |
|
*
|
462 |
|
* @y.exclude
|
463 |
|
*/
|
464 |
|
public DistortedProgram(final InputStream vert, final InputStream frag, final String vertHeader, final String fragHeader,
|
465 |
|
int glslVersion, final String[] feedback )
|
466 |
|
throws FragmentCompilationException,VertexCompilationException,LinkingException
|
|
395 |
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
396 |
/** Only for use by the library itself.
|
|
397 |
*
|
|
398 |
* @y.exclude
|
|
399 |
*/
|
|
400 |
constructor(vert: InputStream, frag: InputStream, vertHeader: String,
|
|
401 |
fragHeader: String, glslVersion: Int, feedback: Array<String?>?)
|
467 |
402 |
{
|
468 |
|
init(glslVersion);
|
|
403 |
init(glslVersion)
|
469 |
404 |
|
470 |
|
final String vertShader = readTextFileFromRawResource(vert, true );
|
471 |
|
final String fragShader = readTextFileFromRawResource(frag, false);
|
|
405 |
val vertShader = readTextFileFromRawResource(vert, true)
|
|
406 |
val fragShader = readTextFileFromRawResource(frag, false)
|
472 |
407 |
|
473 |
|
final int vertShaderHandle = compileShader(GLES30.GL_VERTEX_SHADER , vertHeader + vertShader);
|
474 |
|
final int fragShaderHandle = compileShader(GLES30.GL_FRAGMENT_SHADER, fragHeader + fragShader);
|
|
408 |
val vertShaderHandle = compileShader(GLES30.GL_VERTEX_SHADER , vertHeader + vertShader)
|
|
409 |
val fragShaderHandle = compileShader(GLES30.GL_FRAGMENT_SHADER, fragHeader + fragShader)
|
475 |
410 |
|
476 |
|
mProgramHandle = createAndLinkProgram(vertShaderHandle, fragShaderHandle, mAttributeName, glslVersion>= 300 ? feedback:null );
|
|
411 |
programHandle = createAndLinkProgram(
|
|
412 |
vertShaderHandle,
|
|
413 |
fragShaderHandle,
|
|
414 |
mAttributeName,
|
|
415 |
if (glslVersion >= 300) feedback else null
|
|
416 |
)
|
477 |
417 |
|
478 |
|
setUpAttributes();
|
479 |
|
setUpUniforms();
|
|
418 |
setUpAttributes()
|
|
419 |
setUpUniforms()
|
480 |
420 |
}
|
481 |
421 |
|
482 |
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
483 |
|
/**
|
484 |
|
* Only for use by the library itself.
|
485 |
|
*
|
486 |
|
* @y.exclude
|
487 |
|
*/
|
488 |
|
public DistortedProgram(final InputStream vert, final InputStream frag, final String vertHeader, final String fragHeader,
|
489 |
|
final String enabledVert, final String enabledFrag, int glslVersion, final String[] feedback )
|
490 |
|
throws FragmentCompilationException,VertexCompilationException,LinkingException
|
|
422 |
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
423 |
/** Only for use by the library itself.
|
|
424 |
*
|
|
425 |
* @y.exclude
|
|
426 |
*/
|
|
427 |
constructor(vert: InputStream, frag: InputStream, vertHeader: String, fragHeader: String,
|
|
428 |
enabledVert: String?, enabledFrag: String?, glslVersion: Int, feedback: Array<String?>?)
|
491 |
429 |
{
|
492 |
|
init(glslVersion);
|
|
430 |
init(glslVersion)
|
493 |
431 |
|
494 |
|
String vertShader = readTextFileFromRawResource( vert, true );
|
495 |
|
String fragShader = readTextFileFromRawResource( frag, false);
|
|
432 |
var vertShader = readTextFileFromRawResource(vert, true)
|
|
433 |
var fragShader = readTextFileFromRawResource(frag, false)
|
496 |
434 |
|
497 |
|
if( enabledVert!=null ) vertShader = insertEnabledEffects(vertShader,enabledVert);
|
498 |
|
if( enabledFrag!=null ) fragShader = insertEnabledEffects(fragShader,enabledFrag);
|
|
435 |
if (enabledVert != null) vertShader = insertEnabledEffects(vertShader!!, enabledVert)
|
|
436 |
if (enabledFrag != null) fragShader = insertEnabledEffects(fragShader!!, enabledFrag)
|
499 |
437 |
|
500 |
|
final int vertShaderHandle = compileShader(GLES30.GL_VERTEX_SHADER , vertHeader + vertShader);
|
501 |
|
final int fragShaderHandle = compileShader(GLES30.GL_FRAGMENT_SHADER, fragHeader + fragShader);
|
|
438 |
val vertShaderHandle = compileShader(GLES30.GL_VERTEX_SHADER , vertHeader + vertShader)
|
|
439 |
val fragShaderHandle = compileShader(GLES30.GL_FRAGMENT_SHADER, fragHeader + fragShader)
|
502 |
440 |
|
503 |
|
mProgramHandle = createAndLinkProgram(vertShaderHandle, fragShaderHandle, mAttributeName, glslVersion>= 300 ? feedback:null );
|
|
441 |
programHandle = createAndLinkProgram(
|
|
442 |
vertShaderHandle,
|
|
443 |
fragShaderHandle,
|
|
444 |
mAttributeName,
|
|
445 |
if (glslVersion >= 300) feedback else null
|
|
446 |
)
|
504 |
447 |
|
505 |
|
setUpAttributes();
|
506 |
|
setUpUniforms();
|
|
448 |
setUpAttributes()
|
|
449 |
setUpUniforms()
|
507 |
450 |
}
|
508 |
451 |
|
509 |
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
510 |
|
/**
|
511 |
|
* Only for use by the library itself.
|
512 |
|
*
|
513 |
|
* @y.exclude
|
514 |
|
*/
|
515 |
|
public DistortedProgram(final InputStream vertex, final InputStream fragment, final String vertexHeader, final String fragmentHeader, int glslVersion )
|
516 |
|
throws FragmentCompilationException,VertexCompilationException,LinkingException
|
|
452 |
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
453 |
/** Only for use by the library itself.
|
|
454 |
*
|
|
455 |
* @y.exclude
|
|
456 |
*/
|
|
457 |
constructor( vert: InputStream, frag: InputStream, vertHeader: String, fragHeader: String, glslVersion: Int) :
|
|
458 |
this(vert, frag, vertHeader, fragHeader, glslVersion, null)
|
|
459 |
|
|
460 |
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
461 |
// PUBLIC API
|
|
462 |
/** Create a new Shader Program from two source strings.
|
|
463 |
*
|
|
464 |
* Needs to be called from a thread holding the OpenGL context.
|
|
465 |
*
|
|
466 |
* @param vert Vertex shader code.
|
|
467 |
* @param frag Fragment shader code.
|
|
468 |
* @throws FragmentCompilationException fragment shader failed to compile
|
|
469 |
* @throws VertexCompilationException vertex shader failed to compile
|
|
470 |
* @throws LinkingException shaders failed to link
|
|
471 |
*/
|
|
472 |
constructor(vert: String, frag: String)
|
517 |
473 |
{
|
518 |
|
this(vertex,fragment,vertexHeader,fragmentHeader,glslVersion,null);
|
519 |
|
}
|
|
474 |
init(300)
|
520 |
475 |
|
521 |
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
522 |
|
// PUBLIC API
|
523 |
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
524 |
|
/**
|
525 |
|
* Create a new Shader Program from two source strings.
|
526 |
|
* <p>
|
527 |
|
* Needs to be called from a thread holding the OpenGL context.
|
528 |
|
*
|
529 |
|
* @param vertex Vertex shader code.
|
530 |
|
* @param fragment Fragment shader code.
|
531 |
|
* @throws FragmentCompilationException fragment shader failed to compile
|
532 |
|
* @throws VertexCompilationException vertex shader failed to compile
|
533 |
|
* @throws LinkingException shaders failed to link
|
534 |
|
*/
|
535 |
|
public DistortedProgram(final String vertex, final String fragment)
|
536 |
|
throws FragmentCompilationException,VertexCompilationException,LinkingException
|
537 |
|
{
|
538 |
|
init(300);
|
|
476 |
doAttributes(vert, true)
|
|
477 |
doAttributes(frag, false)
|
539 |
478 |
|
540 |
|
doAttributes(vertex , true );
|
541 |
|
doAttributes(fragment, false);
|
|
479 |
val vertHandle = compileShader(GLES30.GL_VERTEX_SHADER , vert)
|
|
480 |
val fragHandle = compileShader(GLES30.GL_FRAGMENT_SHADER, frag)
|
542 |
481 |
|
543 |
|
final int vertexShaderHandle = compileShader(GLES30.GL_VERTEX_SHADER , vertex );
|
544 |
|
final int fragmentShaderHandle = compileShader(GLES30.GL_FRAGMENT_SHADER, fragment);
|
|
482 |
programHandle = createAndLinkProgram(vertHandle, fragHandle, mAttributeName, null)
|
545 |
483 |
|
546 |
|
mProgramHandle = createAndLinkProgram(vertexShaderHandle, fragmentShaderHandle, mAttributeName, null );
|
547 |
|
|
548 |
|
setUpAttributes();
|
549 |
|
setUpUniforms();
|
|
484 |
setUpAttributes()
|
|
485 |
setUpUniforms()
|
550 |
486 |
}
|
551 |
487 |
|
552 |
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
553 |
|
/**
|
554 |
|
* Return the handle of the created program so that we can later, say, call glUseProgram.
|
555 |
|
*/
|
556 |
|
public int getProgramHandle()
|
|
488 |
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
489 |
/** Return the handle of the created program so that we can later, say, call glUseProgram.
|
|
490 |
*
|
|
491 |
* Use the program and enable all vertex attribute arrays.
|
|
492 |
* Needs to be called from a thread holding the OpenGL context.
|
|
493 |
*/
|
|
494 |
fun useProgram()
|
557 |
495 |
{
|
558 |
|
return mProgramHandle;
|
|
496 |
GLES30.glUseProgram(programHandle)
|
|
497 |
|
|
498 |
for (i in 0..<mNumAttributes)
|
|
499 |
GLES30.glEnableVertexAttribArray(mAttribute!![i])
|
559 |
500 |
}
|
560 |
501 |
|
561 |
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
562 |
|
/**
|
563 |
|
* Use the program and enable all vertex attribute arrays.
|
564 |
|
* Needs to be called from a thread holding the OpenGL context.
|
565 |
|
*/
|
566 |
|
public void useProgram()
|
|
502 |
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
503 |
/** Disable all vertex attribute arrays.
|
|
504 |
* Needs to be called from a thread holding the OpenGL context.
|
|
505 |
*/
|
|
506 |
fun stopUsingProgram()
|
567 |
507 |
{
|
568 |
|
GLES30.glUseProgram(mProgramHandle);
|
|
508 |
GLES30.glUseProgram(0)
|
569 |
509 |
|
570 |
|
for(int i=0; i<mNumAttributes; i++)
|
571 |
|
{
|
572 |
|
GLES30.glEnableVertexAttribArray(mAttribute[i]);
|
573 |
|
}
|
|
510 |
for (i in 0..<mNumAttributes)
|
|
511 |
GLES30.glDisableVertexAttribArray(mAttribute!![i])
|
574 |
512 |
}
|
575 |
513 |
|
576 |
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
577 |
|
/**
|
578 |
|
* Disable all vertex attribute arrays.
|
579 |
|
* Needs to be called from a thread holding the OpenGL context.
|
580 |
|
*/
|
581 |
|
public void stopUsingProgram()
|
|
514 |
companion object
|
582 |
515 |
{
|
583 |
|
GLES30.glUseProgram(0);
|
|
516 |
const val ATTR_LAYOUT_PNTC: Int = 0
|
|
517 |
const val ATTR_LAYOUT_PTC : Int = 1
|
|
518 |
const val ATTR_LAYOUT_PNT : Int = 2
|
|
519 |
const val ATTR_LAYOUT_PNC : Int = 3
|
|
520 |
const val ATTR_LAYOUT_PT : Int = 4
|
|
521 |
const val ATTR_LAYOUT_P : Int = 5
|
|
522 |
const val ATTR_LAYOUT_UNK : Int = 6
|
|
523 |
|
|
524 |
///////////////////////////////////////////////////////////////////////////////////////////
|
|
525 |
@Throws(FragmentCompilationException::class, VertexCompilationException::class)
|
|
526 |
private fun compileShader(shaderType: Int, shaderSource: String): Int
|
|
527 |
{
|
|
528 |
val shaderHandle = GLES30.glCreateShader(shaderType)
|
584 |
529 |
|
585 |
|
for(int i=0; i<mNumAttributes; i++)
|
586 |
|
{
|
587 |
|
GLES30.glDisableVertexAttribArray(mAttribute[i]);
|
588 |
|
}
|
|
530 |
if (shaderHandle != 0)
|
|
531 |
{
|
|
532 |
GLES30.glShaderSource(shaderHandle, shaderSource)
|
|
533 |
GLES30.glCompileShader(shaderHandle)
|
|
534 |
val compileStatus = IntArray(1)
|
|
535 |
GLES30.glGetShaderiv(shaderHandle, GLES30.GL_COMPILE_STATUS, compileStatus, 0)
|
|
536 |
|
|
537 |
if (compileStatus[0] != GLES30.GL_TRUE)
|
|
538 |
{
|
|
539 |
val error = GLES30.glGetShaderInfoLog(shaderHandle)
|
|
540 |
|
|
541 |
GLES30.glDeleteShader(shaderHandle)
|
|
542 |
|
|
543 |
when (shaderType)
|
|
544 |
{
|
|
545 |
GLES30.GL_VERTEX_SHADER -> throw VertexCompilationException(error)
|
|
546 |
GLES30.GL_FRAGMENT_SHADER -> throw FragmentCompilationException(error)
|
|
547 |
else -> throw RuntimeException(error)
|
|
548 |
}
|
|
549 |
}
|
|
550 |
}
|
|
551 |
|
|
552 |
return shaderHandle
|
|
553 |
}
|
|
554 |
|
|
555 |
///////////////////////////////////////////////////////////////////////////////////////////
|
|
556 |
private fun insertEnabledEffects(code: String, effects: String): String?
|
|
557 |
{
|
|
558 |
val marker = "// ENABLED EFFECTS WILL BE INSERTED HERE"
|
|
559 |
val length = marker.length
|
|
560 |
val place = code.indexOf(marker)
|
|
561 |
|
|
562 |
if (place >= 0)
|
|
563 |
{
|
|
564 |
val beg = code.substring(0, place-1)
|
|
565 |
val end = code.substring(place+length)
|
|
566 |
return beg+effects+end
|
|
567 |
}
|
|
568 |
else DistortedLibrary.logMessage("DistortedProgram: Error: marker string not found in SHADER!")
|
|
569 |
|
|
570 |
return null
|
|
571 |
}
|
589 |
572 |
}
|
590 |
|
}
|
|
573 |
}
|
591 |
574 |
|
592 |
575 |
|
the 'program' package converted to Kotlin.