Autore Topic: Realtà Aumentata e OpenGl  (Letto 1029 volte)

Offline Claudio24

  • Nuovo arrivato
  • *
  • Post: 18
  • Respect: 0
    • Mostra profilo
Realtà Aumentata e OpenGl
« il: 13 Novembre 2011, 16:38:49 CET »
0
Salve a tutti, sto "raffinando", la mia applicazione di realtà aumentata e vorrei inserire dei marcatori, nel mio caso elementi di open gl come dei cubi.
Bene vedendo diversi tutorial sul web in particolare questo

OpenGL ES Tutorial for Android – Part I – Setting up the view | Jayway Team Blog - Sharing Experience

Sono riuscito a far conciliare camera, view che contiene il layout ed elementi opengl, poichè spesso l'applicazione scoppiava all'avvio. Però purtroppo non riesco a visualizzare gli elementi openGl sulla fotocamera.

Dunque vorrei chiedervi se qualcuno gentilmente può indicarmi come risolvere la cosa (dalle conoscenze di informatica grafica ricordo che c'era tipo un fattore Z che indicava la profondità).

Inoltre siccome la mia applicazione fa apparire dei messaggi, ricevuti da un server, sulla fotocamera vorrei una politica con cui far apparire scomparire gli elementi openGl.

Grazie mille per la pazienza e la disponibilità.

Offline Verandi

  • Utente normale
  • ***
  • Post: 378
  • Respect: +75
    • Mostra profilo
  • Sistema operativo:
    Windows 7
Re:Realtà Aumentata e OpenGl
« Risposta #1 il: 13 Novembre 2011, 17:23:45 CET »
0
Ciao!  Premetto potrei aver compreso male, quindi sii paziente.  ;-)
Usi una surfaceView per la fotocamera e una GLSurfaceView per i cubi, entrambe all'interno di un frameLayout? Il "fattore z" viene dato dall'ordine in cui sono inseriti nell'xml di layout.

Se il problema della profondità riguarda i cubi, la coordinata sull'asse z la indichi assieme alle coordinate x e y di ogni vertice. Se non la indichi, viene dato per scontato sia 0.

Per far scomparire i cubi, basta non disegnarli nel frame successivo.   :-)

Offline Claudio24

  • Nuovo arrivato
  • *
  • Post: 18
  • Respect: 0
    • Mostra profilo
Re:Realtà Aumentata e OpenGl
« Risposta #2 il: 13 Novembre 2011, 17:31:56 CET »
0
Esatto io uso una SurfaceView per la camera, una GLSurfaceView per disegnare gli elementi (ho parlato di cubi perchè alla fine userò quelli ma al momento sono dei quadrati) e poi una View sulla quale farò visualizzare le informazioni.

Le aggiungo a frameLayout come hai detto tu e poi faccio setContentView, nell'ordine 1 - camera, 2 - GlSurfaceView, 3 - View. Il tutto in maniera programmatica, perciò senza xml.

Quando però lancio l'applicazione non vedo niente sulla camera a parte gli elementi della View, in parole povere non vedo gli elementi della GlSurfaceView. Quindi ho avanzato l'ipotesi della profondità ma non ne sono sicuro.

Offline Verandi

  • Utente normale
  • ***
  • Post: 378
  • Respect: +75
    • Mostra profilo
  • Sistema operativo:
    Windows 7
Re:Realtà Aumentata e OpenGl
« Risposta #3 il: 13 Novembre 2011, 17:42:27 CET »
0
L'ordine mi pare giusto, anche perché riesci a vedere la camera e la view. Forse c'è qualche errore nel codice dell'openGL. Potresti postarci il codice di tutto quello che fai nel Renderer?   ;-)

EDIT: Rileggendo il tuo post, con "non vedo niente sulla camera a parte la view", intendi che visualizzi comunque ciò che vede la fotocamera e il contenuto della view oppure vedi solo la view ma non ciò che vede la fotocamera?
« Ultima modifica: 13 Novembre 2011, 17:49:22 CET da Verandi »

Offline Claudio24

  • Nuovo arrivato
  • *
  • Post: 18
  • Respect: 0
    • Mostra profilo
Re:Realtà Aumentata e OpenGl
« Risposta #4 il: 13 Novembre 2011, 21:46:40 CET »
0
Si è corretto, vedo tutto tranne gli elementi tranne il renderer. Vedo sia c'ho che inquadra la camera che il contenuto della view cui sono scritte delle cose.

Ti posto il codice, vedo se riesco a farlo bene è la prima volta che lo faccio.

Renderer:

Codice (Java): [Seleziona]
package it.dis.arsensor.ar;

import it.dis.arsensor.ar.opengl.Square;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;

public class ARSensorSquare implements Renderer {
       
        Square square;
        float[] rgba;
       
        public ARSensorSquare(){
                square = new Square();
        }

        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
                // Set the background color to transparent ( rgba ).
//              gl.glClearColor(1, 0, 0, 0);  // OpenGL docs.
               
