GLSL Shader does not have Location Table?

Started by Phobeus, September 14, 2011, 19:17:21

Previous topic - Next topic

Phobeus

Hi,

I am currently trying to get into the GLSL stuff with lwjgl. Basically, it seems to work fine as I am able to write shaders that can be used to manipulate e.g. the color of a quad. I think this proofs, that at least parts are running fine. However, I am not able to access any uniform variables defined in the shader as always -1 is returned. I nearly tried everything to find out what exactly the problem is, but I am about to give up. I have absolutely no clue what seems to be the problem in never getting any variable returned.

As my real application is somewhat more complicate I tried manage it with the example in the wiki. But I also getting always just a "-1". Basically I just modified two things... adding a missing semicolon and allowing to activate the shader when the getInfo does not return anything (what seems to be default for my NVIDIA driver, as it is returning errors, when the shader is obvisouly wrong).

My vertex shader, defining a new variable "pos". When modifying the vertColor, I can change the color of the box.
varying vec4 vertColor;

uniform vec3 pos;

void main(){
	gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex;
	vertColor = vec4(0.6, 0.3, 0.4, 1.0);
}


Fragment shader is unchanged.

varying vec4 vertColor;
 
void main(){
gl_FragColor = vertColor;
}


import org.lwjgl.opengl.GL11;
import java.io.BufferedReader;
import java.io.FileReader;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.ARBShaderObjects;
import org.lwjgl.opengl.ARBVertexShader;
import org.lwjgl.opengl.ARBFragmentShader;
import org.lwjgl.opengl.Util;

/**
 * The vertex and fragment shaders are setup when the box object is constructed.
 * They are applied to the GL state prior to the box being drawn, and released
 * from that state after drawing.
 * 
 * @author Stephen Jones
 */
public class Box {

	/*
	 * if the shaders are setup ok we can use shaders, otherwise we just use
	 * default settings
	 */
	private boolean useShader = true;

	/*
	 * program shader, to which is attached a vertex and fragment shaders. They
	 * are set to 0 as a check because GL will assign unique int values to each
	 */
	private int shader = 0;
	private int vertShader = 0;
	private int fragShader = 0;

	public Box() {

		/*
		 * create the shader program. If OK, create vertex and fragment shaders
		 */
		shader = ARBShaderObjects.glCreateProgramObjectARB();

		if (shader != 0) {
			vertShader = createVertShader("shaders/screen.vert");
			fragShader = createFragShader("shaders/screen.frag");
		} else
			useShader = false;

		/*
		 * if the vertex and fragment shaders setup sucessfully, attach them to
		 * the shader program, link the sahder program (into the GL context I
		 * suppose), and validate
		 */
		if (vertShader != 0 && fragShader != 0) {
			ARBShaderObjects.glAttachObjectARB(shader, vertShader);
			ARBShaderObjects.glAttachObjectARB(shader, fragShader);
			ARBShaderObjects.glLinkProgramARB(shader);
			ARBShaderObjects.glValidateProgramARB(shader);
			useShader = printLogInfo(shader);			
		} else
			useShader = false;
		System.out.println(useShader);
	}

	/*
	 * If the shader was setup succesfully, we use the shader. Otherwise we run
	 * normal drawing code.
	 */
	public void draw() {
		if (useShader) {
			ARBShaderObjects.glUseProgramObjectARB(shader);

			// Trying to fetch the position
			int pos=ARBShaderObjects.glGetUniformLocationARB(
					shader, "pos");
			System.out.println(pos);
		}
		GL11.glLoadIdentity();
		GL11.glTranslatef(0.0f, 0.0f, -10.0f);
		GL11.glColor3f(1.0f, 1.0f, 1.0f);// white

		GL11.glBegin(GL11.GL_QUADS);
		GL11.glVertex3f(-1.0f, 1.0f, 0.0f);
		GL11.glVertex3f(1.0f, 1.0f, 0.0f);
		GL11.glVertex3f(1.0f, -1.0f, 0.0f);
		GL11.glVertex3f(-1.0f, -1.0f, 0.0f);
		GL11.glEnd();

		// release the shader
		ARBShaderObjects.glUseProgramObjectARB(0);

	}

