app/src/main/java/puscas/mobilertapp/utils/UtilsShader.java
package puscas.mobilertapp.utils; import android.opengl.GLES20;import android.opengl.GLUtils; Extra separation in import group before 'androidx.annotation.NonNull'import androidx.annotation.NonNull;import androidx.annotation.VisibleForTesting; Extra separation in import group before 'com.google.common.base.Preconditions'import com.google.common.base.Preconditions; Extra separation in import group before 'java.util.Map'import java.util.Map;import java.util.logging.Logger; Extra separation in import group before 'puscas.mobilertapp.configs.ConfigGlAttribute'import puscas.mobilertapp.configs.ConfigGlAttribute;import puscas.mobilertapp.exceptions.FailureException; /** * Utility class with some helper methods to create GLSL programs and load GLSL shaders. */public final class UtilsShader { /** * Logger for this class. */ private static final Logger logger = Logger.getLogger(UtilsShader.class.getSimpleName()); /** * Private constructor to avoid creating instances. */ private UtilsShader() { throw new UnsupportedOperationException("Not implemented."); } /** * Helper method that attaches some GLSL shaders into an OpenGL program. * * @param shaderProgram The index of OpenGL shader program. * @param shadersCode The shaders' code. */ public static void attachShaders(final int shaderProgram, @NonNull final Map<Integer, String> shadersCode) { logger.info("attachShaders"); loadAndAttachShaders(shaderProgram, shadersCode); final int[] attachedShaders = new int[1];Line is longer than 100 characters (found 112). UtilsGL.run(() -> GLES20.glGetProgramiv(shaderProgram, GLES20.GL_ATTACHED_SHADERS, attachedShaders, 0)); checksShaderLinkStatus(shaderProgram); } /** * Helper method that checks the OpenGL shader link status in a program. * * @param shaderProgram The OpenGL shader program index. */ public static void checksShaderLinkStatus(final int shaderProgram) { logger.info("checksShaderLinkStatus"); final int[] linkStatus = new int[1];Line is longer than 100 characters (found 102). UtilsGL.run(() -> GLES20.glGetProgramiv(shaderProgram, GLES20.GL_LINK_STATUS, linkStatus, 0)); if (linkStatus[0] != GLES20.GL_TRUE) { final String strError = UtilsGL.run(shaderProgram, GLES20::glGetProgramInfoLog); final String msg = "Could not link program shader: " + strError; UtilsGL.run(() -> GLES20.glDeleteProgram(shaderProgram)); throw new FailureException(msg); } } /** * Helper method which loads an OpenGL shader. * * @param shaderType The type of the shader (vertex or fragment shader). * @param source The code of the shader. * @return The OpenGL index of the shader. */Method `loadShader` has 28 lines of code (exceeds 25 allowed). Consider refactoring. @VisibleForTesting public static int loadShader(final int shaderType, @NonNull final String source) { logger.info("loadShader"); final int shader = UtilsGL.run(() -> GLES20.glCreateShader(shaderType)); if (shader == 0) { logger.info("loadShader error 1"); final int glError = GLES20.glGetError(); final String msgError = GLUtils.getEGLErrorString(glError);Line is longer than 100 characters (found 116). final String msg = "There was an error while creating the shader object: (" + glError + ") " + msgError; throw new FailureException(msg); } UtilsGL.run(() -> GLES20.glShaderSource(shader, source)); UtilsGL.run(() -> GLES20.glCompileShader(shader)); final int[] compiled = new int[1]; UtilsGL.run(() -> GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0)); if (compiled[0] == 0) { logger.info("loadShader error 2"); final int glError = GLES20.glGetError(); final String informationLog = UtilsGL.run(() -> GLES20.glGetShaderInfoLog(shader)); final String msg = "Could not compile shader " + shaderType + ": " + informationLog; final String msgError = GLUtils.getEGLErrorString(glError); logger.severe(msg); logger.severe(source);Use the built-in formatting to construct this argument. logger.severe("Error: " + msgError); UtilsGL.run(() -> GLES20.glDeleteShader(shader)); UtilsGL.run(GLES20::glReleaseShaderCompiler); throw new FailureException(informationLog); } logger.info("loadShader finish"); return shader; } /** * Helper method that initializes a GLSL program. * It deletes the previous GLSL program if it was created. * * @param shaderProgram The OpenGL shader program index to recreate. * @return A new created OpenGL shader program index. */ public static int reCreateProgram(final int shaderProgram) { logger.info("reCreateProgram"); if (shaderProgram != 0) { final String deleteProgramMessage = "Deleting GL program: " + shaderProgram; logger.info(deleteProgramMessage); UtilsGL.run(() -> GLES20.glDeleteProgram(shaderProgram)); } final int newShaderProgram = UtilsGL.<Integer>run(GLES20::glCreateProgram); if (newShaderProgram == 0) { logger.severe("Could not create GL program."); final String programInfo = GLES20.glGetProgramInfoLog(0); throw new FailureException(programInfo); } final String createdProgramMessage = "GL program created: " + newShaderProgram; logger.info(createdProgramMessage); return newShaderProgram; } /** * Helper method that binds and enables an OpenGL attribute. * * @param shaderProgram The shader program index. * @param config The {@link ConfigGlAttribute} configurator. */ public static void connectOpenGlAttribute(final int shaderProgram, @NonNull final ConfigGlAttribute config) { logger.info("connectOpenGlAttribute"); UtilsGL.run(() -> GLES20.glBindAttribLocation( shaderProgram, config.getAttributeLocation(), config.getAttributeName())); UtilsGL.run(() -> GLES20.glVertexAttribPointer(config.getAttributeLocation(), config.getComponentsInBuffer(), GLES20.GL_FLOAT, false, 0, config.getBuffer())); UtilsGL.run(() -> GLES20.glEnableVertexAttribArray(config.getAttributeLocation())); } /** * Helper method that loads a vertex and a fragment shaders and attach those * to a GLSL program. * * @param shaderProgram The index of OpenGL shader program. * @param shadersCode The shaders' code. */ public static void loadAndAttachShaders(final int shaderProgram, @NonNull final Map<Integer, String> shadersCode) { logger.info("loadAndAttachShaders"); final int vertexShader = getShaderIndex(shadersCode, GLES20.GL_VERTEX_SHADER); final int fragmentShader = getShaderIndex(shadersCode, GLES20.GL_FRAGMENT_SHADER); // Attach and link shaders to program UtilsGL.run(() -> GLES20.glAttachShader(shaderProgram, vertexShader)); UtilsGL.run(() -> GLES20.glAttachShader(shaderProgram, fragmentShader)); UtilsGL.run(() -> GLES20.glLinkProgram(shaderProgram)); UtilsGL.run(() -> GLES20.glDeleteShader(vertexShader)); UtilsGL.run(() -> GLES20.glDeleteShader(fragmentShader)); } /** * Helper method which loads an OpenGL shader and returns the OpenGL index of the shader. * * @param shadersCode The shaders' code. * @param shaderType The type of the shader (vertex or fragment shader). * @return The OpenGL index of the shader. */Line is longer than 100 characters (found 110). private static int getShaderIndex(@NonNull final Map<Integer, String> shadersCode, final int shaderType) { final String shaderCode = shadersCode.get(shaderType); Preconditions.checkNotNull(shaderCode, "shaderCode shouldn't be null"); return loadShader(shaderType, shaderCode); } }