Can Java Be converted to C.. GLSL Shader Class

Hello,

I have been using an implementation of GLSL shaders that consists of a lot of hard coding along with the vert/frag shader code.

I came across a java class for glsl shaders which seems to make loading shaders a snap. My only problem is that I can’t seem to finc much about converting java to c.

Anyway, here is an example. (Java Class code at the end)

The simple call for initializing the shader.


import GLShaders; //our shader wrapper

public int basicShader; //an integer reference to our shader

basicShader = GLShaders.loadShadersCode("basic.vert","basic.frag");
myTexture = TextureLoader.get().getTexture("anyTextureIWant.tga");

GL20.glUseProgram(basicShader); //start using this shader
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, myTexture.getTextureID());
GLShaders.sendUniform1i(basicShader, "myTexture",0);

Fog Vertex Shader

 
uniform vec3 CameraPosition;// the current camera position (x,y,z)
varying float Distance;// the distance we will send forward 
void main()
{
vec4 a = gl_Vertex;
float dx = a.x - CameraPosition.x;
float dy = a.y - CameraPosition.y;
float dz = a.z - CameraPosition.z;
Distance = clamp((dx*dx)+(dy*dy)+(dz*dz),0.0,50000.0);
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
}

Fog Fragment Shader


varying float Distance;
uniform sampler2D TheTexture;
void main (void)
{
vec4 color= texture2D(TheTexture, gl_TexCoord[0].st);
gl_FragColor = mix(color, vec4(0.5, 0.5, 0.5, 1), Distance/50000.0);
}

See how simple that is to use fog? It’s 95% smaller than the current code I’ve been using. Here is the java class that is actually used above.


package MyPackage;
/* *Author: Abdul Bezrati *Email: [email]abezrati@hotmail.com[/email] */
/* Fixed Memory leaks due to too many bytebuffers - TheSmit  email: [email]TheSmit@warmtart.co.uk[/email] */
import org.lwjgl.opengl.ARBFragmentProgram;
import org.lwjgl.opengl.ARBVertexProgram;
import org.lwjgl.opengl.ARBShaderObjects;
import org.lwjgl.opengl.ARBFragmentShader; 
import org.lwjgl.opengl.ARBVertexShader;
import org.lwjgl.opengl.GL11;
import java.io.FileInputStream; 
import java.io.DataInputStream;
import java.io.InputStream;
import org.lwjgl.BufferUtils; 
import java.nio.FloatBuffer;
import java.nio.ByteBuffer; 
import java.nio.IntBuffer; 

public class GLShaders{
	static ByteBuffer buffer= BufferUtils.createByteBuffer(1024);;	
	private static boolean VPSupported = false, FPSupported = false, VSSupported = false, FSSupported = false;
	private static IntBuffer logBuffer = BufferUtils.createIntBuffer(1);
	static{ VPSupported = checkExtensionSupport("GL_ARB_vertex_program");
	FPSupported = checkExtensionSupport("GL_ARB_fragment_program");
	VSSupported = checkExtensionSupport("GL_ARB_vertex_shader");
	FSSupported = checkExtensionSupport("GL_ARB_fragment_shader");
	}
	
