/** * Gets the location of a shader attribute.<br> * Uses either the cached value {@link #getCachedAttribLocation(String)} if valid, or the GLSL * queried via {@link GL2ES2#glGetAttribLocation(int, String)}.<br> * The location will be cached. * * @return -1 if there is no such attribute available, otherwise >= 0 * @throws GLException if no program is attached * @throws GLException if the program is not linked and no location was cached. * @see #getCachedAttribLocation(String) * @see #bindAttribLocation(GL2ES2, int, GLArrayData) * @see #bindAttribLocation(GL2ES2, int, String) * @see GL2ES2#glGetAttribLocation(int, String) */ public int getAttribLocation(GL2ES2 gl, String name) { if (null == shaderProgram) throw new GLException("No program is attached"); int location = getCachedAttribLocation(name); if (0 > location) { if (!shaderProgram.linked()) throw new GLException("Program is not linked"); location = gl.glGetAttribLocation(shaderProgram.program(), name); if (0 <= location) { Integer idx = new Integer(location); activeAttribLocationMap.put(name, idx); if (DEBUG) { System.err.println("ShaderState: glGetAttribLocation: " + name + ", loc: " + location); } } else if (verbose) { System.err.println( "ShaderState: glGetAttribLocation failed, no location for: " + name + ", loc: " + location); if (DEBUG) { Thread.dumpStack(); } } } return location; }
public void init(GLAutoDrawable drawable) { drawable.setAutoSwapBufferMode(false); GL2ES2 gl = drawable.getGL().getGL2ES2(); System.err.println("Entering initialization"); System.err.println("GL_VERSION=" + gl.glGetString(gl.GL_VERSION)); System.err.println("GL_EXTENSIONS:"); System.err.println(" " + gl.glGetString(gl.GL_EXTENSIONS)); pmvMatrix = new PMVMatrix(); pmod.initShaderState(gl); st = ShaderState.getCurrent(); // Push the 1st uniform down the path st.glUseProgram(gl, true); pmvMatrix.glMatrixMode(pmvMatrix.GL_PROJECTION); pmvMatrix.glLoadIdentity(); pmvMatrix.glMatrixMode(pmvMatrix.GL_MODELVIEW); pmvMatrix.glLoadIdentity(); if (!st.glUniform(gl, new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf()))) { throw new GLException("Error setting PMVMatrix in shader: " + st); } // OpenGL Render Settings gl.glClearColor(0, 0, 0, 1); gl.glEnable(GL2ES2.GL_DEPTH_TEST); st.glUseProgram(gl, false); // Let's show the completed shader state .. System.out.println(st); }
/** Returns true if a hader compiler is available, otherwise false. */ public static boolean isShaderCompilerAvailable(final GL _gl) { final GL2ES2 gl = _gl.getGL2ES2(); final ProfileInformation info = getProfileInformation(gl); if (null == info.shaderCompilerAvailable) { if (gl.isGLES2()) { boolean queryOK = false; try { final byte[] param = new byte[1]; gl.glGetBooleanv(GL2ES2.GL_SHADER_COMPILER, param, 0); final int err = gl.glGetError(); boolean v = GL.GL_NO_ERROR == err && param[0] != (byte) 0x00; if (!v) { final Set<Integer> bfs = getShaderBinaryFormats(gl); if (bfs.size() == 0) { // no supported binary formats, hence a compiler must be available! v = true; } } info.shaderCompilerAvailable = Boolean.valueOf(v); queryOK = true; } catch (final GLException gle) { System.err.println("Caught exception on thread " + Thread.currentThread().getName()); gle.printStackTrace(); } if (!queryOK) { info.shaderCompilerAvailable = Boolean.valueOf(true); } } else if (gl.isGL2ES2()) { info.shaderCompilerAvailable = new Boolean(true); } else { throw new GLException("Invalid OpenGL profile"); } } return info.shaderCompilerAvailable.booleanValue(); }
/** * If supported, queries the natively supported shader binary formats using {@link * GL2ES2#GL_NUM_SHADER_BINARY_FORMATS} and {@link GL2ES2#GL_SHADER_BINARY_FORMATS} via {@link * GL2ES2#glGetIntegerv(int, int[], int)}. */ public static Set<Integer> getShaderBinaryFormats(final GL _gl) { final GL2ES2 gl = _gl.getGL2ES2(); final ProfileInformation info = getProfileInformation(gl); if (null == info.shaderBinaryFormats) { info.shaderBinaryFormats = new HashSet<Integer>(); if (gl.isGLES2Compatible()) { try { final int[] param = new int[1]; gl.glGetIntegerv(GL2ES2.GL_NUM_SHADER_BINARY_FORMATS, param, 0); final int err = gl.glGetError(); final int numFormats = GL.GL_NO_ERROR == err ? param[0] : 0; if (numFormats > 0) { final int[] formats = new int[numFormats]; gl.glGetIntegerv(GL2ES2.GL_SHADER_BINARY_FORMATS, formats, 0); for (int i = 0; i < numFormats; i++) { info.shaderBinaryFormats.add(Integer.valueOf(formats[i])); } } } catch (final GLException gle) { System.err.println("Caught exception on thread " + Thread.currentThread().getName()); gle.printStackTrace(); } } } return info.shaderBinaryFormats; }
public static void shaderSource(final GL _gl, final int shader, final CharSequence[] source) { final GL2ES2 gl = _gl.getGL2ES2(); if (!isShaderCompilerAvailable(_gl)) { throw new GLException("No compiler is available"); } final int count = (null != source) ? source.length : 0; if (count == 0) { throw new GLException("No sources specified"); } final IntBuffer lengths = Buffers.newDirectIntBuffer(count); for (int i = 0; i < count; i++) { lengths.put(i, source[i].length()); } if (source instanceof String[]) { // rare case .. gl.glShaderSource(shader, count, (String[]) source, lengths); } else { final String[] tmp = new String[source.length]; for (int i = source.length - 1; i >= 0; i--) { final CharSequence csq = source[i]; if (csq instanceof String) { // if ShaderCode.create(.. mutableStringBuilder == false ) tmp[i] = (String) csq; } else { // if ShaderCode.create(.. mutableStringBuilder == true ) tmp[i] = source[i].toString(); } } gl.glShaderSource(shader, count, tmp, lengths); } }
public static boolean createAndLoadShader( final GL _gl, final IntBuffer shader, final int shaderType, final int binFormat, final java.nio.Buffer bin, final PrintStream verboseOut) { final GL2ES2 gl = _gl.getGL2ES2(); int err = gl.glGetError(); // flush previous errors .. if (err != GL.GL_NO_ERROR && null != verboseOut) { verboseOut.println("createAndLoadShader: Pre GL Error: 0x" + Integer.toHexString(err)); } createShader(gl, shaderType, shader); err = gl.glGetError(); if (err != GL.GL_NO_ERROR) { throw new GLException( "createAndLoadShader: CreateShader failed, GL Error: 0x" + Integer.toHexString(err)); } shaderBinary(gl, shader, binFormat, bin); err = gl.glGetError(); if (err != GL.GL_NO_ERROR && null != verboseOut) { verboseOut.println( "createAndLoadShader: ShaderBinary failed, GL Error: 0x" + Integer.toHexString(err)); } return err == GL.GL_NO_ERROR; }
public static boolean isProgramStatusValid(final GL _gl, final int programObj, final int name) { final GL2ES2 gl = _gl.getGL2ES2(); final int[] ires = new int[1]; gl.glGetProgramiv(programObj, name, ires, 0); return ires[0] == 1; }
public final boolean detachFrom(GL2ES2 gl) { RenderState _rs = (RenderState) gl.getContext().getAttachedObject(RenderState.class.getName()); if (_rs == this) { gl.getContext().detachObject(RenderState.class.getName()); return true; } return false; }
@Override public void reshape( final GLAutoDrawable glad, final int x, final int y, final int width, final int height) { final GL2ES2 gl = glad.getGL().getGL2ES2(); if (-1 != swapInterval) { gl.setSwapInterval(swapInterval); } reshapeImpl(gl, x, y, width, height, width, height); }
public static boolean isShaderStatusValid( final GL _gl, final int shaderObj, final int name, final PrintStream verboseOut) { final GL2ES2 gl = _gl.getGL2ES2(); final int[] ires = new int[1]; gl.glGetShaderiv(shaderObj, name, ires, 0); final boolean res = ires[0] == 1; if (!res && null != verboseOut) { verboseOut.println("Shader status invalid: " + getShaderInfoLog(gl, shaderObj)); } return res; }
@Override public void dispose(final GLAutoDrawable glad) { System.err.println( Thread.currentThread() + " RedSquareES2.dispose: tileRendererInUse " + tileRendererInUse); final GL2ES2 gl = glad.getGL().getGL2ES2(); if (!gl.hasGLSL()) { return; } st.destroy(gl); st = null; pmvMatrix = null; System.err.println(Thread.currentThread() + " RedSquareES2.dispose FIN"); }
@Override public void reshapeTile( final TileRendererBase tr, final int tileX, final int tileY, final int tileWidth, final int tileHeight, final int imageWidth, final int imageHeight) { final GL2ES2 gl = tr.getAttachedDrawable().getGL().getGL2ES2(); gl.setSwapInterval(0); reshapeImpl(gl, tileX, tileY, tileWidth, tileHeight, imageWidth, imageHeight); }
public static String getProgramInfoLog(final GL _gl, final int programObj) { final GL2ES2 gl = _gl.getGL2ES2(); final int[] infoLogLength = new int[1]; gl.glGetProgramiv(programObj, GL2ES2.GL_INFO_LOG_LENGTH, infoLogLength, 0); if (infoLogLength[0] == 0) { return "(no info log)"; } final int[] charsWritten = new int[1]; final byte[] infoLogBytes = new byte[infoLogLength[0]]; gl.glGetProgramInfoLog(programObj, infoLogLength[0], charsWritten, 0, infoLogBytes, 0); return new String(infoLogBytes, 0, charsWritten[0]); }
/** * Replace a shader in a program and re-links the program. * * @param gl * @param oldShader the to be replace Shader * @param newShader the new ShaderCode * @param verboseOut the optional verbose output stream * @return true if all steps are valid, shader compilation, attachment and linking; otherwise * false. * @see ShaderState#glEnableVertexAttribArray * @see ShaderState#glDisableVertexAttribArray * @see ShaderState#glVertexAttribPointer * @see ShaderState#getVertexAttribPointer * @see ShaderState#glReleaseAllVertexAttributes * @see ShaderState#glResetAllVertexAttributes * @see ShaderState#glResetAllVertexAttributes * @see ShaderState#glResetAllVertexAttributes */ public synchronized boolean replaceShader( GL2ES2 gl, ShaderCode oldShader, ShaderCode newShader, PrintStream verboseOut) { if (!init(gl) || !newShader.compile(gl, verboseOut)) { return false; } boolean shaderWasInUse = inUse(); if (shaderWasInUse) { useProgram(gl, false); } if (null != oldShader && allShaderCode.remove(oldShader)) { if (attachedShaderCode.remove(oldShader)) { ShaderUtil.detachShader(gl, shaderProgram, oldShader.shader()); } } add(newShader); if (attachedShaderCode.add(newShader)) { ShaderUtil.attachShader(gl, shaderProgram, newShader.shader()); } gl.glLinkProgram(shaderProgram); programLinked = ShaderUtil.isProgramLinkStatusValid(gl, shaderProgram, System.err); if (programLinked && shaderWasInUse) { useProgram(gl, true); } return programLinked; }
/** * Performs {@link GL2ES2#glValidateProgram(int)} * * <p>One shall only call this method while debugging and only if all required resources by the * shader are set. * * <p>Note: It is possible that a working shader program will fail validation. This has been * experienced on NVidia APX2500 and Tegra2. * * @see GL2ES2#glValidateProgram(int) */ public static boolean isProgramExecStatusValid( final GL _gl, final int programObj, final PrintStream verboseOut) { final GL2ES2 gl = _gl.getGL2ES2(); gl.glValidateProgram(programObj); if (!isProgramStatusValid(gl, programObj, GL2ES2.GL_VALIDATE_STATUS)) { if (null != verboseOut) { verboseOut.println( "Program validation failed: " + programObj + "\n\t" + getProgramInfoLog(gl, programObj)); } return false; } return true; }
/** * Binds a shader attribute to a location. Multiple names can be bound to one location. The value * will be cached and can be retrieved via {@link #getCachedAttribLocation(String)} before or * after linking. * * @throws GLException if no program is attached * @throws GLException if the program is already linked * @see javax.media.opengl.GL2ES2#glBindAttribLocation(int, int, String) * @see #getAttribLocation(GL2ES2, String) * @see #getCachedAttribLocation(String) */ public void bindAttribLocation(GL2ES2 gl, int location, String name) { if (null == shaderProgram) throw new GLException("No program is attached"); if (shaderProgram.linked()) throw new GLException("Program is already linked"); final Integer loc = new Integer(location); activeAttribLocationMap.put(name, loc); gl.glBindAttribLocation(shaderProgram.program(), location, name); }
public void display(GLAutoDrawable glad) { final GL2ES2 gl = glad.getGL().getGL2ES2(); if (multisample) { gl.glEnable(GL.GL_MULTISAMPLE); } gl.glClearColor(0, 0, 0, 0); // gl.glEnable(GL.GL_DEPTH_TEST); // gl.glDepthFunc(GL.GL_LESS); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); st.useProgram(gl, true); immModeSink.draw(gl, true); st.useProgram(gl, false); }
private void draw(GL2ES2 gl) { // gl.glClearColor(0.5f, 0.1f, 0.1f, 1); // gl.glClear(GL2ES2.GL_COLOR_BUFFER_BIT); shaderState.useProgram(gl, true); time.setData((System.currentTimeMillis() - millisOffset) / 1000.0f); shaderState.uniform(gl, time); vertices.enableBuffer(gl, true); gl.glDrawArrays(GL2ES2.GL_TRIANGLE_STRIP, 0, 4); vertices.enableBuffer(gl, false); shaderState.useProgram(gl, false); // Compute current framerate and printout. frameCount++; fcount += 1; int m = (int) (System.currentTimeMillis() - millisOffset); if (m - lastm > 1000 * fint) { frameRate = (float) (fcount) / fint; fcount = 0; lastm = m; } if (frameCount % TARGET_FPS == 0) { System.out.println("FrameCount: " + frameCount + " - " + "FrameRate: " + frameRate); } }
private void setup(GL2ES2 gl) { if (60 < TARGET_FPS) { // Disables vsync gl.setSwapInterval(0); } glu = new GLU(); vertShader = ShaderCode.create( gl, GL2ES2.GL_VERTEX_SHADER, LandscapeES2.class, "shader", "shader/bin", "landscape", true); fragShader = ShaderCode.create( gl, GL2ES2.GL_FRAGMENT_SHADER, LandscapeES2.class, "shader", "shader/bin", "landscape", true); vertShader.defaultShaderCustomization(gl, true, true); fragShader.defaultShaderCustomization(gl, true, true); shaderProg = new ShaderProgram(); shaderProg.add(gl, vertShader, System.err); shaderProg.add(gl, fragShader, System.err); shaderState = new ShaderState(); shaderState.attachShaderProgram(gl, shaderProg, true); resolution = new GLUniformData("iResolution", 3, FloatBuffer.wrap(new float[] {width, height, 0})); shaderState.ownUniform(resolution); shaderState.uniform(gl, resolution); time = new GLUniformData("iGlobalTime", 0.0f); shaderState.ownUniform(time); vertices = GLArrayDataServer.createGLSL("inVertex", 2, GL.GL_FLOAT, false, 4, GL.GL_STATIC_DRAW); vertices.putf(-1.0f); vertices.putf(-1.0f); vertices.putf(+1.0f); vertices.putf(-1.0f); vertices.putf(-1.0f); vertices.putf(+1.0f); vertices.putf(+1.0f); vertices.putf(+1.0f); vertices.seal(gl, true); shaderState.ownAttribute(vertices, true); shaderState.useProgram(gl, false); doneSetup = true; }
public static boolean isProgramLinkStatusValid( final GL _gl, final int programObj, final PrintStream verboseOut) { final GL2ES2 gl = _gl.getGL2ES2(); if (!gl.glIsProgram(programObj)) { if (null != verboseOut) { verboseOut.println("Program name invalid: " + programObj); } return false; } if (!isProgramStatusValid(gl, programObj, GL2ES2.GL_LINK_STATUS)) { if (null != verboseOut) { verboseOut.println( "Program link failed: " + programObj + "\n\t" + getProgramInfoLog(gl, programObj)); } return false; } return true; }
public static void shaderBinary( final GL _gl, final IntBuffer shaders, final int binFormat, final java.nio.Buffer bin) { final GL2ES2 gl = _gl.getGL2ES2(); if (getShaderBinaryFormats(gl).size() <= 0) { throw new GLException("No binary formats are supported"); } final int shaderNum = shaders.remaining(); if (shaderNum <= 0) { throw new GLException("No shaders specified"); } if (null == bin) { throw new GLException("Null shader binary"); } final int binLength = bin.remaining(); if (0 >= binLength) { throw new GLException("Empty shader binary (remaining == 0)"); } gl.glShaderBinary(shaderNum, shaders, binFormat, bin, binLength); }
/** * Disables all vertex attribute arrays. * * <p>Their enabled stated will be removed from this state only if 'removeFromState' is true. * * <p>This method purpose is more for debugging. * * @see #glEnableVertexAttribArray * @see #glDisableVertexAttribArray * @see #glVertexAttribPointer * @see #getVertexAttribPointer * @see #glReleaseAllVertexAttributes * @see #glResetAllVertexAttributes * @see #glResetAllVertexAttributes * @see ShaderProgram#glReplaceShader */ public void disableAllVertexAttributeArrays(GL2ES2 gl, boolean removeFromState) { for (Iterator<String> iter = activedAttribEnabledMap.keySet().iterator(); iter.hasNext(); ) { final String name = iter.next(); if (removeFromState) { activedAttribEnabledMap.remove(name); } final int index = getAttribLocation(gl, name); if (0 <= index) { gl.glDisableVertexAttribArray(index); } } }
private final void relocateAttribute(GL2ES2 gl, GLArrayData attribute) { // get new location .. final String name = attribute.getName(); final int loc = getAttribLocation(gl, name); attribute.setLocation(loc); if (0 <= loc) { if (isVertexAttribArrayEnabled(name)) { // enable attrib, VBO and pass location/data gl.glEnableVertexAttribArray(loc); } if (attribute.isVBO()) { gl.glBindBuffer(GL.GL_ARRAY_BUFFER, attribute.getVBOName()); gl.glVertexAttribPointer(attribute); gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0); } else { gl.glVertexAttribPointer(attribute); } } }
public void setStyle(GL2ES2 gl, LineStyle style) { gl.glUniform1f(this.handles.LINE_THICKNESS_PX, style.thickness_PX); gl.glUniform1f(this.handles.FEATHER_THICKNESS_PX, style.feather_PX); gl.glUniform1i(this.handles.JOIN_TYPE, style.joinType.value); gl.glUniform1f(this.handles.MITER_LIMIT, style.miterLimit); if (style.stippleEnable) { gl.glUniform1i(this.handles.STIPPLE_ENABLE, 1); gl.glUniform1f(this.handles.STIPPLE_SCALE, style.stippleScale); gl.glUniform1i(this.handles.STIPPLE_PATTERN, style.stipplePattern); } else { gl.glUniform1i(this.handles.STIPPLE_ENABLE, 0); } }
public synchronized void useProgram(GL2ES2 gl, boolean on) { if (!programLinked) { throw new GLException("Program is not linked"); } if (programInUse == on) { return; } if (0 == shaderProgram) { on = false; } gl.glUseProgram(on ? shaderProgram : 0); programInUse = on; }
public void end(GL2ES2 gl) { gl.glDisableVertexAttribArray(this.handles.inXy); gl.glDisableVertexAttribArray(this.handles.inFlags); gl.glDisableVertexAttribArray(this.handles.inMileage); gl.glDisableVertexAttribArray(this.handles.inRgba); gl.glUseProgram(0); gl.getGL3().glBindVertexArray(0); }
/** * Set the {@link GLArrayData} vertex attribute data. * * <p>This method uses the {@link GLArrayData}'s location if set. If data location is unset it * will be retrieved via {@link #getAttribLocation(GL2ES2, GLArrayData)}, set and cached in this * state. * * @return false, if the location could not be determined, otherwise true * @throws GLException if no program is attached * @throws GLException if the program is not linked and no location was cached. * @see #glEnableVertexAttribArray * @see #glDisableVertexAttribArray * @see #glVertexAttribPointer * @see #getVertexAttribPointer */ public boolean vertexAttribPointer(GL2ES2 gl, GLArrayData data) { int location = data.getLocation(); if (0 > location) { location = getAttribLocation(gl, data); } if (0 <= location) { // only pass the data, if the attribute exists in the current shader if (DEBUG) { System.err.println("ShaderState: glVertexAttribPointer: " + data); } gl.glVertexAttribPointer(data); return true; } return false; }
public static boolean createAndCompileShader( final GL _gl, final IntBuffer shader, final int shaderType, final CharSequence[][] sources, final PrintStream verboseOut) { final GL2ES2 gl = _gl.getGL2ES2(); int err = gl.glGetError(); // flush previous errors .. if (err != GL.GL_NO_ERROR && null != verboseOut) { verboseOut.println("createAndCompileShader: Pre GL Error: 0x" + Integer.toHexString(err)); } createShader(gl, shaderType, shader); err = gl.glGetError(); if (err != GL.GL_NO_ERROR) { throw new GLException( "createAndCompileShader: CreateShader failed, GL Error: 0x" + Integer.toHexString(err)); } shaderSource(gl, shader, sources); err = gl.glGetError(); if (err != GL.GL_NO_ERROR) { throw new GLException( "createAndCompileShader: ShaderSource failed, GL Error: 0x" + Integer.toHexString(err)); } compileShader(gl, shader); err = gl.glGetError(); if (err != GL.GL_NO_ERROR && null != verboseOut) { verboseOut.println( "createAndCompileShader: CompileShader failed, GL Error: 0x" + Integer.toHexString(err)); } return isShaderStatusValid(gl, shader, GL2ES2.GL_COMPILE_STATUS, verboseOut) && err == GL.GL_NO_ERROR; }
/** * Set the uniform data. * * <p>Even if the uniform is not found in the current shader, it is stored in this state. * * @param data the GLUniforms's name must match the uniform one, it's index will be set with the * uniforms's location, if found. * @return false, if the name is not found, otherwise true * @throws GLException if the program is not in use * @see #glGetUniformLocation * @see javax.media.opengl.GL2ES2#glGetUniformLocation * @see javax.media.opengl.GL2ES2#glUniform * @see #getUniformLocation * @see ShaderProgram#glReplaceShader */ public boolean uniform(GL2ES2 gl, GLUniformData data) { if (!shaderProgram.inUse()) throw new GLException("Program is not in use"); int location = data.getLocation(); if (0 > location) { location = getUniformLocation(gl, data); } if (0 <= location) { // only pass the data, if the uniform exists in the current shader if (DEBUG) { System.err.println("ShaderState: glUniform: " + data); } gl.glUniform(data); } return true; }
public void begin(GL2ES2 gl) { if (this.handles == null) { this.handles = new LineProgramHandles(gl); } gl.getGL3().glBindVertexArray(GLUtils.defaultVertexAttributeArray(gl)); gl.glUseProgram(this.handles.program); gl.glEnableVertexAttribArray(this.handles.inXy); gl.glEnableVertexAttribArray(this.handles.inFlags); gl.glEnableVertexAttribArray(this.handles.inMileage); gl.glEnableVertexAttribArray(this.handles.inRgba); }