All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.dabasan.joglf.gl.shader.ShaderFunctions Maven / Gradle / Ivy

There is a newer version: 11.7.0
Show newest version
package com.github.dabasan.joglf.gl.shader;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.github.dabasan.joglf.gl.tool.BufferFunctions;
import com.github.dabasan.joglf.gl.wrapper.GLWrapper;
import com.github.dabasan.tool.FileFunctions;
import com.jogamp.common.nio.Buffers;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2ES2;

/**
 * Shader functions
 * 
 * @author Daba
 *
 */
public class ShaderFunctions {
	private static Logger logger = LoggerFactory.getLogger(ShaderFunctions.class);

	private static Map program_ids_map = new HashMap<>();

	/**
	 * Creates a program after compiling shaders.
	 * 
	 * @param program_name
	 *            Name of the program
	 * @param vertex_shader_filename
	 *            Filename of the vertex shader
	 * @param fragment_shader_filename
	 *            Filename of the fragment shader
	 * @return -1 on error and 0 on success
	 */
	public static int CreateProgram(String program_name, String vertex_shader_filename,
			String fragment_shader_filename) {
		logger.info("Start creating a program. program_name={}", program_name);
		logger.info("vertex_shader_filename={} fragment_shader_filename={}", vertex_shader_filename,
				fragment_shader_filename);

		final int vertex_shader_id = GLWrapper.glCreateShader(GL2ES2.GL_VERTEX_SHADER);
		final int fragment_shader_id = GLWrapper.glCreateShader(GL2ES2.GL_FRAGMENT_SHADER);

		// Load the code files of shaders.
		List vertex_shader_code_list;
		List fragment_shader_code_list;
		String[] vertex_shader_code;
		String[] fragment_shader_code;
		try {
			vertex_shader_code_list = FileFunctions.GetFileAllLines(vertex_shader_filename,
					"UTF-8");
			fragment_shader_code_list = FileFunctions.GetFileAllLines(fragment_shader_filename,
					"UTF-8");
		} catch (final IOException e) {
			logger.error("Error while reading.", e);
			return -1;
		}
		vertex_shader_code = new String[vertex_shader_code_list.size()];
		fragment_shader_code = new String[fragment_shader_code_list.size()];
		vertex_shader_code_list.toArray(vertex_shader_code);
		fragment_shader_code_list.toArray(fragment_shader_code);

		// Add LF to every line of the code.
		for (int i = 0; i < vertex_shader_code.length; i++) {
			vertex_shader_code[i] += "\n";
		}
		for (int i = 0; i < fragment_shader_code.length; i++) {
			fragment_shader_code[i] += "\n";
		}

		final IntBuffer info_log_length = Buffers.newDirectIntBuffer(1);
		final IntBuffer result = Buffers.newDirectIntBuffer(1);
		ByteBuffer error_message;
		String error_message_str;

		// Compile vertex shader.
		GLWrapper.glShaderSource(vertex_shader_id, vertex_shader_code.length, vertex_shader_code,
				null);
		GLWrapper.glCompileShader(vertex_shader_id);

		// Check vertex shader.
		GLWrapper.glGetShaderiv(vertex_shader_id, GL2ES2.GL_COMPILE_STATUS, result);
		if (result.get(0) == GL.GL_FALSE) {
			GLWrapper.glGetShaderiv(vertex_shader_id, GL2ES2.GL_INFO_LOG_LENGTH, info_log_length);
			error_message = Buffers.newDirectByteBuffer(info_log_length.get(0));
			GLWrapper.glGetShaderInfoLog(vertex_shader_id, info_log_length.get(0), null,
					error_message);
			error_message_str = BufferFunctions.GetStringFromByteBuffer(error_message);

			logger.error("Vertex shader compilation failed.");
			logger.error(error_message_str);

			return -1;
		}

		// Compile fragment shader.
		GLWrapper.glShaderSource(fragment_shader_id, fragment_shader_code.length,
				fragment_shader_code, null);
		GLWrapper.glCompileShader(fragment_shader_id);

		// Check fragment shader.
		GLWrapper.glGetShaderiv(fragment_shader_id, GL2ES2.GL_COMPILE_STATUS, result);
		if (result.get(0) == GL.GL_FALSE) {
			GLWrapper.glGetShaderiv(fragment_shader_id, GL2ES2.GL_INFO_LOG_LENGTH, info_log_length);
			error_message = Buffers.newDirectByteBuffer(info_log_length.get(0));
			GLWrapper.glGetShaderInfoLog(fragment_shader_id, info_log_length.get(0), null,
					error_message);
			error_message_str = BufferFunctions.GetStringFromByteBuffer(error_message);

			logger.error("Fragment shader compilation failed.");
			logger.error(error_message_str);

			return -1;
		}

		// Link program.
		final int program_id = GLWrapper.glCreateProgram();
		GLWrapper.glAttachShader(program_id, vertex_shader_id);
		GLWrapper.glAttachShader(program_id, fragment_shader_id);

		GLWrapper.glLinkProgram(program_id);

		// Check program.
		GLWrapper.glGetProgramiv(program_id, GL2ES2.GL_LINK_STATUS, result);
		if (result.get(0) == GL.GL_FALSE) {
			GLWrapper.glGetProgramiv(program_id, GL2ES2.GL_INFO_LOG_LENGTH, info_log_length);
			error_message = Buffers.newDirectByteBuffer(info_log_length.get(0));
			GLWrapper.glGetProgramInfoLog(program_id, info_log_length.get(0), null, error_message);
			error_message_str = BufferFunctions.GetStringFromByteBuffer(error_message);

			logger.error("Program link failed.");
			logger.error(error_message_str);

			return -1;
		}

		GLWrapper.glDeleteShader(vertex_shader_id);
		GLWrapper.glDeleteShader(fragment_shader_id);

		program_ids_map.put(program_name, program_id);
		logger.info("Successfully created a program. program_name={} program_id={}", program_name,
				program_id);

		return 0;
	}

	public static int GetProgramID(String program_name) {
		if (program_ids_map.containsKey(program_name) == false) {
			return -1;
		}
		return program_ids_map.get(program_name);
	}

	public static int UseProgram(String program_name) {
		if (program_ids_map.containsKey(program_name) == false) {
			logger.trace("Invalid program name. program_name={}", program_name);
			return -1;
		}

		final int program_id = program_ids_map.get(program_name);
		GLWrapper.glUseProgram(program_id);

		return 0;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy