2014-12-07 7 views
0

Я создаю живые обои для android, я объясню, как это работает, поскольку я считаю, что это связано с проблемой, я сожалею о длинном вопросе, но мне нужно все объяснить, потому что проблему трудно описать.Ошибка смешивания OpenGLES, альфа накапливается

Я использую OpenGLES 2.0, у меня есть реализация GLSurfaceView и реализация обоев, я передаю его рендереру, чтобы вызвать методы рисования, как и большинство живых обоев OpenGL.

Способ, которым был реализован мой рендерер: в службе обоев у меня есть независимый поток, который будет вызывать метод draw каждый X секунд, для GLSurfaceView установлено значение RENDERMODE_WHEN_DIRTY, поэтому этот поток обновлений определяет, когда происходит рисование ,

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

Теперь проблема, я получил прозрачность работает, как вы можете увидеть здесь: first time rendering

Но когда я теряю фокус и вернуть на обоях, я нажимаю кнопку назад на селекторном обои андроида, или изменить обои, а затем вернуться к нему. Альфа-ценность вещей будет расти.

Здесь 2 ячейки, одна слева имеет начальное значение альфа 0,1, то есть значение справа 0.5. Initial setup, no focus is lost yet

Теперь, когда я уйду и вернусь, метод GLSurfaceView onVisibilityChanged будет называться, он работает, как ожидалось, но как вы можете увидеть значения альфа будет увеличиваться по какой-то причине, и продолжают расти, как я уеду и вернуться:

Exited and went back 1 time 1 разы Exited and went back 2 times 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"); 
     } 
    } 
}  

ответ

0

Ну, я установил его, убивая процесс обои в когда GLSurfaceView уничтожается (android.os.Process.killProcess (android.os.Process.myPid())).

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

Тем не менее я буду убивать процесс как решение.