                gl.glShadeModel(GL10.GL_SMOOTH);
                // Depth buffer setup.
                gl.glClearDepthf(0.0f);
                // Enables depth testing.
                gl.glEnable(GL10.GL_DEPTH_TEST);
                // The type of depth testing to do.
                gl.glDepthFunc(GL10.GL_LEQUAL);
                // Really nice perspective calculations.
                gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
               
                gl.glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
               
               
        }

        /*
         * (non-Javadoc)
         *
         * @see
         * android.opengl.GLSurfaceView.Renderer#onDrawFrame(javax.
         * microedition.khronos.opengles.GL10)
         */

        public void onDrawFrame(GL10 gl) {
               
                gl.glClear(GL10.GL_COLOR_BUFFER_BIT | // OpenGL docs.
                GL10.GL_DEPTH_BUFFER_BIT);
               
                // Replace the current matrix with the identity matrix
                gl.glLoadIdentity();
               
                gl.glTranslatef( 0.0f, 0.0f, -12.5f );
               
                square.draw(gl);

        }

        /*
         * (non-Javadoc)
         *
         * @see
         * android.opengl.GLSurfaceView.Renderer#onSurfaceChanged(javax.
         * microedition.khronos.opengles.GL10, int, int)
         */

        public void onSurfaceChanged(GL10 gl, int width, int height) {
                // Sets the current view port to the new size.
                gl.glViewport(0, 0, width, height);
                // Select the projection matrix
                gl.glMatrixMode(GL10.GL_PROJECTION);
                // Reset the projection matrix
                gl.glLoadIdentity();
                // Calculate the aspect ratio of the window
                GLU.gluPerspective(gl, 45.0f, (float) width / (float) height, 0.1f,
                                100.0f);
                // Select the modelview matrix
                gl.glMatrixMode(GL10.GL_MODELVIEW);
                // Reset the modelview matrix
                gl.glLoadIdentity();
               
        }

}

Square

Codice (Java): [Seleziona]
package it.dis.arsensor.ar.opengl;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.opengles.GL10;

public class Square {
        // Our vertices.
        private float vertices[] = {
                      -1.0f,  1.0f, 0.0f,  // 0, Top Left
                      -1.0f, -1.0f, 0.0f,  // 1, Bottom Left
                       1.0f, -1.0f, 0.0f,  // 2, Bottom Right
                       1.0f,  1.0f, 0.0f,  // 3, Top Right
                };

        // The order we like to connect them.
        private short[] indices = { 0, 1, 2, 0, 2, 3 };

        // Our vertex buffer.
        private FloatBuffer vertexBuffer;

        // Our index buffer.
        private ShortBuffer indexBuffer;

        public Square() {
                // a float is 4 bytes, therefore we multiply the number if
                // vertices with 4.
                ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
                vbb.order(ByteOrder.nativeOrder());
                vertexBuffer = vbb.asFloatBuffer();
                vertexBuffer.put(vertices);
                vertexBuffer.position(0);

                // short is 2 bytes, therefore we multiply the number if
                // vertices with 2.
                ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
                ibb.order(ByteOrder.nativeOrder());
                indexBuffer = ibb.asShortBuffer();
                indexBuffer.put(indices);
                indexBuffer.position(0);
        }

        /**
         * This function draws our square on screen.
         * @param gl
         */

        public void draw(GL10 gl) {
                // Counter-clockwise winding.
                gl.glFrontFace(GL10.GL_CCW); // OpenGL docs
                // Enable face culling.
                gl.glEnable(GL10.GL_CULL_FACE); // OpenGL docs
                // What faces to remove with the face culling.
                gl.glCullFace(GL10.GL_BACK); // OpenGL docs

                // Enabled the vertices buffer for writing and to be used during
                // rendering.
                gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);// OpenGL docs.
                // Specifies the location and data format of an array of vertex
                // coordinates to use when rendering.
                gl.glVertexPointer(3, GL10.GL_FLOAT, 0, // OpenGL docs
                                 vertexBuffer);

                gl.glDrawElements(GL10.GL_TRIANGLES, indices.length,// OpenGL docs
                                  GL10.GL_UNSIGNED_SHORT, indexBuffer);

                // Disable the vertices buffer.
                gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); // OpenGL docs
                // Disable face culling.
                gl.glDisable(GL10.GL_CULL_FACE); // OpenGL docs
        }

}

Offline Verandi

  • Utente normale
  • ***
  • Post: 378
  • Respect: +75
    • Mostra profilo
  • Sistema operativo:
    Windows 7
Re:Realtà Aumentata e OpenGl
« Risposta #5 il: 13 Novembre 2011, 22:27:49 CET »
0
Mi pare sia tutto ok. Per ora, la prima cosa che mi viene in mente, anche se ho i miei dubbi, è che la "telecamera" dell'openGl sia troppo lontana, e quindi il quadrato sia troppo piccolo per essere notato. Proverei a cambiare questo nell'onDraw:
Codice (Java): [Seleziona]
gl.glTranslatef( 0.0f, 0.0f, -2.0f );

Però mi sembra strano che escludendo gl.glClearColor(1, 0, 0, 0) dal codice si riesca a vedere la surfaceView della fotocamera dietro alla GLSurfaceView.

