Red de conocimiento de abogados - Derecho de sociedades - Cómo utilizar los efectos multimedia de OpenGL ES en Android

Cómo utilizar los efectos multimedia de OpenGL ES en Android

Preparación

Para comenzar este tutorial, debes tener:

1. Un IDE que admita el desarrollo de Android. Puede descargar la última versión de Android Studio desde el sitio web para desarrolladores de Android.

2. Un teléfono Android con Android 4.0 y superior, y la GPU es compatible con OpenGL ES2.0

3. Conocimientos básicos de OpenGL

Configuración del entorno OpenGL ES.

Crear GLSurfaceView

Para mostrar gráficos OpenGL, necesita usar la clase GLSurfaceView Al igual que cualquier otra subclase de Vista, puede agregarla a su Actividad o encima de una. Fragmento, definiéndolo en el archivo xml de diseño o creando una instancia en el código.

En este tutorial, usamos GLSurfaceView como la única Vista en nuestra Actividad, por lo que, para simplificar, creamos una instancia de GLSurfaceView en el código y la asignamos. Pásala en setContentView para que ocupe toda la pantalla de tu teléfono. . El método onCreate en Actividad

es el siguiente:

protected void onCreate(Bundle saveInstanceState) {

super.onCreate(savedInstanceState);

GLSurfaceView view = new GLSurfaceView(this);

setContentView(view);

}123456123456

Porque el marco de efectos multimedia solo admite OpenGL ES2.0 y la versión anterior, así que pase 2 en el método setEGLContextClientVersion;

view.setEGLContextClientVersion(2);11

Para garantizar que GLSurfaceView solo se represente cuando sea necesario, pasamos el método setRenderMode Establecido en:

view.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);11

Crear renderizador

El renderizador es responsable de renderizar el contenido en GLSurfaceView.

Cree una clase que implemente la interfaz GLSurfaceView.Renderer. Aquí planeamos nombrar esta clase EffectsRenderer, agregar un constructor y anular el método abstracto en la interfaz, de la siguiente manera:

public. la clase EffectsRenderer implementa GLSurfaceView.Renderer {

public EffectsRenderer(Context context){

super();

}

@Override

public void onSurfaceCreated(GL10 gl, EGLConfig config) {

}

@Override

public void onSurfaceChanged(GL10 gl, int width , int altura) {

}

@Override

public void onDrawFrame(GL10 gl) {

}

}123456789101112131415161718123456789101112131415161718

Vuelve a Actividad y llama al método setRenderer para permitir que GLSurfaceView use el Renderer que creamos:

view.setRenderer(new EffectsRenderer(this));11

Escribe un archivo de manifiesto

Si deseas publicar tu aplicación en Google Store, agrega la siguiente declaración en el archivo AndroidManifest.xml:

11

Esto garantizará que su aplicación solo pueda instalarse en dispositivos compatibles con OpenGL ES2.0. El entorno OpenGL ya está listo.

Crear un plano OpenGL

Definir vértices

GLSurfaceView no puede mostrar una foto directamente. La foto primero debe convertirse en una textura y aplicarse al cuadrado OpenGL superior. . En este tutorial, crearé un plano 2D con 4 vértices. Para simplificar, usaré un rectángulo. Ahora, crearé una nueva clase Cuadrado y la usaré para representar la forma.

public class Square {

}123123

El origen del sistema de coordenadas del sistema OpenGL predeterminado está en el centro, por lo que las coordenadas de las cuatro esquinas se puede expresar como:

Esquina inferior izquierda: (-1, -1)

Esquina inferior derecha: (1, -1)

Esquina superior derecha : (1, 1)

Esquina superior izquierda: (-1, 1)

Todos los objetos que dibujamos usando OpenGL deben estar determinados por triángulos. Para dibujar un cuadrado, debemos. Necesito dos objetos con triángulos laterales comunes, eso significa que las coordenadas de estos triángulos deben ser:

triángulo 1: (-1, -1), (1, -1) y (- 1, 1)

triángulo 2: (1, -1), (-1, 1) y (1, 1)

Crea una matriz flotante para representar estos vértices:

vértices flotantes privados[] = {

-1f, -1f,

1f, -1f,

-1f, 1f ,

1f, 1f,

};123456123456

