Translate

Monday, 26 November 2018

Libgdx shaders : Passing multiple shaders in one shader

When using shaders in 3D libgdx we encounter an issue of binding textures to models. Sometimes all environment and 3d models used in game use same textures , specially when you are working with multiple models.

Following codes is used in this example

Vetex Shader 

attribute vec3 a_position;
 attribute vec3 a_normal;
 attribute vec2 a_texCoord0;
 uniform mat4 u_worldTrans;
 uniform mat4 u_projTrans;
 varying vec2 v_texCoord0;
 void main() 

{
 v_texCoord0 = a_texCoord0; gl_Position = u_projTrans * u_worldTrans * vec4(a_position, 1.0);

}



Fragment Shader

#ifdef GL_ES precision mediump float;
 #endif uniform vec3 u_colorU;
 uniform vec3 u_colorV;
 varying vec2 v_texCoord0;
 uniform sampler2D u_texture;
 void main() { 
  gl_FragColor = texture2D(u_texture , v_texCoord0); 
}


In start of render


Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); // Gdx.gl20.glActiveTexture(GL20.GL_TEXTURE0); // texture.bind(); Gdx.gl20.glEnable(GL20.GL_TEXTURE_2D); Gdx.gl20.glEnable(GL20.GL_BLEND);





And here is Working multi texture binding with single shader


import com.badlogic.gdx.Gdx;import com.badlogic.gdx.graphics.Camera;import com.badlogic.gdx.graphics.Color;import com.badlogic.gdx.graphics.GL20;import com.badlogic.gdx.graphics.GLTexture;import com.badlogic.gdx.graphics.g3d.Renderable;import com.badlogic.gdx.graphics.g3d.Shader;import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;import com.badlogic.gdx.graphics.g3d.attributes.TextureAttribute;import com.badlogic.gdx.graphics.g3d.utils.RenderContext;import com.badlogic.gdx.graphics.glutils.ShaderProgram;import com.badlogic.gdx.utils.GdxRuntimeException;
import screens.PlayScreen;
public class TestShader implements Shader {
    ShaderProgram program;
    Camera camera;
    RenderContext context;
    int u_projTrans;
    int u_worldTrans;
    int u_colorU;
    int u_colorV;

    PlayScreen playScreen;

    public TestShader(PlayScreen playScreen) {
        this.playScreen =  playScreen;
    }

    @Override    public void init() {
        String vert = Gdx.files.internal("shaders/uvcolor.vertex.glsl").readString();
        String frag = Gdx.files.internal("shaders/uvcolor.fragment.glsl").readString();
        System.out.println("hello shader" + vert);
        program = new ShaderProgram(vert, frag);
        program.pedantic = false;
        if (!program.isCompiled())
            throw new GdxRuntimeException(program.getLog());
        u_projTrans = program.getUniformLocation("u_projTrans");
        u_worldTrans = program.getUniformLocation("u_worldTrans");
        u_colorU = program.getUniformLocation("u_colorU");
        u_colorV = program.getUniformLocation("u_colorV");
    }

    @Override    public void dispose() {
        program.dispose();
    }

    @Override    public void begin(Camera camera, RenderContext context) {
        this.camera = camera;
        this.context = context;
        program.begin();
        program.setUniformMatrix(u_projTrans, camera.combined);
        context.setDepthTest(GL20.GL_LEQUAL);
        context.setCullFace(GL20.GL_BACK);
        

    }

    @Override    public void render(Renderable renderable) {
        program.setUniformMatrix(u_worldTrans, renderable.worldTransform);
        Color colorU = ((ColorAttribute)renderable.material.get(ColorAttribute.Diffuse)).color;
        Color colorV = ((ColorAttribute)renderable.material.get(ColorAttribute.Diffuse)).color;

        program.setUniformf(u_colorU, colorU.r, colorU.g, colorU.b);
        program.setUniformf(u_colorV, colorV.r, colorV.g, colorV.b);

        ((TextureAttribute)renderable.material.get(TextureAttribute.Diffuse)).textureDescription.texture.bind();

        renderable.meshPart.render(program);
    }

    @Override    public void end() {
        program.end();
    }

    @Override    public int compareTo(Shader other) {
        return 0;
    }
    @Override    public boolean canRender(Renderable renderable) {
        return renderable.material.has(ColorAttribute.Diffuse);
    }
}


Happy coding :P. Please let me know in comments if this helps :D