Я создаю живые обои для android, я объясню, как это работает, поскольку я считаю, что это связано с проблемой, я сожалею о длинном вопросе, но мне нужно все объяснить, потому что проблему трудно описать.Ошибка смешивания OpenGLES, альфа накапливается
Я использую OpenGLES 2.0, у меня есть реализация GLSurfaceView и реализация обоев, я передаю его рендереру, чтобы вызвать методы рисования, как и большинство живых обоев OpenGL.
Способ, которым был реализован мой рендерер: в службе обоев у меня есть независимый поток, который будет вызывать метод draw каждый X секунд, для GLSurfaceView установлено значение RENDERMODE_WHEN_DIRTY, поэтому этот поток обновлений определяет, когда происходит рисование ,
Кроме того, при обслуживании есть способ паузы и возобновления при изменении видимости. Поэтому, даже если я выйду с обоев, служба будет работать, сохраняя состояние всего, пока оно не будет возобновлено.
Теперь проблема, я получил прозрачность работает, как вы можете увидеть здесь:
Но когда я теряю фокус и вернуть на обоях, я нажимаю кнопку назад на селекторном обои андроида, или изменить обои, а затем вернуться к нему. Альфа-ценность вещей будет расти.
Здесь 2 ячейки, одна слева имеет начальное значение альфа 0,1, то есть значение справа 0.5.
Теперь, когда я уйду и вернусь, метод GLSurfaceView onVisibilityChanged будет называться, он работает, как ожидалось, но как вы можете увидеть значения альфа будет увеличиваться по какой-то причине, и продолжают расти, как я уеду и вернуться:
1 разы 2 раза
путь я рисунок сетки установить в моем пиксельном шейдере обращу значение в форме перед нанесением сетки, и что единообразное будет умножить цвет текстуры.
Вот фрагмент шейдера:
precision mediump float;
uniform vec4 u_color;
uniform sampler2D u_texture;
varying vec2 v_textcoord;
void main()
{
gl_FragColor = u_color * texture2D(u_texture, v_textcoord);
}
Конечно перед нанесением сетки я установить смешивание и blendfunc:
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
GLES20.glUniform4f(DayAndNightRenderer.BaseShader.GetUniform("u_color"), color.r, color.g, color.b, 0.5f);
texture.Bind();
mesh.Draw(GLES20.GL_TRIANGLE_FAN, DayAndNightRenderer.BaseShader);
GLES20.glDisable(GLES20.GL_BLEND);
И рисунок сетки, даже если цвет равномерная установлен перед тем чертеж:
GLES20.glUniformMatrix4fv(shader.GetUniform("u_transmat"), 1, false, Transform.GetProjectedTransformationMatrix().ToFloatBuffer());
GLES20.glEnableVertexAttribArray(shader.GetAttribute("a_pos"));
GLES20.glEnableVertexAttribArray(shader.GetAttribute("a_textcoord"));
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, VBO[0]);
GLES20.glVertexAttribPointer(shader.GetAttribute("a_pos"), 3, GLES20.GL_FLOAT, false, Vertex.SIZE, 0);
GLES20.glVertexAttribPointer(shader.GetAttribute("a_textcoord"), 3, GLES20.GL_FLOAT, false, Vertex.SIZE, Vertex.POS_SIZE);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, IBO[0]);
GLES20.glDrawElements(primitive, size, GLES20.GL_UNSIGNED_INT, 0);
GLES20.glDisableVertexAttribArray(shader.GetAttribute("a_textcoord"));
GLES20.glDisableVertexAttribArray(shader.GetAttribute("a_pos"));
то, что я пытался до сих пор:
- Изменение смеси funcs, кажется, не влияют на ошибку, которая добавляет к значению альфа
- перезаряжая шейдер между потерями фокуса
- Очисткой фреймбуфера, я установил GLES20.glClearColor (0f, 0f , 0f, 0f); при запуске и вызове GLES20.glClear (GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); каждый кадр
Ничего из вышеперечисленного не работает, и я не использую какую-либо переменную, которую я использую, чтобы настроить альфа, которая накапливается, альфа вещей задана константой, как вы можете видеть в коде, где я устанавливаю цвет равномерная.
Я не знаю, что вызывает это, это происходит только, теряя фокус обоев и возвращаясь к нему, при первом запуске, не возвращаясь, он отлично рисует.
Вот onVisibilityChanged метод, кстати:
@Override
public void onVisibilityChanged(boolean visible)
{
super.onVisibilityChanged(visible);
if (hassetrenderer)
{
if (visible)
{
OpenGLES2WallpaperService.updatehandler.Start();
glsurfaceview.onResume();
Log.i("DN", "State: running");
}
else
{
OpenGLES2WallpaperService.updatehandler.Stop();
glsurfaceview.onPause();
Log.i("DN", "State: not running");
}
}
}