IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Composants graphiques Android Discussion :

SurfaceView / TextureView / GLSurfaceView


Sujet :

Composants graphiques Android

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Delphi 10.4
    Inscrit en
    Août 2007
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Delphi 10.4

    Informations forums :
    Inscription : Août 2007
    Messages : 51
    Par défaut SurfaceView / TextureView / GLSurfaceView
    Bonjour,

    je développe une application Android (min 4.4) (JAVA/Android Studio) qui doit "faire défiler" une image panoramique 360° à des vitesse différentes.
    J'ai dans un premier temps réaliser cela avec une SurfaceView + Thread en chargeant une BitMaP dans laquelle se trouve l'image à laquelle j'ai ajouté
    à droite une répétition de la zone de gauche. Ainsi avec un canvas.drawBitmap(bmp, src , dst, opkpaint) et en faisant varier la zone "src" cela fonctionne très bien
    sur certaine plateforme hardware (genre TV box RK3188+MALI400) (FPS : 60 très très stable).

    Par contre sur d'autre hardware notamment sur un RK3288 + MALI T760 (pourtant 50% plus performant sur le papier) cela saccade, et le FPS n'est pas
    stable. Je fais quelques recherche et trouve que TextureView devrait apporter de meilleur performances que SurfaceView sans trop d'adaptation à réaliser.
    En effet cela est légèrement meilleur mais sans être totalement satisfaisant. Dès lors je passe sous OpenGL 3D avec un GLSurfaceView. Cette fois l'adaptation est
    totalement différente et je passé par une texture2D et toutes l'artillerie OpenGl pour juste afficher un BMP ! Le résultat n'est pas meilleur qu'avec TextView....
    quelle déception croyant que c'était LA solution.

    Bref. que me conseillez-vous comme principe de base pour réaliser cette fonction d'affichage BMP sur toute la surface de l'écran.
    Comment par exemple régler le FPS indépendamment de la fréquence d'affichage de base pour par exemple n'être qu'a 30FPS mais stable (pas d'effet saccadé).

    Merci pour vos idées ...

  2. #2
    Membre chevronné Avatar de smartties
    Homme Profil pro
    Dev
    Inscrit en
    Février 2010
    Messages
    222
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Dev

    Informations forums :
    Inscription : Février 2010
    Messages : 222
    Par défaut
    Salut,

    Tu ne dis pas comment tu affiche ton image avec Opengl (d'ailleurs qu'elle est sa résolution ?) donc je présume que si ça saccade c'est que tu dois modifier ta texture, pixel par pixel sur ton CPU à chaque frame (ou à chaque mouvement) puis afficher le résultat ?

    Une solution serait de créer deux triangles (formant un rectangle) sur lesquels tu plaque ta texture en faisant varier les coordonnées UV selon ta vitesse. Pour ce qui est de la répétition, ça se fait dans le fragment shader.
    Si tu utilise cette méthode ça devrait tourner à 60fps partout et ça sera stable.

    Petite astuce pour les un peu plus avancés, si le shader s'applique sur une surface couvrant tout l'écran, une optimisation est d'utiliser un seul triangle, comme expliqué ici : http://www.gdcvault.com/play/1020624...s-with-DirectX chapitre Full screen Triangle.


    Comment par exemple régler le FPS indépendamment de la fréquence d'affichage de base pour par exemple n'être qu'a 30FPS mais stable (pas d'effet saccadé).
    Tu ne le mentionne pas, mais je suppose que tu utilise Java et Opengl ES 1.1 ou 2.0 ? Donc tu dois afficher tes objets avec la méthode OnDrawFrame() ?
    Et ta question peut être reformulé comme ceci : comment gérer la fréquence d'appel à la fonction OnDrawFrame ?

    Une solution serait de mettre un sleep(temps); dans cette fonction OnDrawFrame(), avec la variable temps te permettant d'ajuster le FPS que tu désire.
    Deuxième solution, passer ton context Opengl en mode RENDERMODE_WHEN_DIRTY et utiliser un thread qui appel requestRender(); toutes les 30/1000 ms afin d'avoir ton 30 FPS.
    requestRender() va se charger d'appeler la fonction OnDrawFrame de manière safe.

    Mais bon réduire le nombre d'appel à OnDrawFrame ne va pas enlever "l'effet saccadé"

  3. #3
    Membre averti
    Profil pro
    Delphi 10.4
    Inscrit en
    Août 2007
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Delphi 10.4

    Informations forums :
    Inscription : Août 2007
    Messages : 51
    Par défaut
    Tout d'abord un tout grand merci pour ta réponse ....

    ensuite

    Citation Envoyé par smartties Voir le message
    Salut,

    Tu ne dis pas comment tu affiche ton image avec Opengl (d'ailleurs qu'elle est sa résolution ?) donc je présume que si ça saccade c'est que tu dois modifier ta texture, pixel par pixel sur ton CPU à chaque frame (ou à chaque mouvement) puis afficher le résultat ?

    Une solution serait de créer deux triangles (formant un rectangle) sur lesquels tu plaque ta texture en faisant varier les coordonnées UV selon ta vitesse. Pour ce qui est de la répétition, ça se fait dans le fragment shader.
    Si tu utilise cette méthode ça devrait tourner à 60fps partout et ça sera stable.
    C'est exactement ce que je fais (peut-être pas optimisé car je suis reparti d'exemples n'étant pas familié avec opengl).


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    		optopos = optopos +0.005f ;
    		if (optopos > 0.5F) optopos = 0.0F ;
     
    		uvs[0] = optopos ;
    		uvs[2] = optopos ;
    		uvs[4] = optopos+0.5f ;
    		uvs[6] = optopos+0.5f ;
     
    		ByteBuffer bb = ByteBuffer.allocateDirect(uvs.length * 4);
    		bb.order(ByteOrder.nativeOrder());
    		uvBuffer = bb.asFloatBuffer();
    		uvBuffer.put(uvs);
    		uvBuffer.position(0);
     
    		GLES20.glVertexAttribPointer ( mTexCoordLoc, 2, GLES20.GL_FLOAT,false, 0, uvBuffer);
     
    		// Get handle to shape's transformation matrix
    		int mtrxhandle = GLES20.glGetUniformLocation(riGraphicTools.sp_Image, "uMVPMatrix");
     
    		// Apply the projection and view transformation
    		GLES20.glUniformMatrix4fv(mtrxhandle, 1, false, m, 0);
     
    		// Get handle to textures locations
    		int mSamplerLoc = GLES20.glGetUniformLocation (riGraphicTools.sp_Image, "s_texture" );
     
    		// Set the sampler texture unit to 0, where we have saved the texture.
    		GLES20.glUniform1i ( mSamplerLoc, 0);
     
    		// Draw the triangle
    		GLES20.glDrawElements(GLES20.GL_TRIANGLES, optoindices.length,
    				GLES20.GL_UNSIGNED_SHORT, optodrawListBuffer);
    Tu ne le mentionne pas, mais je suppose que tu utilise Java et Opengl ES 1.1 ou 2.0 ? Donc tu dois afficher tes objets avec la méthode OnDrawFrame() ?
    Et ta question peut être reformulé comme ceci : comment gérer la fréquence d'appel à la fonction OnDrawFrame ?
    ... oui Java et Opengl 2.0

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    // Create an OpenGL ES 2.0 context.
    setEGLContextClientVersion(2);
     
    setRenderer(this);
    // Render the view only when there is a change in the drawing data
    setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    141
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 141
    Par défaut
    Un petit truc sur les Bitmaps, attention de bien vérifier ce que l'on charge...

    Un bitmap xhdpi peut vite exploser si il est upscalé en xxhdpi, d'où des fois des surprises par rapport aux perfs.

Discussions similaires

  1. Rapidité de rafraichissement d'une SurfaceView
    Par Simon MARQUIS dans le forum Composants graphiques
    Réponses: 0
    Dernier message: 06/04/2011, 12h36
  2. Problème conception Animation-list + SurfaceView
    Par freezerhm dans le forum Composants graphiques
    Réponses: 0
    Dernier message: 22/01/2011, 12h27
  3. SurfaceView, comment la rendre transparente ?
    Par dawadam dans le forum Composants graphiques
    Réponses: 0
    Dernier message: 26/12/2010, 12h34
  4. Récupérer les pixels du SurfaceView et les modifier
    Par ToTo13 dans le forum Composants graphiques
    Réponses: 9
    Dernier message: 12/10/2010, 13h54
  5. Probleme de ralentissement a cause d'un spinner et d'un surfaceview
    Par Folkene dans le forum Composants graphiques
    Réponses: 0
    Dernier message: 30/12/2009, 02h10

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo