Java tutorial
/* * 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; public class GLShaderBuilder { private String name; private String fragmentSource; private String vertexSource; public GLShaderBuilder(String name, String vertexSource, String fragmentSource) { this.name = name; this.fragmentSource = fragmentSource; this.vertexSource = vertexSource; } public GLShader createShader(GLResources resourceManager) { int vertexShaderId = compileShader(vertexSource, GL20.GL_VERTEX_SHADER); int fragmentShaderId = compileShader(fragmentSource, GL20.GL_FRAGMENT_SHADER); int programId = GL20.glCreateProgram(); GL20.glAttachShader(programId, vertexShaderId); GL20.glAttachShader(programId, fragmentShaderId); // Bind attribute locations GL20.glBindAttribLocation(programId, 0, "in_Position"); if (vertexSource.contains("in_Normal")) GL20.glBindAttribLocation(programId, 1, "in_Normal"); if (vertexSource.contains("in_TexCoord")) GL20.glBindAttribLocation(programId, 2, "in_TexCoord"); GL20.glLinkProgram(programId); validateLinkage(programId); GL20.glValidateProgram(programId); return new GLShader(programId, vertexShaderId, fragmentShaderId); } private 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 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)); } } private int compileShader(String source, int shaderType) { int vertexShaderId = GL20.glCreateShader(shaderType); GL20.glShaderSource(vertexShaderId, source); GL20.glCompileShader(vertexShaderId); validateCompilation(vertexShaderId); return vertexShaderId; } }