Nesse artigo, publicado em 14/06/2012 no blog obviam.net, o autor se aprofunda nos recursos gráficos da plataforma Android. O Android suporta a API OpenGL ES. Não é preciso dizer que a manipulação de gráficos através de uma GPU dedicada é muito mais eficiente do que faze-lo na CPU. Muitos dispositivos Android possuem uma GPU dedicada.
O OpenGL é uma API para desenhar gráficos 2D e 3D que são renderizados na GPU. Isso libera recursos preciosos de computação da CPU que podem ser usados em física mais complexa ou mais entidades ou algo não relacionado a parte gráfica.
Se você tem conhecimento de como exibir gráficos em um dispositivo Android, você já sabe que para poder exibir elementos gráficos, precisa de uma superfície (surface) ou renderizador (renderer). No artigo indicado no último link, é mostrado o uso de um SurfaceView a partir do qual obtemos o Canvas e fazemos todos os desenhos nele chamando o método draw de dentro do loop do jogo.
O uso do OpenGL não é muito diferente. O Android vem com uma implementação dedicada da interface SurfaceView para exibir imagens renderizadas pela OpenGL.
Vamos criar o projeto da forma comum.
Chamaremos a Activity simplesmente de Run
. Verifique o que o assistente gerou, que deve ser o seguinte:
public class Run extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } }
Criando o renderizador do OpenGL
Vamos criar agora o renderizador. Crie um classe com o nome GlRenderer
que implementa a interfaceandroid.opengl.GLSurfaceView.Renderer
.
Ela deve ficar dessa forma:
import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.opengl.GLSurfaceView.Renderer; public class GlRenderer implements Renderer { @Override public void onDrawFrame(GL10 gl) { } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { } @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { } }
Precisamos implementar os 3 métodos acima. No momento eles estão vazios e não fazem nada.
Os métodos
onSurfaceCreated(GL10 gl, EGLConfig config)
criado ou recriado. É importante dar suporte a parte da recriação pois a cada vez que o dispositivo entra em hibernação e acorda, a superfície é recriada. Como o contexto que guarda os recursos é destruído também, esse é local onde iremos carrega-los (imagens para as texturas, etc).
onSurfaceChanged(GL10 gl, int width, int height)
é chamado sempre a superfície muda de tamanho. Isso afeta principalmente nosso viewport. O viewport é apenas uma região retangular na qual visualizamos o mundo do jogo.
onDrawFrame(GL10 gl)
é chamado pela thread do renderizador para desenhar cada quadro. Aqui é onde todo o processo de desenho acontece. Não precisamos chamar esse método explicitamente. Uma thread de renderização é chamada pelo Android e ela chama esse método.
Vamos alternar para o renderizador do OpenGL. Verifique a nova activity Run
.
package net.obviam.opengl; import android.app.Activity; import android.opengl.GLSurfaceView; import android.os.Bundle; import android.view.Window; import android.view.WindowManager; public class Run extends Activity { /** The OpenGL view */ private GLSurfaceView glSurfaceView; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // requesting to turn the title OFF requestWindowFeature(Window.FEATURE_NO_TITLE); // making it full screen getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // Initiate the Open GL view and // create an instance with this activity glSurfaceView = new GLSurfaceView(this); // set our renderer to be the main renderer with // the current activity context glSurfaceView.setRenderer(new GlRenderer()); setContentView(glSurfaceView); } /** Remember to resume the glSurface */ @Override protected void onResume() { super.onResume(); glSurfaceView.onResume(); } /** Also pause the glSurface */ @Override protected void onPause() { super.onPause(); glSurfaceView.onPause(); } }
Na linha 12 declaramos uma variável membro GLSurfaceView
. Esse é o nosso view OpenGL fornecido pelo Android. Quando instanciamos ele (linha 27) temos que fazer com que ele tenha ciência do contexto. Isso é, para o view ter acesso ao ambiente da aplicação.
Tudo o que precisamos fazer é adicionar nosso renderizador a esse view. Isso fazemois na linha 31. A linha 32 diz à activity para usar nosso view OpenGL.
Os métodos onResume()
e onPause()
estão sendo substituídos e disparam os métodos respectivos em nosso view.
Você pode executar a aplicação como uma app Android e deve visualizar uma tela preta vazia. E é isto. Alternamos nossa aplicação do canvas para o renderizador OpenGL.
Para aprender como exibir primitivas (triângulos, retângulos) como o OpenGL, verifique o próximo artigo.
Traduzido de obviam.net