2016-04-09 2 views
2

Я экспериментировал с полевыми шрифтами расстояния, как описано в этой статье: https://github.com/libgdx/libgdx/wiki/Distance-field-fontslibGDX - Пользовательские шейдеры для TextButton шрифта

Все отлично работает, когда я просто делаю шрифт, но когда я пытаюсь использовать затенение на TextButton, кнопка просто становится белой, потому что она применяет шейдер ко всей кнопке, а не только текст. Я огляделся, но я не могу найти информацию о том, как изменить шейдер только для текста TextButton, поэтому я прошу; как применить шейп-шейдер к текстовому рендерингу TextButton?

Init Код:

textShader = new ShaderProgram(Gdx.files.internal("graphics/shaders/font/font.vert"), 
      Gdx.files.internal("graphics/shaders/font/font.frag")); 
//exact same shaders as linked article 
stage = new Stage(); 
stage.getBatch().setShader(textShader); 
//Setting the shader for the stage will set the shader for everything in the stage, 
//like my labels/buttons etc. This works fine for my labels as they are plain text, 
//but my buttons become completely white. 

init the rest of my labels, buttons, batches etc... 

Рендер код:

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

render background/other stuff... 

stage.act(delta); 
stage.draw(); 

Фрагмент шейдеры:

#ifdef GL_ES 
precision mediump float; 
#endif 

uniform sampler2D u_texture; 

varying vec4 v_color; 
varying vec2 v_texCoord; 

const float c_width = 0.5; 
const float c_edge = 0.1; 

const vec2 c_offset = vec2(0); 

const float c_borderWidth = 0.5; 
const float c_borderEdge = 0.5; 

const vec3 c_color = vec3(0.7, 0.3, 0.1); 
const vec3 c_outlineColor = vec3(0.3); 

void main() { 
    float distance = 1.0 - texture(u_texture, v_texCoord).a; 
    float alpha = 1.0 - smoothstep(c_width, c_width + c_edge, distance); 

    float distance2 = 1.0 - texture(u_texture, v_texCoord + c_offset).a; 
    float outlineAlpha = 1.0 - smoothstep(c_borderWidth, c_borderWidth + c_borderEdge, distance2); 

    float overallAlpha = alpha + (1.0 - alpha) * outlineAlpha; 
    vec3 overallColour = mix(c_outlineColor, c_color, alpha/overallAlpha); 

    gl_FragColor = vec4(overallColour, overallAlpha); 
} 

Vertex шейдеров:

uniform mat4 u_projTrans; 

attribute vec4 a_position; 
attribute vec2 a_texCoord0; 
attribute vec4 a_color; 

varying vec4 v_color; 
varying vec2 v_texCoord; 

void main() { 
    gl_Position = u_projTrans * a_position; 
    v_texCoord = a_texCoord0; 
    v_color = a_color; 
} 
+0

мы можем видеть ваш код, пожалуйста? –

+0

Я добавил код. Я также должен отметить, что текст в TextButtons прекрасен, это всего лишь фон кнопок, которые запутываются. – Charanor

ответ

3

Шейдер поля расстояния не может отображать другие вещи в обычном режиме. Чтобы использовать его в scene2D, вам нужно временно переключиться на этот шейдер только при рисовании ярлыков, поэтому вам нужно будет создать подкласс Label, который может поменять шейдер. Может быть, что-то вроде этого:

public class CustomShaderLabel extends Label { 
    private ShaderProgram shader; 
    public CustomShaderLabel(CharSequence text, Skin skin) { 
     super(text, skin); 
    } 

    public CustomShaderLabel(CharSequence text, Skin skin, String styleName) { 
     super(text, skin, styleName); 
    } 

    public CustomShaderLabel(CharSequence text, Skin skin, String fontName, Color color) { 
     super(text, skin, fontName, color); 
    } 

    public CustomShaderLabel(CharSequence text, Skin skin, String fontName, String colorName) { 
     super(text, skin, fontName, colorName); 
    } 

    public CustomShaderLabel(CharSequence text, LabelStyle style) { 
     super(text, style); 
    } 

    public ShaderProgram getShader() { 
     return shader; 
    } 

    public void setShader(ShaderProgram shader) { 
     this.shader = shader; 
    } 

    public void draw (Batch batch, float parentAlpha) { 
     if (shader != null) batch.setShader(shader); 
     super.draw(batch, parentAlpha); 
     if (shader != null) batch.setShader(null); 
    } 
} 

Имейте в виде, что это приведет к дополнительным партиям флеши везде, где есть этикетки, которые могли бы стать проблемой, если у вас есть сложная иерархия с большим количеством ярлыков.

Поскольку TextButton не знает, как использовать свой собственный тип ярлыка, вам нужно будет использовать стандартную кнопку и добавить к ней ярлык или, возможно, скопировать большую часть класса TextButton для создания собственной версии (поэтому вы можете использовать TextButton.TextButtonStyles для стилизации своей метки внутри кнопки).

+0

Это работает, но теперь у меня есть проблема, что мои ярлыки не используют мои действия (они не fadeIn/fadeOut/не изменяют свою альфу). Любое решение? – Charanor

+0

Если вы используете шейдер из этой ссылки, замените альфа на последней строке буквой альфа * v_color.a – Tenfour04

+1

Я не использую тот же шейдер, но вместо этого я сделал generalAlpha * v_color.a в своем коде, и это сработало. Благодаря! – Charanor

Смежные вопросы