Para posicionar la textura en el cuadrado, necesita determinar las coordenadas del vértice de la textura y cree otra matriz para representar las coordenadas de los vértices de la textura:

textureVertices flotantes privados[] = {

0f,1f,

1f,1f,

0f,0f,

1f,0f

};123456123456

Crear buffer

Estas matrices de coordenadas deben ser convertidos en caracteres de búfer (búfer de bytes) para su uso en OpenGL Antes, a continuación defina:

private FloatBuffer verticesBuffer;

private FloatBuffer TextureBuffer;1212

Inicializar estos búferes en el método inicializeBuffers: use ByteBuffer. allocateDirect para crear el búfer, debido a que el valor flotante es de 4 bytes, entonces la longitud de la matriz de bytes que necesitamos debe ser 4 veces mayor que la del flotante.

El método ByteBuffer.nativeOrder se utiliza a continuación para definir el orden de los bytes en la plataforma nativa subyacente. Utilice el método asFloatBuffer para convertir

ByteBuffer en FloatBuffer. Después de crear el FloatBuffer, llamamos al método put para colocar la matriz flotante en el búfer. Finalmente, llamamos al método

position. para garantizar que se nos lea desde el principio del búfer.

private void inicializeBuffers(){

ByteBuffer buff = ByteBuffer.allocateDirect(vertices.length * 4);

buff.order(ByteOrder.nativeOrder() );

verticesBuffer = buff.asFloatBuffer();

verticesBuffer.put(vértices);

verticesBuffer.position(0);

buff = ByteBuffer.allocateDirect(textureVertices.length * 4);

buff.order(ByteOrder.nativeOrder());

texturaBuffer = buff.asFloatBuffer(); p>

texturaBuffer.put(textureVertices);

texturaBuffer.position(0);

}1234567891011121312345678910111213

Crear sombreador

< Los sombreadores son simplemente programas en C que se ejecutan en cada vértice individual de la GPU. En este tutorial, utilizamos dos tipos de sombreadores: sombreadores de vértices y sombreadores de fragmentos.

Código del sombreador de vértices:

atributo vec4 aPosition

atributo vec2 aTexPosition

variante vec2 vTexPosition

void main() {

gl_Position = aPosition;

vTexPosition = aTexPosition

};12345671234567

Código de sombreado de fragmentos

precisión mediap float;

muestra uniforme2D uTexture

variante vec2 vTexPosition;

void main() {

gl_FragColor = textura2D(uTexture, vTexPosition);

};123456123456

Si conoce OpenGL, este código le resultará familiar; si no, para comprender este código, Puede consultar la documentación de OpenGL. Aquí hay una explicación concisa:

El sombreador de vértices es responsable de dibujar un único vértice. aPosition es una variable vinculada al FloatBuffer que contiene las coordenadas de estos vértices. De manera similar, aTexPosition es una variable vinculada al FloatBuffer que contiene las coordenadas de la textura. gl_Position

es una variable creada en OpenGL que representa la posición de cada vértice. vTexPosition es una variable de matriz cuyo valor se pasa al sombreador de fragmentos.

En este tutorial, el sombreador de fragmentos es responsable de colorear el cuadrado. Toma el color de la textura usando el método textura2D y asigna el color al fragmento usando una variable gl_FragColor creada en OpenGL.

En esta clase, el código del sombreador debe convertirse a String.

Cadena final privada vertexShaderCode =

"atributo vec4 aPosition;" +

"atributo vec2 aTexPosition;" +

"variante vec2 vTexPosition;" +

"void main() {" +

" gl_Position = aPosition;" +

" vTexPosition = aTexPosition;" +

"}";

FragmentShaderCode final privado =

"precisión mediump float;" +

"muestra uniforme2D uTexture;" p> p>

"varying vec2 vTexPosition;" +

"void main() {" +

" gl_FragColor = textura2D(uTexture, vTexPosition);" p>

"}";1234567891011121314151612345678910111213141516

Crear programa

Crea un nuevo método inicializeProgram para crear un programa OpenGL que compila y vincula sombreadores.

Utilice glCreateShader para crear un objeto de sombreado y devolver un puntero en forma de int. Para crear un sombreador de vértices, pásele GL_VERTEX_SHADER. De manera similar, para crear un sombreador de fragmentos, pásele GL_FRAGMENT_SHADER. A continuación, utilice el método

