【问题标题】:Libgdx shader, render and draw confusionLibgdx 着色器,渲染和绘制混乱
【发布时间】:2014-08-16 00:48:34
【问题描述】:

在我的 Libgdx Scene2D 舞台中,我试图让演员闪烁白色。 使用 OpenGLES 2.0,我知道我需要使用着色器来实现这一点,但我在实现它时遇到了问题。

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

My World 类是创建舞台的地方。它是这样渲染的:

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 类中定义的演员。这个类有自己的 我尝试使用着色器将演员着色为纯白色的绘制方法。这里是draw方法:

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、绘制方法和渲染方法是如何协同工作的!

感谢您的宝贵时间

【问题讨论】:

  • 您是否在某处重置了Shader,以便SpriteBatch 再次使用默认的Shader?实际上,在你的情况下,我不会用Shader 来做,这个任务并不复杂。只需存储默认的Texture 和纯白色Texture 并说Texture t = flashing ? white : default;draw Texture t
  • 嘿@Springrbua,感谢您的回答。不,我认为我没有在任何地方重置着色器,我该怎么做?我宁愿避免使用手动创建的第二组白色纹理,我的游戏中应该有几十个不同的纹理,每个都有独特的形状,所以我认为编程方法看起来更好
  • 无论如何你都可以而且应该使用TextureAtlas,但你必须做出决定。我想如果你说batch.setShader(null) 它会再次使用默认的Shader,但我不确定。
  • setShader 的 javadok 说:“使用 null 参数调用此方法以使用默认着色器。”
  • 太棒了,这行得通,谢谢。如果您想将其写为答案,我可以为您批准:) 我已经使用了 TextureAtlas,但除非我没有得到您,否则我不想手动创建十几个纯白色精灵的 png 文件。感谢您的宝贵时间

标签: opengl libgdx shader render draw


【解决方案1】:

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

Texture t = flashing ? whiteTexture : defaultTexture;

drawTexture t
只是一个建议:如果不是绝对必要,请不要使用batch.flush(),因为flush() 会对GPU 进行绘图调用,这会降低一些性能。

【讨论】:

  • 非常感谢,不仅您的回答是正确的,而且您还花时间事先讨论。你也有很好的建议。祝你有美好的一天
  • 非常感谢!你也是:)
猜你喜欢
  • 2023-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多