JOGL v2.6.0-rc-20250712
JOGL, High-Performance Graphics Binding for Java™ (public API).
ShaderUtil.java
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * - Redistribution of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * - Redistribution in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * Neither the name of Sun Microsystems, Inc. or the names of
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * This software is provided "AS IS," without a warranty of any kind. ALL
20 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
21 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
22 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
23 * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
24 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
25 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
26 * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
27 * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
28 * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
29 * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
30 * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31 *
32 */
33
34package com.jogamp.opengl.util.glsl;
35
36import java.io.PrintStream;
37import java.nio.*;
38import java.util.*;
39
40import com.jogamp.opengl.*;
41
42import com.jogamp.common.nio.Buffers;
43import com.jogamp.opengl.GLExtensions;
44
45public final class ShaderUtil {
46 public static String getShaderInfoLog(final GL _gl, final int shaderObj) {
47 final GL2ES2 gl = _gl.getGL2ES2();
48 final int[] infoLogLength=new int[1];
49 gl.glGetShaderiv(shaderObj, GL2ES2.GL_INFO_LOG_LENGTH, infoLogLength, 0);
50
51 if(infoLogLength[0]==0) {
52 return "(no info log)";
53 }
54 final int[] charsWritten=new int[1];
55 final byte[] infoLogBytes = new byte[infoLogLength[0]];
56 gl.glGetShaderInfoLog(shaderObj, infoLogLength[0], charsWritten, 0, infoLogBytes, 0);
57
58 return new String(infoLogBytes, 0, charsWritten[0]);
59 }
60
61 public static String getProgramInfoLog(final GL _gl, final int programObj) {
62 final GL2ES2 gl = _gl.getGL2ES2();
63 final int[] infoLogLength=new int[1];
64 gl.glGetProgramiv(programObj, GL2ES2.GL_INFO_LOG_LENGTH, infoLogLength, 0);
65
66 if(infoLogLength[0]==0) {
67 return "(no info log)";
68 }
69 final int[] charsWritten=new int[1];
70 final byte[] infoLogBytes = new byte[infoLogLength[0]];
71 gl.glGetProgramInfoLog(programObj, infoLogLength[0], charsWritten, 0, infoLogBytes, 0);
72
73 return new String(infoLogBytes, 0, charsWritten[0]);
74 }
75
76 public static boolean isShaderStatusValid(final GL _gl, final int shaderObj, final int name, final PrintStream verboseOut) {
77 final GL2ES2 gl = _gl.getGL2ES2();
78 final int[] ires = new int[1];
79 gl.glGetShaderiv(shaderObj, name, ires, 0);
80
81 final boolean res = ires[0]==1;
82 if(!res && null!=verboseOut) {
83 verboseOut.println("Shader status invalid: "+ getShaderInfoLog(gl, shaderObj));
84 }
85 return res;
86 }
87
88 public static boolean isShaderStatusValid(final GL _gl, final IntBuffer shaders, final int name, final PrintStream verboseOut) {
89 boolean res = true;
90 for (int i = shaders.position(); i < shaders.limit(); i++) {
91 res = isShaderStatusValid(_gl, shaders.get(i), name, verboseOut) && res;
92 }
93 return res;
94 }
95
96 public static boolean isProgramStatusValid(final GL _gl, final int programObj, final int name) {
97 final GL2ES2 gl = _gl.getGL2ES2();
98 final int[] ires = new int[1];
99 gl.glGetProgramiv(programObj, name, ires, 0);
100
101 return ires[0]==1;
102 }
103
104 public static boolean isProgramLinkStatusValid(final GL _gl, final int programObj, final PrintStream verboseOut) {
105 final GL2ES2 gl = _gl.getGL2ES2();
106 if(!gl.glIsProgram(programObj)) {
107 if(null!=verboseOut) {
108 verboseOut.println("Program name invalid: "+programObj);
109 }
110 return false;
111 }
112 if(!isProgramStatusValid(gl, programObj, GL2ES2.GL_LINK_STATUS)) {
113 if(null!=verboseOut) {
114 verboseOut.println("Program link failed: "+programObj+"\n\t"+ getProgramInfoLog(gl, programObj));
115 }
116 return false;
117 }
118 return true;
119 }
120
121 /**
122 * Performs {@link GL2ES2#glValidateProgram(int)}
123 * <p>
124 * One shall only call this method while debugging and only if all required
125 * resources by the shader are set.
126 * </p>
127 * <p>
128 * Note: It is possible that a working shader program will fail validation.
129 * This has been experienced on NVidia APX2500 and Tegra2.
130 * </p>
131 * @see GL2ES2#glValidateProgram(int)
132 **/
133 public static boolean isProgramExecStatusValid(final GL _gl, final int programObj, final PrintStream verboseOut) {
134 final GL2ES2 gl = _gl.getGL2ES2();
135 gl.glValidateProgram(programObj);
136 if(!isProgramStatusValid(gl, programObj, GL2ES2.GL_VALIDATE_STATUS)) {
137 if(null!=verboseOut) {
138 verboseOut.println("Program validation failed: "+programObj+"\n\t"+ getProgramInfoLog(gl, programObj));
139 }
140 return false;
141 }
142 return true;
143 }
144
145 public static void createShader(final GL _gl, final int type, final IntBuffer shaders) {
146 final GL2ES2 gl = _gl.getGL2ES2();
147 for (int i = shaders.position(); i < shaders.limit(); i++) {
148 shaders.put(i, gl.glCreateShader(type));
149 }
150 }
151
152 /**
153 * If supported, queries the natively supported shader binary formats using
154 * {@link GL2ES2#GL_NUM_SHADER_BINARY_FORMATS} and {@link GL2ES2#GL_SHADER_BINARY_FORMATS}
155 * via {@link GL2ES2#glGetIntegerv(int, int[], int)}.
156 */
157 public static Set<Integer> getShaderBinaryFormats(final GL _gl) {
158 final GL2ES2 gl = _gl.getGL2ES2();
159 final ProfileInformation info = getProfileInformation(gl);
160 if(null == info.shaderBinaryFormats) {
161 info.shaderBinaryFormats = new HashSet<Integer>();
162 if (gl.isGLES2Compatible()) {
163 try {
164 final int[] param = new int[1];
166 final int err = gl.glGetError();
167 final int numFormats = GL.GL_NO_ERROR == err ? param[0] : 0;
168 if(numFormats>0) {
169 final int[] formats = new int[numFormats];
171 for(int i=0; i<numFormats; i++) {
172 info.shaderBinaryFormats.add(Integer.valueOf(formats[i]));
173 }
174 }
175 } catch (final GLException gle) {
176 System.err.println("Caught exception on thread "+Thread.currentThread().getName());
177 gle.printStackTrace();
178 }
179 }
180 }
181 return info.shaderBinaryFormats;
182 }
183
184 /** Returns true if a hader compiler is available, otherwise false. */
185 public static boolean isShaderCompilerAvailable(final GL _gl) {
186 final GL2ES2 gl = _gl.getGL2ES2();
187 final ProfileInformation info = getProfileInformation(gl);
188 if(null==info.shaderCompilerAvailable) {
189 if(gl.isGLES2()) {
190 boolean queryOK = false;
191 try {
192 final byte[] param = new byte[1];
194 final int err = gl.glGetError();
195 boolean v = GL.GL_NO_ERROR == err && param[0]!=(byte)0x00;
196 if(!v) {
197 final Set<Integer> bfs = getShaderBinaryFormats(gl);
198 if(bfs.size()==0) {
199 // no supported binary formats, hence a compiler must be available!
200 v = true;
201 }
202 }
203 info.shaderCompilerAvailable = Boolean.valueOf(v);
204 queryOK = true;
205 } catch (final GLException gle) {
206 System.err.println("Caught exception on thread "+Thread.currentThread().getName());
207 gle.printStackTrace();
208 }
209 if(!queryOK) {
210 info.shaderCompilerAvailable = Boolean.valueOf(true);
211 }
212 } else if( gl.isGL2ES2() ) {
213 info.shaderCompilerAvailable = new Boolean(true);
214 } else {
215 throw new GLException("Invalid OpenGL profile");
216 }
217 }
218 return info.shaderCompilerAvailable.booleanValue();
219 }
220
221 /** Returns true if GeometryShader is supported, i.e. whether GLContext is &ge; 3.2 or ARB_geometry_shader4 extension is available. */
222 public static boolean isGeometryShaderSupported(final GL _gl) {
223 final GLContext ctx = _gl.getContext();
224 return ctx.getGLVersionNumber().compareTo(GLContext.Version3_2) >= 0 ||
226 }
227
228 public static void shaderSource(final GL _gl, final int shader, final CharSequence[] source)
229 {
230 final GL2ES2 gl = _gl.getGL2ES2();
231 if(!isShaderCompilerAvailable(_gl)) {
232 throw new GLException("No compiler is available");
233 }
234
235 final int count = (null!=source)?source.length:0;
236 if(count==0) {
237 throw new GLException("No sources specified");
238 }
239
240 final IntBuffer lengths = Buffers.newDirectIntBuffer(count);
241 for(int i=0; i<count; i++) {
242 lengths.put(i, source[i].length());
243 }
244 if(source instanceof String[]) {
245 // rare case ..
246 gl.glShaderSource(shader, count, (String[])source, lengths);
247 } else {
248 final String[] tmp = new String[source.length];
249 for(int i = source.length - 1; i>=0; i--) {
250 final CharSequence csq = source[i];
251 if(csq instanceof String) {
252 // if ShaderCode.create(.. mutableStringBuilder == false )
253 tmp[i] = (String) csq;
254 } else {
255 // if ShaderCode.create(.. mutableStringBuilder == true )
256 tmp[i] = source[i].toString();
257 }
258 }
259 gl.glShaderSource(shader, count, tmp, lengths);
260 }
261 }
262
263 public static void shaderSource(final GL _gl, final IntBuffer shaders, final CharSequence[][] sources)
264 {
265 final int sourceNum = (null!=sources)?sources.length:0;
266 final int shaderNum = (null!=shaders)?shaders.remaining():0;
267 if(shaderNum<=0 || sourceNum<=0 || shaderNum!=sourceNum) {
268 throw new GLException("Invalid number of shaders and/or sources: shaders="+
269 shaderNum+", sources="+sourceNum);
270 }
271 for(int i=0; i<sourceNum; i++) {
272 shaderSource(_gl, shaders.get(shaders.position() + i), sources[i]);
273 }
274 }
275
276 public static void shaderBinary(final GL _gl, final IntBuffer shaders, final int binFormat, final java.nio.Buffer bin)
277 {
278 final GL2ES2 gl = _gl.getGL2ES2();
279 if(getShaderBinaryFormats(gl).size()<=0) {
280 throw new GLException("No binary formats are supported");
281 }
282
283 final int shaderNum = shaders.remaining();
284 if(shaderNum<=0) {
285 throw new GLException("No shaders specified");
286 }
287 if(null==bin) {
288 throw new GLException("Null shader binary");
289 }
290 final int binLength = bin.remaining();
291 if(0>=binLength) {
292 throw new GLException("Empty shader binary (remaining == 0)");
293 }
294 gl.glShaderBinary(shaderNum, shaders, binFormat, bin, binLength);
295 }
296
297 public static void compileShader(final GL _gl, final IntBuffer shaders)
298 {
299 final GL2ES2 gl = _gl.getGL2ES2();
300 for (int i = shaders.position(); i < shaders.limit(); i++) {
301 gl.glCompileShader(shaders.get(i));
302 }
303 }
304
305 public static void attachShader(final GL _gl, final int program, final IntBuffer shaders)
306 {
307 final GL2ES2 gl = _gl.getGL2ES2();
308 for (int i = shaders.position(); i < shaders.limit(); i++) {
309 gl.glAttachShader(program, shaders.get(i));
310 }
311 }
312
313 public static void detachShader(final GL _gl, final int program, final IntBuffer shaders)
314 {
315 final GL2ES2 gl = _gl.getGL2ES2();
316 for (int i = shaders.position(); i < shaders.limit(); i++) {
317 gl.glDetachShader(program, shaders.get(i));
318 }
319 }
320
321 public static void deleteShader(final GL _gl, final IntBuffer shaders)
322 {
323 final GL2ES2 gl = _gl.getGL2ES2();
324 for (int i = shaders.position(); i < shaders.limit(); i++) {
325 gl.glDeleteShader(shaders.get(i));
326
327 }
328 }
329
330 public static boolean createAndLoadShader(final GL _gl, final IntBuffer shader, final int shaderType,
331 final int binFormat, final java.nio.Buffer bin,
332 final PrintStream verboseOut)
333 {
334 final GL2ES2 gl = _gl.getGL2ES2();
335 int err = gl.glGetError(); // flush previous errors ..
336 if(err!=GL.GL_NO_ERROR && null!=verboseOut) {
337 verboseOut.println("createAndLoadShader: Pre GL Error: 0x"+Integer.toHexString(err));
338 }
339
340 createShader(gl, shaderType, shader);
341 err = gl.glGetError();
342 if(err!=GL.GL_NO_ERROR) {
343 throw new GLException("createAndLoadShader: CreateShader failed, GL Error: 0x"+Integer.toHexString(err));
344 }
345
346 shaderBinary(gl, shader, binFormat, bin);
347
348 err = gl.glGetError();
349 if(err!=GL.GL_NO_ERROR && null!=verboseOut) {
350 verboseOut.println("createAndLoadShader: ShaderBinary failed, GL Error: 0x"+Integer.toHexString(err));
351 }
352 return err == GL.GL_NO_ERROR;
353 }
354
355 public static boolean createAndCompileShader(final GL _gl, final IntBuffer shader, final int shaderType,
356 final CharSequence[][] sources,
357 final PrintStream verboseOut)
358 {
359 final GL2ES2 gl = _gl.getGL2ES2();
360 int err = gl.glGetError(); // flush previous errors ..
361 if(err!=GL.GL_NO_ERROR && null!=verboseOut) {
362 verboseOut.println("createAndCompileShader: Pre GL Error: 0x"+Integer.toHexString(err));
363 }
364
365 createShader(gl, shaderType, shader);
366 err = gl.glGetError();
367 if(err!=GL.GL_NO_ERROR) {
368 throw new GLException("createAndCompileShader: CreateShader failed, GL Error: 0x"+Integer.toHexString(err));
369 }
370
371 shaderSource(gl, shader, sources);
372 err = gl.glGetError();
373 if(err!=GL.GL_NO_ERROR) {
374 throw new GLException("createAndCompileShader: ShaderSource failed, GL Error: 0x"+Integer.toHexString(err));
375 }
376
377 compileShader(gl, shader);
378 err = gl.glGetError();
379 if(err!=GL.GL_NO_ERROR && null!=verboseOut) {
380 verboseOut.println("createAndCompileShader: CompileShader failed, GL Error: 0x"+Integer.toHexString(err));
381 }
382
383 return isShaderStatusValid(gl, shader, GL2ES2.GL_COMPILE_STATUS, verboseOut) && err == GL.GL_NO_ERROR;
384 }
385
386 private static final String implObjectKey = "com.jogamp.opengl.util.glsl.ShaderUtil" ;
387
388 private static class ProfileInformation {
389 Boolean shaderCompilerAvailable = null;
390 Set<Integer> shaderBinaryFormats = null;
391 }
392
393 private static ProfileInformation getProfileInformation(final GL gl) {
394 final GLContext context = gl.getContext();
395 context.validateCurrent();
396 ProfileInformation data = (ProfileInformation) context.getAttachedObject(implObjectKey);
397 if (data == null) {
398 data = new ProfileInformation();
399 context.attachObject(implObjectKey, data);
400 }
401 return data;
402 }
403}
Abstraction for an OpenGL rendering context.
Definition: GLContext.java:74
final Object getAttachedObject(final String name)
Returns the attached user object for the given name to this GLContext.
Definition: GLContext.java:611
final Object attachObject(final String name, final Object obj)
Sets the attached user object for the given name to this GLContext.
Definition: GLContext.java:619
static final VersionNumber Version3_2
Version 3.2.
Definition: GLContext.java:150
final VersionNumber getGLVersionNumber()
Returns this context OpenGL version.
Definition: GLContext.java:777
abstract boolean isExtensionAvailable(String glExtensionName)
Returns true if the specified OpenGL extension can be successfully called using this GL context given...
A generic exception for OpenGL errors used throughout the binding as a substitute for RuntimeExceptio...
Class holding OpenGL extension strings, commonly used by JOGL's implementation.
static final String ARB_geometry_shader4
static boolean createAndLoadShader(final GL _gl, final IntBuffer shader, final int shaderType, final int binFormat, final java.nio.Buffer bin, final PrintStream verboseOut)
static boolean isShaderStatusValid(final GL _gl, final int shaderObj, final int name, final PrintStream verboseOut)
Definition: ShaderUtil.java:76
static String getShaderInfoLog(final GL _gl, final int shaderObj)
Definition: ShaderUtil.java:46
static void deleteShader(final GL _gl, final IntBuffer shaders)
static boolean isProgramExecStatusValid(final GL _gl, final int programObj, final PrintStream verboseOut)
Performs GL2ES2#glValidateProgram(int).
static boolean isGeometryShaderSupported(final GL _gl)
Returns true if GeometryShader is supported, i.e.
static boolean isProgramLinkStatusValid(final GL _gl, final int programObj, final PrintStream verboseOut)
static boolean isShaderCompilerAvailable(final GL _gl)
Returns true if a hader compiler is available, otherwise false.
static void attachShader(final GL _gl, final int program, final IntBuffer shaders)
static boolean isProgramStatusValid(final GL _gl, final int programObj, final int name)
Definition: ShaderUtil.java:96
static void compileShader(final GL _gl, final IntBuffer shaders)
static boolean isShaderStatusValid(final GL _gl, final IntBuffer shaders, final int name, final PrintStream verboseOut)
Definition: ShaderUtil.java:88
static String getProgramInfoLog(final GL _gl, final int programObj)
Definition: ShaderUtil.java:61
static Set< Integer > getShaderBinaryFormats(final GL _gl)
If supported, queries the natively supported shader binary formats using GL2ES2#GL_NUM_SHADER_BINARY_...
static void shaderSource(final GL _gl, final int shader, final CharSequence[] source)
static void createShader(final GL _gl, final int type, final IntBuffer shaders)
static void shaderBinary(final GL _gl, final IntBuffer shaders, final int binFormat, final java.nio.Buffer bin)
static void shaderSource(final GL _gl, final IntBuffer shaders, final CharSequence[][] sources)
static boolean createAndCompileShader(final GL _gl, final IntBuffer shader, final int shaderType, final CharSequence[][] sources, final PrintStream verboseOut)
static void detachShader(final GL _gl, final int program, final IntBuffer shaders)
void glGetProgramiv(int program, int pname, IntBuffer params)
Entry point to C language function: void {@native glGetProgramiv}(GLuint program,...
void glCompileShader(int shader)
Entry point to C language function: void {@native glCompileShader}(GLuint shader) Part of GL_ES_VE...
static final int GL_LINK_STATUS
GL_ES_VERSION_2_0, GL_VERSION_2_0 Define "GL_LINK_STATUS" with expression '0x8B82',...
Definition: GL2ES2.java:358
void glDeleteShader(int shader)
Entry point to C language function: void {@native glDeleteShader}(GLuint shader) Part of GL_ES_VER...
void glValidateProgram(int program)
Entry point to C language function: void {@native glValidateProgram}(GLuint program) Part of GL_ES...
void glGetProgramInfoLog(int program, int bufSize, IntBuffer length, ByteBuffer infoLog)
Entry point to C language function: void {@native glGetProgramInfoLog}(GLuint program,...
void glDetachShader(int program, int shader)
Entry point to C language function: void {@native glDetachShader}(GLuint program,...
static final int GL_NUM_SHADER_BINARY_FORMATS
GL_ARB_ES2_compatibility, GL_ES_VERSION_2_0, GL_VERSION_4_1 Define "GL_NUM_SHADER_BINARY_FORMATS" wit...
Definition: GL2ES2.java:468
void glShaderBinary(int n, IntBuffer shaders, int binaryformat, Buffer binary, int length)
Entry point to C language function: void {@native glShaderBinary}(GLint n, const GLuint * shaders,...
static final int GL_COMPILE_STATUS
GL_ES_VERSION_2_0, GL_VERSION_2_0 Define "GL_COMPILE_STATUS" with expression '0x8B81',...
Definition: GL2ES2.java:72
static final int GL_VALIDATE_STATUS
GL_ES_VERSION_2_0, GL_VERSION_2_0 Define "GL_VALIDATE_STATUS" with expression '0x8B83',...
Definition: GL2ES2.java:207
static final int GL_SHADER_BINARY_FORMATS
GL_ARB_ES2_compatibility, GL_ES_VERSION_2_0, GL_VERSION_4_1 Define "GL_SHADER_BINARY_FORMATS" with ex...
Definition: GL2ES2.java:116
boolean glIsProgram(int program)
Entry point to C language function: GLboolean {@native glIsProgram}(GLuint program) Part of GL_ES_...
void glGetShaderiv(int shader, int pname, IntBuffer params)
Entry point to C language function: void {@native glGetShaderiv}(GLuint shader, GLenum pname,...
static final int GL_SHADER_COMPILER
GL_ARB_ES2_compatibility, GL_ES_VERSION_2_0, GL_VERSION_4_1 Define "GL_SHADER_COMPILER" with expressi...
Definition: GL2ES2.java:308
void glShaderSource(int shader, int count, String[] string, IntBuffer length)
Entry point to C language function: void {@native glShaderSource}(GLuint shader, GLsizei count,...
void glAttachShader(int program, int shader)
Entry point to C language function: void {@native glAttachShader}(GLuint program,...
int glCreateShader(int type)
Entry point to C language function: GLuint {@native glCreateShader}(GLenum type) Part of GL_ES_VER...
void glGetShaderInfoLog(int shader, int bufSize, IntBuffer length, ByteBuffer infoLog)
Entry point to C language function: void {@native glGetShaderInfoLog}(GLuint shader,...
static final int GL_INFO_LOG_LENGTH
GL_ES_VERSION_2_0, GL_VERSION_2_0 Define "GL_INFO_LOG_LENGTH" with expression '0x8B84',...
Definition: GL2ES2.java:379
boolean isGLES2Compatible()
Indicates whether this GL object is compatible with the core OpenGL ES2 functionality.
GL2ES2 getGL2ES2()
Casts this object to the GL2ES2 interface.
boolean isGL2ES2()
Indicates whether this GL object conforms to a GL2ES2 compatible profile.
GLContext getContext()
Returns the GLContext associated which this GL object.
boolean isGLES2()
Indicates whether this GL object conforms to the OpenGL ES ≥ 2.0 profile.
void glGetIntegerv(int pname, IntBuffer data)
Entry point to C language function: void {@native glGetIntegerv}(GLenum pname, GLint * data) Part ...
void glGetBooleanv(int pname, ByteBuffer data)
Entry point to C language function: void {@native glGetBooleanv}(GLenum pname, GLboolean * data) P...
static final int GL_NO_ERROR
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_NO_ERROR" with expres...
Definition: GL.java:481
int glGetError()
Entry point to C language function: GLenum {@native glGetError}() Part of GL_ES_VERSION_2_0,...