glShaderSource para asociar el código de sombreado correspondiente al sombreador. Utilice glCompileShader para compilar código de sombreado.

Después de compilar el código del sombreador, cree un nuevo programa glCreateProgram Similar a glCreateShader, también devuelve un puntero en forma de int. Llame al método glAttachShader para adjuntar el sombreador al programa. Finalmente, llame a glLinkProgram para vincularlo.

Código:

privado int vertexShader;

privado int fragmentShader;

programa privado int;

privado void inicializeProgram(){

vertexShader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);

GLES20.glShaderSource(vertexShader, vertexShaderCode);

GLES20.glCompileShader( vertexShader);

fragmentShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);

GLES20.glShaderSource(fragmentShader, fragmentShaderCode);

GLES20.glCompileShader(fragmentShader) ;

programa = GLES20.glCreateProgram();

GLES20.glAttachShader(programa, vertexShader);

GLES20.glAttachShader(programa, fragmentShader);

p>

GLES20.glLinkProgram(program);

}1234567891011121314151617181912345678910111213141516171819

Puede encontrar que los métodos OpenGL (comenzando con gl) están todos en la clase GLES20 , lo cual es porque estamos usando OpenGL ES2.0. Si usamos una versión superior, se usarán estas clases: GLES30, GLES31.

Dibuja la forma

Ahora define el método de dibujo para dibujar usando los puntos y el sombreador que definimos anteriormente.

Esto es lo que debe hacer:

1. Utilice el método glBindFramebuffer para crear un objeto framebuffer (FBO)

2. Llame a glUseProgram para crear el programa. , como se mencionó antes

3. Pase GL_BLEND al método glDisable para deshabilitar la mezcla de colores durante el renderizado.

4. Llame a glGetAttribLocation para obtener los identificadores de las variables aPosition y aTexPosition

5. Utilice glVertexAttribPointer para conectar los identificadores de aPosition y aTexPosition a sus respectivos verticesBuffer y TextureBuffer.

6. Utilice el método glBindTexture para vincular la textura (pasada como parámetro al método de dibujo) al sombreador de fragmentos

7 Llame al método glClear para borrar el contenido de GLSurfaceView

. p>

8. Finalmente, use el método glDrawArrays. Dibuje dos triángulos (es decir, cuadrados)

Código:

public void draw(int textura){

GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0 );

GLES20.glUseProgram(programa);

GLES20.glDisable(GLES20.GL_BLEND);

int positionHandle = GLES20.glGetAttribLocation(programa, "aPosition ");

int texturaHandle = GLES20.glGetUniformLocation(programa, "uTexture");

int texturaPositionHandle = GLES20.glGetAttribLocation( programa, "aTexPosition");

GLES20.glVertexAttribPointer(texturePositionHandle, 2, GLES20.GL_FLOAT, false, 0, TextureBuffer);

GLES20.glEnableVertexAttribArray(texturePositionHandle);

GLES20.glActiveTexture(GLES20.GL_TEXTURE0) ;

GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textura);

GLES20.glUniform1i(textureHandle, 0);

GLES20.glVertexAttribPointer(positionHandle, 2, GLES20.GL_FLOAT, false, 0, verticesBuffer);

GLES20.glEnableVertexAttribArray(positionHandle);

GLES20.glClear(GLES20. GL_COLOR_BUFFER_BIT);

GLES20. glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);

}12345678910111213141516171819202122123456789101112131415161718192021. 22

Agregar método de inicialización en el constructor:

Cuadrado público(){

inicializarBuffe

rs();

inicializeProgram();

}12341234

Renderizando planos y texturas OpenGL

Ahora nuestro renderizador no hace nada No, Necesitamos cambiarlo para renderizar el plano que creamos al frente.

Primero, creemos un mapa de bits, agreguemos una foto a la carpeta res/drawable, la llamé forest.jpg y usemos BitmapFactory para convertir la foto en un mapa de bits. Almacena también el tamaño de la foto.

Cambie el constructor de EffectsRenderer de la siguiente manera,

foto de mapa de bits privada;

private int photoWidth, photoHeight;

public EffectsRenderer(Contexto) contexto ){

super();

foto = BitmapFactory.decodeResource(context.getResources(), R.drawable.forest);

photoWidth = foto . getWidth();

fotoHeight = foto.getHeight();

}1234567812345678