	private static boolean checkExtensionSupport(String extension){
		String supportedExtensions = GL11.glGetString(GL11.GL_EXTENSIONS); 
		return supportedExtensions.indexOf(extension) != -1;
	}
	public static int loadProgramCode(String filename, boolean isFragment){
		if(isFragment && !FPSupported){
			System.out.println("GL_ARB_fragment_program is not supported, skipping.");
			return 0;
		}
		else if(!VPSupported){
			System.out.println("GL_ARB_vertex_program is not supported, skipping.");
			return 0;
		}
		ByteBuffer shaderPro = getProgramCode(filename);
		IntBuffer id = BufferUtils.createIntBuffer(1); 
		if(isFragment){ 
			ARBFragmentProgram.glGenProgramsARB(id);
			ARBFragmentProgram.glBindProgramARB(ARBFragmentProgram.GL_FRAGMENT_PROGRAM_ARB , id.get(0));
			ARBFragmentProgram.glProgramStringARB(ARBFragmentProgram.GL_FRAGMENT_PROGRAM_ARB, ARBFragmentProgram.GL_PROGRAM_FORMAT_ASCII_ARB, shaderPro);
			System.out.println(GL11.glGetString(ARBFragmentProgram.GL_PROGRAM_ERROR_STRING_ARB));
		}
		else{ 
			ARBVertexProgram.glGenProgramsARB(id); 
			ARBVertexProgram.glBindProgramARB(ARBVertexProgram.GL_VERTEX_PROGRAM_ARB , id.get(0)); 
			ARBVertexProgram.glProgramStringARB(ARBVertexProgram.GL_VERTEX_PROGRAM_ARB, ARBVertexProgram.GL_PROGRAM_FORMAT_ASCII_ARB, shaderPro); 
			System.out.println(GL11.glGetString(ARBVertexProgram.GL_PROGRAM_ERROR_STRING_ARB));
		}
		return id.get(0);
	}
	public static int loadShadersCode(String vertexShaderFile, String fragmentShaderFile){
		if(!FSSupported || !VSSupported){ 
			System.out.println("GL_ARB_fragment_shader or GL_ARB_vertex_shader is not supported, skipping.");
			return 0;
		}
		ByteBuffer vertexShader = getProgramCode(vertexShaderFile), fragmentShader = getProgramCode(fragmentShaderFile);
		int vertexShaderID = 0, fragmentShaderID = 0, linkedShadersID = 0;
		vertexShaderID = ARBShaderObjects.glCreateShaderObjectARB(ARBVertexShader.GL_VERTEX_SHADER_ARB);
		ARBShaderObjects.glShaderSourceARB(vertexShaderID, vertexShader);
		ARBShaderObjects.glCompileShaderARB(vertexShaderID);
		printShaderObjectInfoLog(vertexShaderFile, vertexShaderID);
		ARBShaderObjects.glGetObjectParameterARB(vertexShaderID, ARBShaderObjects.GL_OBJECT_COMPILE_STATUS_ARB, logBuffer);
		if(logBuffer.get(0) == GL11.GL_FALSE ){ 
			System.out.println("Error in vertex shader"); 
			return 0;
		}
		fragmentShaderID = ARBShaderObjects.glCreateShaderObjectARB(ARBFragmentShader.GL_FRAGMENT_SHADER_ARB);
		ARBShaderObjects.glShaderSourceARB(fragmentShaderID, fragmentShader);
		ARBShaderObjects.glCompileShaderARB(fragmentShaderID); 
		printShaderObjectInfoLog(fragmentShaderFile, fragmentShaderID);
		ARBShaderObjects.glGetObjectParameterARB(fragmentShaderID, ARBShaderObjects.GL_OBJECT_COMPILE_STATUS_ARB, logBuffer);
		if(logBuffer.get(0) == GL11.GL_FALSE ){
			System.out.println("Error in fragment shader");
			return 0;
		}
		linkedShadersID = ARBShaderObjects.glCreateProgramObjectARB();
		ARBShaderObjects.glAttachObjectARB(linkedShadersID, vertexShaderID);
		ARBShaderObjects.glAttachObjectARB(linkedShadersID, fragmentShaderID);
		ARBShaderObjects.glLinkProgramARB(linkedShadersID);
		printShaderProgramInfoLog(linkedShadersID);
		ARBShaderObjects.glGetObjectParameterARB(linkedShadersID, ARBShaderObjects.GL_OBJECT_LINK_STATUS_ARB, logBuffer);
		if(logBuffer.get(0) == GL11.GL_FALSE ){
			System.out.println("Error in linking shaders");
			return 0;
		}
		System.out.println("Vertex and Fragment shaders linked OK.");
		return linkedShadersID;
	}
	public static void sendUniform1i(int id, String name, int value){
		int location = getUniformLocation(id, name);
		if(checkGLError(location, name)== 0) return;
		ARBShaderObjects.glUniform1iARB(location, value);
	}
	public static void sendUniform2i(int id, String name, int value1, int value2){
		int location = getUniformLocation(id, name);
		if(checkGLError(location, name)== 0) return;
		ARBShaderObjects.glUniform2iARB(location, value1, value2);
	}
	public static void sendUniform3i(int id, String name, int value1, int value2, int value3){
		int location = getUniformLocation(id, name);
		if(checkGLError(location, name)== 0) return;
		ARBShaderObjects.glUniform3iARB(location, value1, value2, value3);
	}
	public static void sendUniform4i(int id, String name, int value1, int value2, int value3, int value4){
		int location = getUniformLocation(id, name);
		if(checkGLError(location, name)== 0) return; 
		ARBShaderObjects.glUniform4iARB(location, value1, value2, value3, value4);
	}
	public static void sendUniform1f(int id, String name, float value){
		int location = getUniformLocation(id, name); if(checkGLError(location, name)== 0) return;
		ARBShaderObjects.glUniform1fARB(location, value);
	}
	public static void sendUniform2f(int id, String name, float value1, float value2){
		int location = getUniformLocation(id, name);
		if(checkGLError(location, name)== 0) return;
		ARBShaderObjects.glUniform2fARB(location, value1, value2);
	} 
	public static void sendUniform3f(int id, String name, float value1, float value2, float value3){
		int location = getUniformLocation(id, name);
		if(checkGLError(location, name)== 0) return; 
		ARBShaderObjects.glUniform3fARB(location, value1, value2, value3);
	}
	public static void sendUniform4f(int id, String name, float value1, float value2, float value3, float value4){ 
		int location = getUniformLocation(id, name);
		if(checkGLError(location, name)== 0) return;
		ARBShaderObjects.glUniform4fARB(location, value1, value2, value3, value4);
	}
	public static void sendUniform1FB(int id, String name, FloatBuffer values){
		int location = getUniformLocation(id, name); 
		if(checkGLError(location, name)== 0) return;
		ARBShaderObjects.glUniform1ARB(location, values);
	}
	public static void sendUniform2FB(int id, String name, FloatBuffer values){
		int location = getUniformLocation(id, name);
		if(checkGLError(location, name)== 0) return; 
		ARBShaderObjects.glUniform2ARB(location, values);
	} 
	public static void sendUniform3FB(int id, String name, FloatBuffer values){
		int location = getUniformLocation(id, name); 
		if(checkGLError(location, name)== 0) return;
		ARBShaderObjects.glUniform3ARB(location, values);
	} 
	public static void sendUniform4FB(int id, String name, FloatBuffer values){
		int location = getUniformLocation(id, name);
		if(checkGLError(location, name)== 0) return;
		ARBShaderObjects.glUniform4ARB(location, values); 
	}
	public static void sendUniform1IB(int id, String name, IntBuffer values){
		int location = getUniformLocation(id, name);
		if(checkGLError(location, name)== 0) return;
		ARBShaderObjects.glUniform1ARB(location, values);
	}
	public static void sendUniform2IB(int id, String name, IntBuffer values){
		int location = getUniformLocation(id, name);
		if(checkGLError(location, name)== 0) return; 
		ARBShaderObjects.glUniform2ARB(location, values);
	}
	public static void sendUniform3IB(int id, String name, IntBuffer values){ 
		int location = getUniformLocation(id, name);
		if(checkGLError(location, name)== 0) return;
		ARBShaderObjects.glUniform3ARB(location, values);
	} 
	public static void sendUniform4IB(int id, String name, IntBuffer values){
		int location = getUniformLocation(id, name);
		if(checkGLError(location, name)== 0) return; 
		ARBShaderObjects.glUniform4ARB(location, values); 
	}
	private static int getUniformLocation(int id, String name) {
		buffer.clear();
		buffer.put(name.getBytes());
		buffer.put((byte)0);
		buffer.flip();
		return ARBShaderObjects.glGetUniformLocationARB(id, buffer);
	}
	private static void printShaderObjectInfoLog(String file, int ID) {
		ARBShaderObjects.glGetObjectParameterARB(ID, ARBShaderObjects.GL_OBJECT_INFO_LOG_LENGTH_ARB, logBuffer);
		final int logLength = logBuffer.get(0);
		if( logLength <= 1 ) return;
		final ByteBuffer log = BufferUtils.createByteBuffer(logLength);
		ARBShaderObjects.glGetInfoLogARB(ID, null, log); 
		byte[] byteArray = new byte[logLength];
		log.get(byteArray);
		System.out.println("
Info Log of Shader Object: " + file);
		System.out.println("--------------------------");
		System.out.println(new String(byteArray)); 
	}
	private static void printShaderProgramInfoLog(int ID) { 
		ARBShaderObjects.glGetObjectParameterARB(ID, ARBShaderObjects.GL_OBJECT_INFO_LOG_LENGTH_ARB, logBuffer); 
		final int logLength = logBuffer.get(0);
		if(logLength <= 1 ) return; 
		final ByteBuffer log = BufferUtils.createByteBuffer(logLength);
		ARBShaderObjects.glGetInfoLogARB(ID, null, log);
		byte[] byteArray = new byte[logLength];
		log.get(byteArray); 
		System.out.println("
Shader Program Info Log: ");
		System.out.println("--------------------------");
		System.out.println(new String(byteArray));
	}
	private static ByteBuffer getProgramCode(String filename){ ClassLoader fileLoader = GLShaders.class.getClassLoader();
	InputStream fileInputStream = fileLoader.getResourceAsStream(filename);
	byte[] shaderCode = null;
	try{
		if(fileInputStream == null) fileInputStream = new FileInputStream(filename);
		DataInputStream dataStream = new DataInputStream(fileInputStream); 
		dataStream.readFully(shaderCode = new byte[fileInputStream.available()]); 
		fileInputStream.close();
		dataStream.close();
	}
	catch(Exception e ){
		System.out.println(e.getMessage());
	}
	ByteBuffer shaderPro = BufferUtils.createByteBuffer(shaderCode.length) .put(shaderCode); 
	shaderPro.flip();
	return shaderPro;
	}
	private static int checkGLError(int location, String name){
		if(location == -1){
			System.out.println("Error: couldn't loacte " + name); 
			return 0;
		}
		return 1;
	}
	public static String getLogMessagePrograms(){
		if((VPSupported && FPSupported)) return "Success";
		if(VPSupported && !FPSupported) return "Error: Fragment Program is not supported";
		return "Error: Fragment & Vertex Programs are not supported";
	}
	public static String getLogMessageShaders(){
		if((VSSupported && FSSupported)) return "Success"; 
		if(VSSupported && !FSSupported) return "Error: Fragment Shader is not supported";
		return "Error: Fragment & Vertex Shaders are not supported";
	}
}

So can all of this code be converted to C?

Thanks,
Chris

Yes it can but you could also learn to program in Java and have an easier programming life in general hehe

The only real difference (besides the obvious, object oriented language) is that we use native buffers in LWJGL - so replace the Byte/Int/FloatBuffers with C/C++ arrays. The rest of the translation should be obvious when you’re armed with the API (http://java.sun.com/javase/6/docs/api).

You may find it easier to hunt down some C code wrappers though if you want to stay with that language :slight_smile:

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.