JOGL Shader Linking Issues

So recently I have been working on porting a game from Java2D to JOGL. The process has been going well, but I ran into an error about 2 weeks ago and it’s been pretty elusive. I did the shaders like I’ve done in all my other projects, but this is the error I’m getting:

GLDebugEvent[ id 0x1
type Error
severity High: dangerous undefined behavior
source GL API
msg GL_INVALID_OPERATION in glGetAttribLocation(program not linked)
when 1442422448181
source 3.3 (Core profile, arb, debug, compat[ES2, ES3], FBO, hardware) - 3.3 (Core Profile) Mesa 10.6.2 - hash 0x6009cf80]

Here is the code for loading shaders:

      shaders[B_V] = glo.glCreateShader(GL3.GL_VERTEX_SHADER);
		shaders[B_F] = glo.glCreateShader(GL3.GL_FRAGMENT_SHADER);
		shaders[U_V] = glo.glCreateShader(GL3.GL_VERTEX_SHADER);
		shaders[U_F] = glo.glCreateShader(GL3.GL_FRAGMENT_SHADER);
		
		String tempString = "";
		
		try {
			//Background vertex shader
			BufferedReader read = new BufferedReader(new InputStreamReader(RenderUtils.class.getResourceAsStream("BackgroundShaderV.glsl")));
			while((tempString = read.readLine()) != null)
			{
				shaderSources[B_V][0] += (tempString + System.lineSeparator());
			}
			
			tempString = "";
			
			//Background fragment shader
			read = new BufferedReader(new InputStreamReader(RenderUtils.class.getResourceAsStream("BackgroundShaderF.glsl")));
			while((tempString = read.readLine()) != null)
			{
				shaderSources[B_F][0] += (tempString + System.lineSeparator());
			}
			
			tempString = "";
			
			//Unit vertex shader
			read = new BufferedReader(new InputStreamReader(RenderUtils.class.getResourceAsStream("UnitShaderV.glsl")));
			while((tempString = read.readLine()) != null)
			{
				shaderSources[U_V][0] += (tempString + System.lineSeparator());
			}
			
			tempString = "";
			
			//Unit fragment shader
			read = new BufferedReader(new InputStreamReader(RenderUtils.class.getResourceAsStream("UnitShaderF.glsl")));
			while((tempString = read.readLine()) != null)
			{
				shaderSources[U_F][0] += (tempString + System.lineSeparator());
			}
			
			//compile shaders
			glo.glShaderSource(shaders[B_V], 1, shaderSources[B_V], null, 0);
			glo.glCompileShader(shaders[B_V]);
			
			glo.glShaderSource(shaders[B_F], 1, shaderSources[B_F], null, 0);
			glo.glCompileShader(shaders[B_F]);
			
			glo.glShaderSource(shaders[U_V], 1, shaderSources[U_V], null, 0);
			glo.glCompileShader(shaders[U_V]);
			
			glo.glShaderSource(shaders[U_F], 1, shaderSources[U_F], null, 0);
			glo.glCompileShader(shaders[U_F]);
			
			//link shaders
			backgroundShader = glo.glCreateProgram();
			glo.glAttachShader(backgroundShader, shaders[B_V]);
			glo.glAttachShader(backgroundShader, shaders[B_F]);
			glo.glLinkProgram(backgroundShader);
			
			unitShader = glo.glCreateProgram();
			glo.glAttachShader(unitShader, shaders[U_V]);
			glo.glAttachShader(unitShader, shaders[U_F]);
			glo.glLinkProgram(unitShader);
			
			
			glo.glUseProgram(backgroundShader);

If anyone has run into this issue before and could give some advice it would be most appreciated.

Hi,

Which version are you using?

On the glGetAttribLocation api doc I see it returns that error in these cases

[quote]GL_INVALID_OPERATION is generated if program is not a value generated by OpenGL.

GL_INVALID_OPERATION is generated if program is not a program object.

GL_INVALID_OPERATION is generated if program has not been successfully linked.
[/quote]
So you may want to check if:

  • the program id is != 0

  • if the program is linked

I have always done my initialization like this, much more compact and simpler, you could give it a try :wink:

Thanks, I tried your way of loading shaders and it not only cleaned up my code, it also let me see what the linking error actually was. Can’t believe I had never heard of doing it that way before.

Anyways, it turned out that I had forgot to put a data type in a “out” variable in my vertex shader. The program doesn’t crash now, but just has a black screen ???. I’m sure I’ll figure it out eventually though.

Thanks again, couldn’t have done it without your help.

You can ask for help on our official IRC channel and on our official forum. Good luck.

I am glad it helped!

Anyway, notice that it may be still shorter… if you don’t need to

glBindAttribLocation

or

glBindFragDataLocation

you can skip the

shaderProgram.init(gl4);

and call directly

shaderProgram.link(gl4, System.out);

that will init it if not yet done.

You sure you didn’t mean in your fragment shader? Because that is where the “out vec4” should be… check that

What are you trying to render? Start from a basic scenario and the build on… is at least the clearing color working?

If you can, show us some of your code

[quote]You sure you didn’t mean in your fragment shader? Because that is where the “out vec4” should be… check that

What are you trying to render? Start from a basic scenario and the build on… is at least the clearing color working?

If you can, show us some of your code
[/quote]
I checking and the output is infact from the vertex shader, it’s a vec2 for the texture coordinates.

Basically, I’m trying to render a single quad “the background” with a texture. I tried changing the clear color and the clearing is definitely working, so I believe the context is set up correctly. Perhaps I don’t have the geometry in the right place? I’ve tried moving it around but to no avail. :frowning:

Anywho, if you’d like to take a look at the code here’s a link to the repositiory: https://github.com/DonDrews/DominationIVClient/tree/master/src/render

Most of the related code is under /src/render. I should probably mention that this project is being ported from Java2D.

Thanks for showing an interest by the way, opengl can be rather confusing when you’re new to it.

I took a look to your code and I already saw that:

  • you shouldn’t use a static GL object

  • you didn’t create and load actually any texture…

I strongly suggest you to take a look to this Hello Texture in order to understand how to handle textures.

Once you got the basic knowledge then you could move on

If something isn’t clear, just let me know

elect is right, don’t do that:
https://github.com/DonDrews/DominationIVClient/blob/master/src/render/RenderUtils.java#L78

A GL instance can mutate (for example when emulating OpenGL ES 1 on OpenGL ES 2) and become invalid at runtime. Rather call GLContext.getGL().getGL3() and store the GL instance locally (i.e in a local variable, not in a field).

Thanks for the replies, I’ll be sure to fix up the static GL object issue. But referring to your statement that I’m not loading or creating a texture, I’m not entirely sure what you mean. https://github.com/DonDrews/DominationIVClient/blob/master/src/render/RenderUtils.java#L315-L321 <- That is how I’m doing it currently, but for all I know this could be a very outdated/wrong approach. I saw in your code that you used textures mostly in the standard OpenGL way. glBindTexture2D() and the like. I just saw a few different people using the other approach and assumed that was somehow the “correct” way to do it in JOGL. I don’t believe the documentation says either are deprecated.

Hi Don,

I mean something like this.

I don’t see where you are actually transferring the texture data.

I prefer to use the standard OpenGL way so that everything is clear and it does exactly what you write. This is excellent when you are learning. Once you are confident enough, you can skip most of this somehow automatic steps and put them into some nested methods, but for the begin, I suggest you to sticky to the standard way.