de.ikosa.mars.viewer.glviewer.engine.GLHardcodedShader.java Source code

Java tutorial

Introduction

Here is the source code for de.ikosa.mars.viewer.glviewer.engine.GLHardcodedShader.java

Source

/*
 * Copyright (C) 2013 Clemens-Alexander Brust IT-Dienstleistungen
 *
 *     This program is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package de.ikosa.mars.viewer.glviewer.engine;

import de.ikosa.mars.util.ML;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;

public class GLHardcodedShader {

    private static String texturedVertexShaderSource = loadFromFile("Assets/engine/shaders/phong_tex_vert.glsl");
    private static String texturedFragmentShaderSource = loadFromFile("Assets/engine/shaders/phong_tex_frag.glsl");
    private static String flatVertexShaderSource = loadFromFile("Assets/engine/shaders/phong_notex_vert.glsl");
    private static String flatFragmentShaderSource = loadFromFile("Assets/engine/shaders/phong_notex_frag.glsl");

    private static GLShader texturedShader = createTexturedShader();
    private static GLShader flatShader = createFlatShader();

    private static String loadFromFile(String path) {
        try {
            ML.i(String.format("Loading shader %s", path));
            return StandardCharsets.UTF_8.decode(ByteBuffer.wrap(Files.readAllBytes(Paths.get(path)))).toString();
        } catch (Exception ex) {
            ML.f(ex);
            return "";
        }
    }

    private static GLShader createTexturedShader() {
        int vertexShaderId = compileShader(texturedVertexShaderSource, GL20.GL_VERTEX_SHADER);
        int fragmentShaderId = compileShader(texturedFragmentShaderSource, GL20.GL_FRAGMENT_SHADER);

        int programId = GL20.glCreateProgram();
        GL20.glAttachShader(programId, vertexShaderId);
        GL20.glAttachShader(programId, fragmentShaderId);

        // Bind Attrib Location...
        GL20.glBindAttribLocation(programId, 0, "in_Position");
        GL20.glBindAttribLocation(programId, 1, "in_Normal");
        GL20.glBindAttribLocation(programId, 2, "in_TexCoord");

        GL20.glLinkProgram(programId);

        validateLinkage(programId);

        GL20.glValidateProgram(programId);

        return new GLShader(programId, vertexShaderId, fragmentShaderId);
    }

    private static GLShader createFlatShader() {
        int vertexShaderId = compileShader(flatVertexShaderSource, GL20.GL_VERTEX_SHADER);
        int fragmentShaderId = compileShader(flatFragmentShaderSource, GL20.GL_FRAGMENT_SHADER);

        int programId = GL20.glCreateProgram();
        GL20.glAttachShader(programId, vertexShaderId);
        GL20.glAttachShader(programId, fragmentShaderId);

        // Bind Attrib Location...
        GL20.glBindAttribLocation(programId, 0, "in_Position");
        GL20.glBindAttribLocation(programId, 1, "in_Normal");

        GL20.glLinkProgram(programId);

        validateLinkage(programId);

        GL20.glValidateProgram(programId);

        return new GLShader(programId, vertexShaderId, fragmentShaderId);
    }

    private static int compileShader(String source, int shaderType) {
        int vertexShaderId = GL20.glCreateShader(shaderType);
        GL20.glShaderSource(vertexShaderId, source);
        GL20.glCompileShader(vertexShaderId);

        validateCompilation(vertexShaderId);
        return vertexShaderId;
    }

    private static void validateCompilation(int shaderId) {
        int compileStatus = GL20.glGetShaderi(shaderId, GL20.GL_COMPILE_STATUS);
        int error = GL11.glGetError();

        if (error != GL11.GL_NO_ERROR) {
            ML.f(String.format("Error getting compilation status: 0x%x", error));
        } else if (compileStatus == GL11.GL_FALSE) {
            int logLength = GL20.glGetShaderi(shaderId, GL20.GL_INFO_LOG_LENGTH);
            String log = GL20.glGetShaderInfoLog(shaderId, logLength);
            ML.f(String.format("Error compiling shader: %s", log));
        }
    }

    private static void validateLinkage(int programId) {
        int linkStatus = GL20.glGetProgrami(programId, GL20.GL_LINK_STATUS);
        int error = GL11.glGetError();

        if (error != GL11.GL_NO_ERROR) {
            ML.f(String.format("Error getting link status: 0x%x", error));
        } else if (linkStatus == GL11.GL_FALSE) {
            int logLength = GL20.glGetProgrami(programId, GL20.GL_INFO_LOG_LENGTH);
            String log = GL20.glGetProgramInfoLog(programId, logLength);
            ML.f(String.format("Error linking program: %s", log));
        }
    }

    public static GLShader getTexturedShader() {
        return texturedShader;
    }

    public static GLShader getFlatShader() {
        return flatShader;
    }
}