1
votes

I'm doing some beginning work with shaders in LibGDX. I'm trying to set the color manually but all I get is white.

vertex shader:

attribute vec4 a_position;
uniform mat4 u_projTrans;

void main() {
    gl_Position = u_projTrans * a_position;
    gl_PointSize = 10.0;
}   

fragment shader:

void main()
{
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}

Extremely simple as you can see. With this setup I am able to draw shapes, but they always come out white. With my fragment shader I would expect everything to be red.

Am I missing something in the libgdx stack? Is something getting overridden further up the chain by some libgdx shader defaults or something?

Screen output: Should be red, is white no matter what I do

1
how you're using shader program in your code ? and what do you mean by I am able to draw shapes, is it mesh ?Abhishek Aryan
I'm trying to do it without a Mesh. That might be impossible ... trying to understand the lower level functions without using Mesh. If I can't get it today I'll put a Mesh in.ether_joe
Also, one thing I hadn't done was run ShaderProgram.begin(). When I did that, the vertices disappeared entirely actually. i see you're not using begin() in your code so perhaps it's not required or happens automatically when you start a SpriteBatch. Regardless though thanks for the pointers.ether_joe

1 Answers

1
votes

Somehow you need to pass vertex to OpenGL so LibGDX having Mesh class for this requirement. I am using SpriteBatch that having own mesh that use to draw.

Vertex Shader :

attribute vec4 a_position;
uniform mat4 u_projTrans;

void main()
{
   gl_Position =  u_projTrans * a_position;
}

Fragment Shader :

#ifdef GL_ES
#define LOWP lowp
precision mediump float;
#else
#define LOWP
#endif

void main()
{
  gl_FragColor = vec4(1,0,0,1);
}

ShaderTest

public class ShaderTest extends ApplicationAdapter {

    SpriteBatch spriteBatch;
    Texture texture;
    ShaderProgram shaderProgram;

    @Override
    public void create() {
        spriteBatch=new SpriteBatch();

         shaderProgram=new ShaderProgram(Gdx.files.internal("default.vertex.glsl"),Gdx.files.internal("default.fragment.glsl"));
         shaderProgram.pedantic = false;
         if(shaderProgram.isCompiled()) {
            System.out.println("Compiled Successfully");
            spriteBatch.setShader(shaderProgram);
         }else {
            System.out.println("Some Problem in Shader");
         }

        texture=new Texture("badlogic.jpg");
    }

    @Override
    public void render() {

        Gdx.gl.glClearColor(1,1,0,1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        spriteBatch.begin();
        spriteBatch.draw(texture,100,100);
        spriteBatch.end();
    }

    @Override
    public void dispose() {
        shaderProgram.dispose();
        texture.dispose();
        spriteBatch.dispose();
    }
}

And the output is :

enter image description here

EDIT

Mesh is nothing, It is just a big array of vertices, contains value that required by OpenGL and a single vertex can hold information about Position, Color, Texture Coordinates, or whatever else we would like to pass to the shaders.

According to question you fixed colour in fragment shader that is RED so you only need to pass position of quard to OpenGL.

public class QuardTest extends ApplicationAdapter {

    Mesh quard;
    OrthographicCamera cam;
    ShaderProgram shaderProgram;

    private int Idx = 0;
    private float[] verts= new float[4 * 2];

    @Override
    public void create() {

        cam=new OrthographicCamera();
        shaderProgram=new ShaderProgram(Gdx.files.internal("default.vertex.glsl"),Gdx.files.internal("default.fragment.glsl"));
        if(shaderProgram.isCompiled()) {
            System.out.println("Compiled Successfully");
        }else {
            System.out.println("Some Problem in Shader");
        }

        quard =new Mesh(true,4,0,new VertexAttribute(VertexAttributes.Usage.Position, 2, "a_position"));
    }

    @Override
    public void render() {

        Gdx.gl.glClearColor(1,1,0,1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        drawRect(100,100,100,100);
        drawRect(250,250,50,50);
    }

    public void drawRect(float x, float y, float width, float height){

        if (Idx ==verts.length) {
            flush();
        }

        verts[Idx++] = x;
        verts[Idx++] = y;

        verts[Idx++] = x + width;
        verts[Idx++] = y;

        verts[Idx++] = x + width;
        verts[Idx++] = y + height;

        verts[Idx++] = x;
        verts[Idx++] = y + height;
    }

    public void flush(){

        if (Idx ==0)
            return;

        quard.setVertices(verts);
        Gdx.gl.glDepthMask(false);
        int vertexCount = (Idx /2);
        cam.setToOrtho(false, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
        shaderProgram.begin();
        shaderProgram.setUniformMatrix("u_projTrans", cam.combined);
        quard.render(shaderProgram, GL20.GL_TRIANGLE_FAN, 0, vertexCount);
        shaderProgram.end();
        Gdx.gl.glDepthMask(true);

        Idx =0;
    }
}