LWJGL - Shader loading - Invalid value

I have been reading the red book on open gl and to help me understand the tutorials I have been rewriting them into Java using LWJGL.

I’ve have gotten stuck on one of the tutorials in chapter 3 where the shader will not load.
The goal of the tutorial is to render four triangles using four different buffers, sub-buffer, arrays, elements.

Here is the init code which sets up the triangles and the shaders.


	private void init()
	{
		// A single triangle
		FloatBuffer vertexPositions = BufferUtils.createFloatBuffer(16);
		vertexPositions.put(new float[] { -1.0f, -1.0f, 0.0f, 1.0f });
		vertexPositions.put(new float[] { 1.0f, -1.0f, 0.0f, 1.0f });
		vertexPositions.put(new float[] { -1.0f, 1.0f, 0.0f, 1.0f });
		vertexPositions.put(new float[] { -1.0f, -1.0f, 0.0f, 1.0f });
		vertexPositions.flip();

		// A colours for the triangle
		FloatBuffer vertexColours = BufferUtils.createFloatBuffer(16);
		vertexColours.put(new float[] { 1.0f, 1.0f, 1.0f, 1.0f });
		vertexColours.put(new float[] { 1.0f, 1.0f, 0.0f, 1.0f });
		vertexColours.put(new float[] { 1.0f, 0.0f, 1.0f, 1.0f });
		vertexColours.put(new float[] { 0.0f, 1.0f, 1.0f, 1.0f });
		vertexColours.flip();

		// indices for the triangle strips
		final byte[] vertexIndices = new byte[] { 0, 1, 2 };
		ByteBuffer indicesBuffer = BufferUtils.createByteBuffer(vertexIndices.length);
		indicesBuffer.put(vertexIndices);
		indicesBuffer.flip();

		// Set up the element array buffer
		elementBufferId = GL15.glGenBuffers();
		GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, elementBufferId);
		GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL15.GL_STATIC_DRAW);

		// Set up the vertex attributes
		vaoId = GL30.glGenVertexArrays();
		GL30.glBindVertexArray(vaoId);

		vboId = GL15.glGenBuffers();
		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboId);
		GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertexPositions.capacity() + vertexColours.capacity(), GL15.GL_STATIC_DRAW);

		GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, vertexPositions);
		GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, vertexPositions.capacity(), vertexColours);

		GL20.glVertexAttribPointer(0, 2, GL11.GL_FLOAT, false, 0, 0L);
		GL20.glVertexAttribPointer(1, 4, GL11.GL_FLOAT, false, 0, vertexPositions.capacity());
		GL20.glEnableVertexAttribArray(0);
		GL20.glEnableVertexAttribArray(1);
		// create program

		Matrix4f model_matrix = new Matrix4f();
		Matrix4f projection_matrix = new Matrix4f();

		vertexShader = ShaderUtils.loadShader("src/dw/redbook/tutorials/ex002drawingcommands/primitive_restart.vs.glsl", GL20.GL_VERTEX_SHADER);
		fragmentShader = ShaderUtils.loadShader("src/dw/redbook/tutorials/ex002drawingcommands/primitive_restart.fs.glsl", GL20.GL_FRAGMENT_SHADER);
		// vertexShader = ShaderUtils.loadShader("src/dw/redbook/tutorials/ex002drawingcommands/triangles.vs", GL20.GL_VERTEX_SHADER);
		// fragmentShader = ShaderUtils.loadShader("src/dw/redbook/tutorials/ex002drawingcommands/triangles.fs", GL20.GL_FRAGMENT_SHADER);

		renderProgramId = GL20.glCreateProgram();
		glAttachShader(renderProgramId, vertexShader);
		glAttachShader(renderProgramId, fragmentShader);

		glLinkProgram(renderProgramId);
		glValidateProgram(renderProgramId);
		GL20.glUseProgram(renderProgramId);

		// Create a FloatBuffer with the proper size to store our matrices later
		matrix44Buffer = BufferUtils.createFloatBuffer(16);

	}

If you need to see anything else then I can paste it.

The shader it fails to load is

#version 330

uniform mat4 model_matrix;
uniform mat4 projection_matrix;

layout (location = 0) in vec4 position;
layout (location = 1) in vec4 color;