Offline Verandi

  • Utente normale
  • ***
  • Post: 378
  • Respect: +75
    • Mostra profilo
  • Sistema operativo:
    Windows 7
Re:Realtà Aumentata e OpenGl
« Risposta #6 il: 14 Novembre 2011, 09:28:01 CET »
0
Ho testato il codice. Il problema era il test della profondità dei pixel che non veniva mai passato, perché come valore minimo avevi passato 0 (che è il minimo possibile) e come metodo di test avevi scelto la modalità LEQUAL (less equal).  Dovresti modificare il codice così: 
Codice (Java): [Seleziona]
// Depth buffer setup.
                gl.glClearDepthf(1.0f);
                // Enables depth testing.
                gl.glEnable(GL10.GL_DEPTH_TEST);
                // The type of depth testing to do.
                gl.glDepthFunc(GL10.GL_LEQUAL);
  oppure così:
Codice (Java): [Seleziona]
// Depth buffer setup.
                gl.glClearDepthf(0.0f);
                // Enables depth testing.
                gl.glEnable(GL10.GL_DEPTH_TEST);
                // The type of depth testing to do.
                gl.glDepthFunc(GL10.GL_GEQUAL);
 
oppure cancelli tutte e tre le righe, tenendo conto che, quando disegnerai più quadrati, la profondità verra data dall'ordine in cui li disegnerai e non dal valore della coordinata in z.  ;-)

Offline Claudio24

  • Nuovo arrivato
  • *
  • Post: 18
  • Respect: 0
    • Mostra profilo
Re:Realtà Aumentata e OpenGl
« Risposta #7 il: 14 Novembre 2011, 09:35:23 CET »
0
Intanto ti ringrazio, siccome adesso sono al lavoro non ho i tool android. Però stasera ti faccio sicuramente sapere il risultato.

Grazie ancora.

Offline Claudio24

  • Nuovo arrivato
  • *
  • Post: 18
  • Respect: 0
    • Mostra profilo
Re:Realtà Aumentata e OpenGl
« Risposta #8 il: 14 Novembre 2011, 22:02:38 CET »
0
Funziona Grazie Mille ti stimo. Dovrei solo farlo rimpicciolire, devo agire sull'array che contiene i vertici giusto?

Adesso vorrei una politica per far apparire scomparire l'elemento del GLSurfaceView, pensavo anche di premere sullo schermo e far apparire l'oggetto.

Offline Verandi

  • Utente normale
  • ***
  • Post: 378
  • Respect: +75
    • Mostra profilo
  • Sistema operativo:
    Windows 7
Re:Realtà Aumentata e OpenGl
« Risposta #9 il: 15 Novembre 2011, 10:11:56 CET »
0
Per rimpicciolirlo dipende, perché le dimensioni in prospettiva sono relative e bisogna distinguere il caso "rimpicciolire il quadrato" e il caso "vedere il quadrato rimpicciolito".

Il quadrato che hai disegnato ha il lato di 2 unità ed è centrato all'origine degli assi.  Nell'onDraw() richiami il metodo gl.glTranslatef() con il terzo parametro a -12.5f   (posizione sull'asse z), per cui, quando poi richiami il metodo square.draw(), questo viene disegnato con il centro in 0x e 0y, ma a -12.5 unità in profondità, ovvero 12.5 unità verso l'interno dello schermo. Il tuo occhio è a 0x 0y e 0z, quindi appare come se fosse centrato nel tuo campo visivo a 12.5 unità davanti a te.
Dunque, se il tuo quadrato avesse il lato di 4 unità, ma si trovasse a 25 unità di distanza, il risultato visivo sarebbe lo stesso, nonostante le dimensioni "fisiche" del quadrato siano il doppio.

Con queste premesse, scegli tu cosa fare in base a cosa ti servirà nella tua applicazione:
- puoi cambiare le dimensioni "fisiche" agendo sui vertici o usando il metodo  glScalef();
- puoi cambiare le dimensioni "visive" spostandolo nello spazio con il metodo glTranslatef();
- puoi cambiare le dimensioni "visive" lasciandolo nella stessa posizione nello spazio ma allontanando o avvicinando la "telecamera" con il metodo GLU.lookAt();

Per disegnare o meno l'oggetto, secondo me potresti usare una variabile boolean che cambia in base al tocco sullo schermo.
Codice (Java): [Seleziona]
 
               if (drawCube){
                gl.glLoadIdentity()
                gl.glTranslatef( 0.0f, 0.0f, -12.5f );
                square.draw(gl);
                }


Offline Claudio24

  • Nuovo arrivato
  • *
  • Post: 18
  • Respect: 0
    • Mostra profilo
Re:Realtà Aumentata e OpenGl
« Risposta #10 il: 16 Novembre 2011, 21:43:06 CET »
0
Perfetto sono riuscito a fare quasi tutto  :D

L'ultima cosa che vorrei chiederti era come gestire questa cosa del touch ma ho paura di finire off-topic.
Nel frattempo grazie mille per il tuo preziosissimo, per me, contributo.

Buona serata!