Comment dessiner une texture comme arrière-plan 2D dans OpenGLES 2.0?

je commence à peine avec OpenGL ES 2.0, ce que j'aimerais faire c'est créer une sortie 2D simple. Avec une résolution de 480x800, Comment puis-je dessiner une texture de fond?

[mon environnement de développement est Java / Android, ainsi les exemples directement liés à ce serait mieux, mais d'autres langues seraient très bien.]

17
demandé sur Mark Ingram 2010-10-27 23:07:41

2 réponses

même si vous êtes sur Android, j'ai créé une application d'échantillon d'iPhone qui fait cela pour les cadres de vidéo à venir. Vous pouvez télécharger le code de cet exemple de ici. J'ai un writeup à propos de cette application, qui fait le suivi d'objet couleur en utilisant la vidéo en direct, que vous pouvez lire ici.

dans cette application, je dessine deux triangles pour générer un rectangle, puis la texture qui utilise le suivant coordonnées:

   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,
    };

pour passer à travers le cadre vidéo comme une texture, j'utilise un programme simple avec le vertex shader suivant:

attribute vec4 position;
attribute vec4 inputTextureCoordinate;

varying vec2 textureCoordinate;

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

et le fragment shader:

varying highp vec2 textureCoordinate;

uniform sampler2D videoFrame;

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

le Dessin est une simple question de programme:

glUseProgram(directDisplayProgram);

définition de la texture uniforme:

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

glUniform1i(uniforms[UNIFORM_VIDEOFRAME], 0);   

définir les attributs:

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

puis dessiner les triangles:

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
29
répondu Brad Larson 2010-11-19 17:49:37

vous ne dessinez pas vraiment un fond, vous dessinez plutôt un rectangle (ou, encore plus correctement: deux triangles formant un rectangle) et définissez une texture à cela. Ce n'est pas différent du dessin de tout autre objet sur l'écran.

Il ya beaucoup d'endroits montrant comment cela est fait, peut-être Il ya même un projet d'exemple android montrant cela.

La partie difficile est de trouver quelque chose à afficher devant ou derrière quelque chose d'autre. Pour que cela fonctionne, vous devez définir un tampon de profondeur et de permettre le test de profondeur (glEnable(GL_DEPTH_TEST)). Et vos sommets doivent avoir une coordonnée Z (et dire à glDrawElements que vos sommets sont composés de trois valeurs, Pas de deux).

si vous ne le faites pas, les objets seront rendus dans l'ordre où leurs fonctions glDrawElements() sont appelées (ce qui signifie que celui que vous dessinerez en dernier finira par obscurcir le reste).

mon conseil est de ne pas avoir d'image de fond ou de faire quelque chose de fantaisiste jusqu'à ce que vous obtenez le coup de lui. OpenGL ES 2.0 a une sorte de courbe d'apprentissage raide, et des tutoriels sur ES 1.x n'aide pas vraiment à faire fonctionner la 3D parce qu'ils peuvent utiliser des fonctions d'aide comme gluPerspective, ce que 2.0 n'a tout simplement pas. Commencez par créer un triangle sur un fond de rien. Ensuite, faire une place. Ensuite, si vous voulez déjà devenir fantaisiste, ajoutez une texture. Jouez avec les positions. Voyez ce qui se passe lorsque vous changez la valeur Z de vos sommets. (Indice: Pas beaucoup, si vous n'avez pas de test de profondeur activé. Et même alors,, si vous n'avez pas de projection en perspective, les objets ne seront pas plus petits plus ils seront éloignés, donc il semblera toujours que rien ne s'est passé)

après quelques jours, ça cesse d'être tellement frustrant, et vous finissez par "l'avoir", la plupart du temps.

14
répondu fzwo 2010-12-10 14:57:30