out vec4 vs_fs_color;

void main(void)
{
    vs_fs_color = color;
    gl_Position = projection_matrix * (model_matrix * position);
}

Where is your shader loading code?

Ah yes,
The shaderloader code is very similar that is on the LWJGL wiki

package dw.shader;

import static org.lwjgl.opengl.GL11.GL_FALSE;
import static org.lwjgl.opengl.GL20.GL_COMPILE_STATUS;
import static org.lwjgl.opengl.GL20.glCompileShader;
import static org.lwjgl.opengl.GL20.glCreateShader;
import static org.lwjgl.opengl.GL20.glGetShaderi;
import static org.lwjgl.opengl.GL20.glShaderSource;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

import org.lwjgl.opengl.Display;

import dw.game.GameUtils;

public class ShaderUtils
{

	public static int loadShader(String filename, int shaderType)
	{
		System.out.println("attempting to load:=" + filename);
		StringBuilder shaderSource = new StringBuilder();
		int shaderId = glCreateShader(shaderType);

		BufferedReader reader = null;
		try
		{
			reader = new BufferedReader(new FileReader(filename));
			String line;
			while ((line = reader.readLine()) != null)
			{
				// System.out.println(line);
				shaderSource.append(line).append('\n');
			}
		} catch (IOException e)
		{
			System.err.println("Fragment shader wasn't loaded properly.");
			Display.destroy();
			System.exit(1);
		} finally
		{
			if (reader != null)
			{
				try
				{
					reader.close();
				} catch (IOException e)
				{
					e.printStackTrace();
				}
			}
		}

		glShaderSource(shaderId, shaderSource);
		glCompileShader(shaderId);
		if (glGetShaderi(shaderId, GL_COMPILE_STATUS) == GL_FALSE)
		{
			System.err.println("Fragment shader wasn't able to be compiled correctly.");
			System.exit(1);
		}

		System.out.println("loaded:=" + filename);
		GameUtils.exitOnGLError("loadShader");
		return shaderId;
	}

}

You are getting an [icode]IOException[/icode] which means that the file is not found. Try checking your class path.

I’m not sure it is to do with not finding the files.

The console does manage to display the system.out at the end of the load shader method.
But all I get from the console is.


Attempting to load:=src/dw/redbook/tutorials/ex002drawingcommands/primitive_restart.vs.glsl
loaded:=src/dw/redbook/tutorials/ex002drawingcommands/primitive_restart.vs.glsl
ERROR - loadShader: Invalid value


Interestingly if I load the shaders at the start of the method then the “ERROR” message doesn’t appear until I close the display window.

OpenGL’s [icode]glGetError()[/icode] function returns last generated error, not the error from the previous function. Try adding calls to [icode]GameUtils.exitOnGLError()[/icode] before and after every OpenGL call to determine from where the error comes from.

Your right the error is thrown before the loadShader method.
I’ll post the solution when I find, but I have a better chance of finding it now thanks for your help.

It appears that the vertexPosition and vertexColour’s FloatBuffer did not need to be flipped.
That stopped generating the error.


		// A single triangle
		FloatBuffer vertexPositions = BufferUtils.createFloatBuffer(16);
		vertexPositions.put(new float[] { -1.0f, -1.0f, 0.0f, 1.0f });
		vertexPositions.put(new float[] { 1.0f, -1.0f, 0.0f, 1.0f });
		vertexPositions.put(new float[] { -1.0f, 1.0f, 0.0f, 1.0f });
		vertexPositions.put(new float[] { -1.0f, -1.0f, 0.0f, 1.0f });
		// vertexPositions.flip();

		// A colours for the triangle
		FloatBuffer vertexColours = BufferUtils.createFloatBuffer(16);
		vertexColours.put(new float[] { 1.0f, 1.0f, 1.0f, 1.0f });
		vertexColours.put(new float[] { 1.0f, 1.0f, 0.0f, 1.0f });
		vertexColours.put(new float[] { 1.0f, 0.0f, 1.0f, 1.0f });
		vertexColours.put(new float[] { 0.0f, 1.0f, 1.0f, 1.0f });
		// vertexColours.flip();

I can start looking at making each triangle appear now.

Flipping is absolutely necessary for OpenGL to read the data from it. That is clearly not the case.