Opengl Libgdx着色器,渲染和绘制混乱

Opengl Libgdx着色器,渲染和绘制混乱,opengl,libgdx,shader,render,draw,Opengl,Libgdx,Shader,Render,Draw,在我的Libgdx场景2d阶段,我试图让演员用白色闪烁。 在OpenGLES 2.0中,我明白我需要使用着色器来实现这一点,但在实现它时遇到了问题 我的目标是在一个特殊的游戏事件中给一个演员涂上纯白的颜色。问题是在这个特定的事件中,舞台上的所有东西都变成白色(所有演员和背景),而不仅仅是选定的演员纹理 我的世界级是创造舞台的地方。它的渲染方式如下: public void render() { Gdx.gl.glClearColor(1, 1, 1, 1); Gdx.gl.glClear(GL2

在我的Libgdx场景2d阶段,我试图让演员用白色闪烁。 在OpenGLES 2.0中,我明白我需要使用着色器来实现这一点,但在实现它时遇到了问题

我的目标是在一个特殊的游戏事件中给一个演员涂上纯白的颜色。问题是在这个特定的事件中,舞台上的所有东西都变成白色(所有演员和背景),而不仅仅是选定的演员纹理

我的世界级是创造舞台的地方。它的渲染方式如下:

public void render() {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
update();
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
}
在这个阶段中,我使用MyActor类中定义的参与者。这个班有自己的课 绘制方法,其中我尝试使用着色器将演员着色为纯白。以下是绘制方法:

public void draw(Batch batch, float alpha) {
    if (flashing) {
        batch.setShader(shader);            
    }

    batch.flush();

    Color color = getColor();
    batch.setColor(color.r, color.g, color.b, color.a * alpha);

    batch.draw(tr, getX(), getY(), side/2, side/2, side, side, getScaleX(), getScaleY(), 0);        
}
很明显我对这批货做了些错事。它不是把这个演员涂成白色,而是把所有的东西都涂成白色。而且,即使布尔值闪烁=false,它仍保持白色

以下是如何在actor类MyActor中设置着色器:

ShaderProgram shader;
String vertexShader =
        "attribute vec4 a_position; \n" +
        "attribute vec4 a_color;\n" +
        "attribute vec2 a_texCoord0; \n" +
        "uniform mat4 u_projTrans; \n" +
        "varying vec4 v_color; \n" +
        "varying vec2 v_texCoords; \n" +
        "void main() { \n" +
        "v_color = a_color; \n" +
        "v_texCoords = a_texCoord0; \n" +
        "gl_Position = u_projTrans * a_position; \n" +
        "};";

String fragmentShader = "#ifdef GL_ES\n" +
        "precision mediump float;\n" +
        "#endif\n" + "varying vec4 v_color;\n" +
        "varying vec2 v_texCoords;\n" +
        "uniform sampler2D u_texture;\n" +
        "uniform float grayscale;\n" +
        "void main()\n" +
        "{\n" +
        "vec4 texColor = texture2D(u_texture, v_texCoords);\n" +
        "float gray = dot(texColor.rgb, vec3(5, 5, 5));\n" +
        "texColor.rgb = mix(vec3(gray), texColor.rgb, grayscale);\n" +
        " gl_FragColor = v_color * texColor;\n" +
        "}";
然后开始:

shader = new ShaderProgram(vertexShader, fragmentShader);
我做错了什么

我必须承认,我可能没有正确理解MyActor的批处理、绘图方法和渲染方法是如何协同工作的


感谢您的时间

这里的问题是,您从未将
着色器
设置回默认的
着色器
,因此您的
Spritebatch
始终使用“纯白”
着色器
。 作为
setShader(ShaderProgram shader)
sais的javadock,您可以通过调用
setShader(null)
重置
shader
另一种可能是对纯白使用另一种
纹理
,并简单地说:

Texture t = flashing ? whiteTexture : defaultTexture;
绘制
纹理t


建议:如果不是绝对必要的话,不要使用
batch.flush()
,因为
flush()
对GPU进行绘图调用,这会降低性能。

是否在某个地方重置
着色器
,以便
SpriteBatch
再次使用defaukt
着色器
?实际上,在您的情况下,我不会使用
着色器
,此任务没有那么复杂。只需存储默认的
纹理
和纯白色
纹理
,然后说
纹理t=flash?白色:默认
绘制
纹理t
。嘿@Springrbua,谢谢你的回答。不,我想我不会在任何地方重置着色器,我该怎么做?我宁愿避免使用第二组手动创建的白色纹理,我的游戏中应该有几十种不同的纹理,每种都有一个独特的形状,因此编程方法看起来更好,我认为您可以也应该使用
TextureAtlas
,但您必须做出决定。我想如果你说
batch.setShader(null)
它会再次使用默认的
着色器
,但我不确定。
setShader
的javadok说:“使用null参数调用此方法以使用默认着色器。”很好,谢谢。如果你想写它作为一个答案,我可以批准它为你:)我已经使用了一个TextureAtlas,但除非我没有得到你,我不想手动创建png文件的十几个精灵与白色纯色。谢谢你的时间非常感谢,不仅你的答案是正确的,而且你也可以在讨论之前抽出时间。你也有很好的建议。祝你过得愉快谢谢!你也是:)