How to force OpenGL Version?

Hello.

I bought a new GPU (AMD R9 270) and I can’t run projects anymore in libGDX. This issue include openGL, Shaders and Spritebatch:

Exception in thread "LWJGL Application" java.lang.IllegalArgumentException: Error compiling shader: Vertex shader failed to compile with the following errors:
ERROR: error(#272) Implicit version number 110 not supported by GL3 forward compatible context
ERROR: error(#273) 1 compilation errors.  No code generated

Fragment shader failed to compile with the following errors:
ERROR: error(#272) Implicit version number 110 not supported by GL3 forward compatible context
ERROR: error(#273) 1 compilation errors.  No code generated

at com.badlogic.gdx.graphics.g2d.SpriteBatch.createDefaultShader(SpriteBatch.java:154)
   at com.badlogic.gdx.graphics.g2d.SpriteBatch.<init>(SpriteBatch.java:117)
   at com.badlogic.gdx.graphics.g2d.SpriteBatch.<init>(SpriteBatch.java:74)
   at com.zkiller.com.GameScreen.create(GameScreen.java:22)

I found this (problem with GPUs): http://stackoverflow.com/questions/15234281/out-cant-be-used-with-non-varying-shader-compile-error-on-nvidia-driver-inte
And this: https://github.com/libgdx/libgdx/issues/2605

In AMD Catalyst Control, the openGL Version is: 6.14.10.13283, but in LibGDX is possible to set gl10, gl20, gl30. I tried everything but nothing works…

Probably I need only to force gl version (#version 300 or something), but I don’t know how and where. I’m almost one month with projects stopped.

To define a version in a shader just put:

#version (version number)

at the first line of the shader!

For example, in a project of mine, I use version 150 (which I assume is opengl 3).

#version 150

uniform sampler2D sampler;
uniform sampler2D normalMap;
uniform float specular;
uniform float gloss;

in vec3 vNormal;
in vec2 vTexCoords;
in vec4 vColor;
in vec3 vEyePosition;

...

GL to GLSL version mapping: https://www.opengl.org/wiki/Core_Language_(GLSL)#OpenGL_and_GLSL_versions

To fix this you could go into the LibGDX source and simply add

#version 330 core

or whatever version you want in the shaders and compile from source. Use this version fo LibGDX for all your new projects.

I am not familiar enough with LibGDX to know of an easier way to do this, or if one even exists.

Thanks for the answer guys, but I’m not understand exactly where I need to add “#Version”. I need to add in libgdx source files? like spritebatch class?

I created a new project to show you, using Eclipse and newest version of libgdx:

Desktop config class:

package com.game.com.desktop;

import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
import com.game.com.StarterClass;

public class DesktopLauncher {
	public static void main (String[] arg) {
		LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
		
		config.width = 1280;
		config.height = 720;
		config.fullscreen = false;
		config.vSyncEnabled = false;
		
		new LwjglApplication(new StarterClass(), config);
	}
}

StarterClass:

package com.game.com;

import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL30;

public class StarterClass extends Game
{
	
	@Override
	public void create()
	{
		setScreen(new GameScreen());
	}
}

GameScreen:

package com.game.com;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;

public class GameScreen implements Screen
{
	SpriteBatch batch;
	Texture img;
	
	public GameScreen()
	{
		create();
	}
	
	public void create()
	{
		batch = new SpriteBatch();
		img = new Texture("badlogic.jpg");
	}
	
	@Override
	public void render (float delta)
	{
		Gdx.gl.glClearColor(0, 0, 0, 1);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
		batch.begin();
		batch.draw(img, 0,0);
		batch.end();
	}

	@Override
	public void resize(int width, int height) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void show() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void hide() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void pause() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void resume() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void dispose() {
		// TODO Auto-generated method stub
		
	}
}

I’ve quickly gandered into the LibGDX sources, and found the default shader code. Unfortunately, the shader code is using version 110 which doesn’t work with GL3. Even we can’t edit the shader files unfortunately, they are stored as strings in the SpriteBatch class.

Here’s the code in Line 124 of SpriteBatch.java


static public ShaderProgram createDefaultShader () {
	String vertexShader = "attribute vec4 " + ShaderProgram.POSITION_ATTRIBUTE + ";\n" //
		+ "attribute vec4 " + ShaderProgram.COLOR_ATTRIBUTE + ";\n" //
		+ "attribute vec2 " + ShaderProgram.TEXCOORD_ATTRIBUTE + "0;\n" //
		+ "uniform mat4 u_projTrans;\n" //
		+ "varying vec4 v_color;\n" //
		+ "varying vec2 v_texCoords;\n" //
		+ "\n" //
		+ "void main()\n" //
		+ "{\n" //
		+ "   v_color = " + ShaderProgram.COLOR_ATTRIBUTE + ";\n" //
		+ "   v_color.a = v_color.a * (255.0/254.0);\n" //
		+ "   v_texCoords = " + ShaderProgram.TEXCOORD_ATTRIBUTE + "0;\n" //
		+ "   gl_Position =  u_projTrans * " + ShaderProgram.POSITION_ATTRIBUTE + ";\n" //
		+ "}\n";
	String fragmentShader = "#ifdef GL_ES\n" //
		+ "#define LOWP lowp\n" //
		+ "precision mediump float;\n" //
		+ "#else\n" //
		+ "#define LOWP \n" //
		+ "#endif\n" //
		+ "varying LOWP vec4 v_color;\n" //
		+ "varying vec2 v_texCoords;\n" //
		+ "uniform sampler2D u_texture;\n" //
		+ "void main()\n"//
		+ "{\n" //
		+ "  gl_FragColor = v_color * texture2D(u_texture, v_texCoords);\n" //
		+ "}";

	ShaderProgram shader = new ShaderProgram(vertexShader, fragmentShader);
	if (shader.isCompiled() == false) throw new IllegalArgumentException("Error compiling shader: " + shader.getLog());
	return shader;
}

The only thing you can do now is to wait for them to edit the shader code and make it work. Until then, you have to use older versions of LibGDX.

Submit a pull request or issue, that will make sure it gets noticed.

Or, you can create your own shader and pass it to the SpriteBatch constructor. This is the fixed up version.


static public ShaderProgram createDefaultShader () {
   String vertexShader = "#version 330 core\n"
      + "in vec4 " + ShaderProgram.POSITION_ATTRIBUTE + ";\n" //
      + "in vec4 " + ShaderProgram.COLOR_ATTRIBUTE + ";\n" //
      + "in vec2 " + ShaderProgram.TEXCOORD_ATTRIBUTE + "0;\n" //
      + "uniform mat4 u_projTrans;\n" //
      + "out vec4 v_color;\n" //
      + "out vec2 v_texCoords;\n" //
      + "\n" //
      + "void main()\n" //
      + "{\n" //
      + "   v_color = " + ShaderProgram.COLOR_ATTRIBUTE + ";\n" //
      + "   v_color.a = v_color.a * (255.0/254.0);\n" //
      + "   v_texCoords = " + ShaderProgram.TEXCOORD_ATTRIBUTE + "0;\n" //
      + "   gl_Position =  u_projTrans * " + ShaderProgram.POSITION_ATTRIBUTE + ";\n" //
      + "}\n";
   String fragmentShader = "#version 330 core\n"
      + "#ifdef GL_ES\n" //
      + "#define LOWP lowp\n" //
      + "precision mediump float;\n" //
      + "#else\n" //
      + "#define LOWP \n" //
      + "#endif\n" //
      + "in LOWP vec4 v_color;\n" //
      + "in vec2 v_texCoords;\n" //
      + "out vec4 fragColor;\n" //
      + "uniform sampler2D u_texture;\n" //
      + "void main()\n"//
      + "{\n" //
      + "  fragColor = v_color * texture(u_texture, v_texCoords);\n" //
      + "}";

   ShaderProgram shader = new ShaderProgram(vertexShader, fragmentShader);
   if (shader.isCompiled() == false) throw new IllegalArgumentException("Error compiling shader: " + shader.getLog());
   return shader;
}

Then create the SpriteBatch as in this line.


SpriteBatch spriteBatch = new SpriteBatch(1000, createDefaultShader());

This is the workaround for now. I don’t know how well this works, because I’ve never used LibGDX myself, but it should work.

OH MY GOD, FINALLY WORKS!!!

Thanks a lot, you saved the day! :smiley:

I will do it now, I found several people at google with the same problem and no one knows how to solve. Finally a solution.

Thanks for all information and thanks again!

Issue solved.