	/*
	 * With the exception of syntax, setting up vertex and fragment shaders is
	 * the same.
	 * 
	 * @param the name and path to the vertex shader
	 */
	private int createVertShader(String filename) {
		// vertShader will be non zero if succefully created

		vertShader = ARBShaderObjects
				.glCreateShaderObjectARB(ARBVertexShader.GL_VERTEX_SHADER_ARB);
		// if created, convert the vertex shader code to a String
		if (vertShader == 0) {
			return 0;
		}
		String vertexCode = "";
		String line;
		try {
			BufferedReader reader = new BufferedReader(new FileReader(filename));
			while ((line = reader.readLine()) != null) {
				vertexCode += line + "\n";
			}
		} catch (Exception e) {
			System.out.println("Fail reading vertex shading code");
			return 0;
		}
		/*
		 * associate the vertex code String with the created vertex shader and
		 * compile
		 */
		ARBShaderObjects.glShaderSourceARB(vertShader, vertexCode);
		ARBShaderObjects.glCompileShaderARB(vertShader);
		// if there was a problem compiling, reset vertShader to zero
		if (!printLogInfo(vertShader)) {
			vertShader = 0;
		}
		// if zero we won't be using the shader
		return vertShader;
	}

	// same as per the vertex shader except for method syntax
	private int createFragShader(String filename) {

		fragShader = ARBShaderObjects
				.glCreateShaderObjectARB(ARBFragmentShader.GL_FRAGMENT_SHADER_ARB);
		if (fragShader == 0) {
			return 0;
		}
		String fragCode = "";
		String line;
		try {
			BufferedReader reader = new BufferedReader(new FileReader(filename));
			while ((line = reader.readLine()) != null) {
				fragCode += line + "\n";
			}
		} catch (Exception e) {
			System.out.println("Fail reading fragment shading code");
			return 0;
		}
		ARBShaderObjects.glShaderSourceARB(fragShader, fragCode);
		ARBShaderObjects.glCompileShaderARB(fragShader);
		if (!printLogInfo(fragShader)) {
			fragShader = 0;
		}

		return fragShader;
	}

	/*
	 * oddly enough, checking the success when setting up the shaders is verbose
	 * upon success. If the reference iVal becomes greater than 1, the setup
	 * being examined (obj) has been successful, the information gets printed to
	 * System.out, and true is returned.
	 */
	private static boolean printLogInfo(int obj) {
		IntBuffer iVal = BufferUtils.createIntBuffer(1);
		ARBShaderObjects.glGetObjectParameterARB(obj,
				ARBShaderObjects.GL_OBJECT_INFO_LOG_LENGTH_ARB, iVal);

		int length = iVal.get();
		if (length > 1) {
			// We have some info we need to output.
			ByteBuffer infoLog = BufferUtils.createByteBuffer(length);
			iVal.flip();
			ARBShaderObjects.glGetInfoLogARB(obj, iVal, infoLog);
			byte[] infoBytes = new byte[length];
			infoLog.get(infoBytes);
			String out = new String(infoBytes);
			System.out.println("Info log:\n" + out);
		} 
		// # Changed as NVIDIA driver seems always return nothing on success.
		//else
//			return false;
		return true;
	}

}

The main is unchanged. It might be that I am running into circles and it might be something damn small. But what exactly is wrong with that code?

It is actually pretty hard to find any simple, but complete GLSL samples in the net with Source and Shader codes. If anyone knows a good one that might help to verify, if this is a problem with the driver or linux. I really would appreciate any help that might help finding the problem. So my question is basically just: How can I access a uniform location of a compiled shader in order to provide values between the shader and the java app. Is there a way, to list all locations stored within a shader, instead of accessing it by a key?

spasi

From the spec:

QuoteThe value of -1 will be returned if <name> does not correspond to an active uniform variable name in <programObj> or if <name> starts with the reserved prefix "gl_".

You do not use the "pos" uniform in your shader, that's why -1 is returned. Unused uniforms are always optimized away by the GLSL compiler.

Phobeus

Ah god damn... you are absolutely right. I was searching for the problem by reading specs and rewritting the code from the scratch for a week and now the problem is within my test shaders as all I used did was only defined to minimize the possible problems. That's actually kinda funny ;) Thanks for pin-pointing the problem, as I really was starting to give up because I thought I did not understand anything about this stuff. Many thanks!