2010-10-27 11 views
17

Estoy empezando con OpenGL ES 2.0, lo que me gustaría hacer es crear algunos resultados 2D simples. Dada una resolución de 480x800, ¿cómo puedo dibujar una textura de fondo?Cómo dibujar una textura como fondo 2D en OpenGL ES 2.0?

[Mi entorno de desarrollo es Java/Android, por lo ejemplos que se refieren directamente a eso sería mejor, pero otros idiomas estarían bien.]

Respuesta

29

A pesar de que estás en Android, he creado una aplicación para iPhone que muestra hace esto para los marcos de video entrando. Puede descargar el código para esta muestra en here. Tengo un informe sobre esta aplicación, que hace el seguimiento de objetos basado en color usando video en vivo, que puede leer here.

En esta aplicación, saco dos triángulos para generar un rectángulo, entonces la textura que el uso de las siguientes coordenadas:

static const GLfloat squareVertices[] = { 
     -1.0f, -1.0f, 
     1.0f, -1.0f, 
     -1.0f, 1.0f, 
     1.0f, 1.0f, 
    }; 

    static const GLfloat textureVertices[] = { 
     1.0f, 1.0f, 
     1.0f, 0.0f, 
     0.0f, 1.0f, 
     0.0f, 0.0f, 
    }; 

pase a través del cuadro de vídeo como una textura, utilizo un programa sencillo con el siguiente vértice shader:

attribute vec4 position; 
attribute vec4 inputTextureCoordinate; 

varying vec2 textureCoordinate; 

void main() 
{ 
    gl_Position = position; 
    textureCoordinate = inputTextureCoordinate.xy; 
} 

y la siguiente shader fragmento:

varying highp vec2 textureCoordinate; 

uniform sampler2D videoFrame; 

void main() 
{ 
    gl_FragColor = texture2D(videoFrame, textureCoordinate); 
} 

El dibujo es una simple cuestión de utilizar el programa adecuado:

glUseProgram(directDisplayProgram); 

establecer la textura uniforme:

glActiveTexture(GL_TEXTURE0); 
glBindTexture(GL_TEXTURE_2D, videoFrameTexture); 

glUniform1i(uniforms[UNIFORM_VIDEOFRAME], 0); 

establecer los atributos:

glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices); 
glEnableVertexAttribArray(ATTRIB_VERTEX); 
glVertexAttribPointer(ATTRIB_TEXTUREPOSITON, 2, GL_FLOAT, 0, 0, textureVertices); 
glEnableVertexAttribArray(ATTRIB_TEXTUREPOSITON); 

y luego dibujar los triángulos:

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 
+2

Recuerde que debe cambiar el índice de atributos; esto se hace en su programa de muestra, pero no en la publicación. '// Índice de atributo. enum { ATTRIB_VERTEX, ATTRIB_COLOR, ATTRIB_TEXTUREPOSITON, NUM_ATTRIBUTES }; ' – appas

+0

¿Qué quiere decir con eso @dep? – kevlar

+0

su aplicación necesita alguna actualización. Hay algunas funciones obsoletas y se bloqueó en ios 8. Pero me gusta :-) – Karsten

13

En realidad no dibuja un fondo, en su lugar dibuja un rectángulo (o, aún más correctamente: dos triángulos formando un rectángulo) y establece una textura para eso. Esto no es diferente en absoluto de dibujar cualquier otro objeto en la pantalla.

Hay muchos lugares que muestran cómo se hace esto, tal vez incluso hay un proyecto de ejemplo de Android que muestra esto.

La parte difícil es conseguir que se muestre algo delante o detrás de otra cosa. Para que esto funcione, debe configurar un búfer de profundidad y habilitar la prueba de profundidad (glEnable (GL_DEPTH_TEST)). Y tus vértices necesitan tener una coordenada Z (y decirle a glDrawElements que tus vértices están formados por tres valores, no dos).

Si no hace eso, los objetos se mostrarán en el orden en que se llaman sus funciones glDrawElements() (lo que significa que lo que dibuje último terminará oscureciendo el resto).

Mi consejo es no tener una imagen de fondo o hacer algo elegante hasta que lo domine. OpenGL ES 2.0 tiene una curva de aprendizaje bastante empinada, y los tutoriales de ES 1.x realmente no ayudan a que 3D funcione porque pueden usar funciones de ayuda como gluPerspective, que 2.0 simplemente no tiene. Comience con la creación de un triángulo sobre un fondo de nada. Luego, hazlo un cuadrado. Entonces, si quieres ir de lujo ya, agrega una textura. Juega con las posiciones. Mira lo que sucede cuando cambias el valor Z de tus vértices. (Sugerencia: no mucho, si no tiene habilitada la prueba de profundidad).Y aun así, si no tienes proyección de perspectiva, los objetos no se achicarán cuanto más lejos estén, por lo que todavía parecerá que no pasó nada)

Después de unos días, deja de ser tan malditamente frustrante , y finalmente "lo entiendes", principalmente.