【问题标题】:libgdx shaders - trying to set colorlibgdx 着色器 - 尝试设置颜色
【发布时间】:2026-01-03 06:05:01
【问题描述】:

我正在 LibGDX 中使用着色器做一些初步工作。我正在尝试手动设置颜色,但我得到的只是白色。

顶点着色器:

attribute vec4 a_position;
uniform mat4 u_projTrans;

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

片段着色器:

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

如您所见,非常简单。通过这种设置,我可以绘制形状,但它们总是呈白色。使用我的片段着色器,我希望一切都是红色的。

我是否遗漏了 libgdx 堆栈中的某些内容?某些 libgdx 着色器默认值或其他东西是否会进一步覆盖链上的某些内容?

屏幕输出:

【问题讨论】:

  • 您如何在代码中使用着色器程序? I am able to draw shapes 是什么意思,是网格吗?
  • 我正在尝试不使用网格。这可能是不可能的......试图在不使用 Mesh 的情况下理解较低级别的功能。如果我今天不能得到它,我会放一个 Mesh。
  • 另外,我没有做的一件事是运行 ShaderProgram.begin()。当我这样做时,顶点实际上完全消失了。我看到您没有在代码中使用 begin(),所以它可能不是必需的,或者在您启动 SpriteBatch 时会自动发生。无论如何,感谢您的指点。

标签: java opengl libgdx shader opengl-es-2.0


【解决方案1】:

您需要以某种方式将顶点传递给 OpenGL,因此 LibGDX 具有满足此要求的 Mesh 类。我正在使用SpriteBatch,它有自己的网格用于绘制。

顶点着色器:

attribute vec4 a_position;
uniform mat4 u_projTrans;

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

片段着色器:

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

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

着色器测试

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();
    }
}

输出是:

编辑

网格什么都不是,它只是一个大的顶点数组,包含 OpenGL 所需的值,单个顶点可以保存有关 PositionColorTexture Coordinates 或其他任何我们想要传递的信息到着色器。

根据您在片段着色器中固定颜色为红色的问题,因此您只需将四边形的位置传递给 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;
    }
}

【讨论】:

  • 是的,我正在尝试不使用 spritebatch 或网格。但这可能是试图过多地与框架抗争。谢谢提醒!
  • 感谢您提供有关 ShaderProgram.pedantic 的小提示……不知道那个。
  • @ether_joe 我更新了我的答案请检查,ShaderProgram.pedantic 只是一个标志,表明属性和制服是否必须始终存在 SpriteBatch 要求的时间
  • 是的,我现在在我的代码中包含了一个最小的网格。我以前使用 Java FloatBuffer 并将其与 glVertexAttribPointer() 一起传递,以查看我可以走多低级别。有点愚蠢,但我正在关注非 libgdx 教程,并对它的工作原理感到好奇。网格应该让我到达那里。再次感谢!