Autore Topic: Creare un programma che mi faccia muovere all'interno di una stanza  (Letto 2998 volte)

Offline ottaviane

  • Nuovo arrivato
  • *
  • Post: 16
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    i9100
  • Sistema operativo:
    CM
Salve a tutti.
Vorrei creare un programmino in Android il quale mi visualizza una stanza con pareti tetto e pavimento.
Io dovrei stare al centro e semplicemente girare e guardare le varie zone della stanza. Poi magari cliccare
su una porta o una porzione ben definita della parete per eseguire del codice.
Qualcuno saprebbe indirizzarmi sulla giusta tecnica da utilizzare?
Ho già provato con il codice NEHE e la lezione 10 fa quasi quello di cui ho bisogno: però non sono
riuscito assolutamente ad applicare ad ogni parete una immagine diversa così da simulare la
mia stanza delle cui mura ho scattato delle foto.
ecco il codice che ho modificato:

Activity principale:
Codice (Java): [Seleziona]
package com.Giovanni01;

import android.app.Activity;
import android.os.Bundle;

/**
 * The initial Android Activity, setting and initiating
 * the OpenGL ES Renderer Class @see Lesson10.java
 *
 * @author Savas Ziplies (nea/INsanityDesign)
 */

public class Run extends Activity {

        /** Our own OpenGL View overridden */
        private InRoomsActivity lesson10;

        /**
         * Initiate our @see Lesson10.java,
         * which is GLSurfaceView and Renderer
         */

        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
               
                //Initiate our Lesson with this Activity Context handed over
                lesson10 = new InRoomsActivity(this);
                //Set the lesson as View to the Activity
                setContentView(lesson10);
        }

        /**
         * Remember to resume our Lesson
         */

        @Override
        protected void onResume() {
                super.onResume();
                lesson10.onResume();
        }

        /**
         * Also pause our Lesson
         */

        @Override
        protected void onPause() {
                super.onPause();
                lesson10.onPause();
        }

}

codice per il controllo touch:
Codice (Java): [Seleziona]
package com.Giovanni01;

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

import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
import android.opengl.GLSurfaceView.Renderer;
import android.view.KeyEvent;
import android.view.MotionEvent;

/**
 * This is a port of the {@link http://nehe.gamedev.net} OpenGL
 * tutorials to the Android 1.5 OpenGL ES platform. Thanks to
 * NeHe and all contributors for their great tutorials and great
 * documentation. This source should be used together with the
 * textual explanations made at {@link http://nehe.gamedev.net}.
 * The code is based on the original Visual C++ code with all
 * comments made. It has been altered and extended to meet the
 * Android requirements. The Java code has according comments.
 *
 * If you use this code or find it helpful, please visit and send
 * a shout to the author under {@link http://www.insanitydesign.com/}
 *
 * @DISCLAIMER
 * This source and the whole package comes without warranty. It may or may
 * not harm your computer or cell phone. Please use with care. Any damage
 * cannot be related back to the author. The source has been tested on a
 * virtual environment and scanned for viruses and has passed all tests.
 *
 *
 * This is an interpretation of "Lesson 10: Loading And Moving Through A 3D World"
 * for the Google Android platform.
 *
 * @author Savas Ziplies (nea/INsanityDesign)
 */

public class InRoomsActivity extends GLSurfaceView implements Renderer
{              
        /** Our World */                               
        private World world;           
        private int filter = 0;                         //Which texture filter?
        /** Is blending enabled */
        private boolean blend = false; 
        /** The Activity Context */
        private Context context;
       
        /**
         * Set this class as renderer for this GLSurfaceView.
         * Request Focus and set if focusable in touch mode to
         * receive the Input from Screen
         *
         * @param context - The Activity Context
         */

        public InRoomsActivity(Context context) {
                super(context);
               
                //Set this as Renderer
                this.setRenderer(this);
                //Request focus
                this.requestFocus();
                this.setFocusableInTouchMode(true);            
                //
                this.context = context;        
                //Instance our World
                world = new World(this.context);               
                //Set the world as listener to this view
                this.setOnKeyListener(world);
                this.setOnTouchListener(world);
        }

        /**
         * The Surface is created/init()
         */

        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
                //Settings
                gl.glDisable(GL10.GL_DITHER);                                           //Disable dithering
                gl.glEnable(GL10.GL_TEXTURE_2D);                                        //Enable Texture Mapping
                gl.glShadeModel(GL10.GL_SMOOTH);                                        //Enable Smooth Shading
                gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);                        //Black Background
                gl.glClearDepthf(1.0f);                                                         //Depth Buffer Setup
                gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE);         //Set The Blending Function For Translucency
                gl.glDepthFunc(GL10.GL_LEQUAL);                                         //The Type Of Depth Testing To Do
                //Really Nice Perspective Calculations
                gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
                //Load our world from the textual description
                world.loadWorld("world.txt");
                //Load the texture for our world once during Surface creation
                world.loadGLTexture(gl, this.context);
        }
       
        /**
         * Here we do our drawing
         */

        public void onDrawFrame(GL10 gl) {
                //Clear Screen And Depth Buffer
                gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);       
                gl.glLoadIdentity();                                    //Reset The Current Modelview Matrix
                //Check if the blend flag has been set to enable/disable blending
                if(blend) {
                        gl.glEnable(GL10.GL_BLEND);                     //Turn Blending On
                        gl.glDisable(GL10.GL_DEPTH_TEST);       //Turn Depth Testing Off
                       
                } else {
                        gl.glDisable(GL10.GL_BLEND);            //Turn Blending Off
                        gl.glEnable(GL10.GL_DEPTH_TEST);        //Turn Depth Testing on
                }              
                //
                world.draw(gl, filter);
        }
               

        /**
         * If the surface changes, reset the view
         */

        public void onSurfaceChanged(GL10 gl, int width, int height) {
                if(height == 0) {                                               //Prevent A Divide By Zero By
                        height = 1;                                             //Making Height Equal One
                }

                gl.glViewport(0, 0, width, height);     //Reset The Current Viewport
                gl.glMatrixMode(GL10.GL_PROJECTION);    //Select The Projection Matrix
                gl.glLoadIdentity();                                    //Reset The Projection Matrix

                //Calculate The Aspect Ratio Of The Window
                GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 0.1f, 100.0f);

                gl.glMatrixMode(GL10.GL_MODELVIEW);     //Select The Modelview Matrix
                gl.glLoadIdentity();                                    //Reset The Modelview Matrix
        }
       
/* ***** Listener Events ***** */      
        /**
         * Override the key listener to receive keyUp events.
         *
         * Check for the DPad presses in the middle.
         * Change the texture filter used through the middle press.
         */

        @Override
        public boolean onKeyUp(int keyCode, KeyEvent event) {
                //Middle pressed
                if(keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
                        filter += 1;
                        if(filter > 2) {
                                filter = 0;
                        }
                       
                        //We handled the event
                        return true;
                }
               
                return false;
        }
       
        /**
         * Override the touch screen listener.
         *
         * React to moves and presses on the touchscreen.
         */

        @Override
        public boolean onTouchEvent(MotionEvent event) {
                //
                float x = event.getX();
        float y = event.getY();
       
        //A press on the screen
        if(event.getAction() == MotionEvent.ACTION_UP) {
                //Define an upper area of 10% to define a lower area
                int upperArea = this.getHeight() / 10;
                int lowerArea = this.getHeight() - upperArea;
               
                //
                if(y > lowerArea) {
                        //Change the blend setting if the lower area left has been pressed
                        if(x < (this.getWidth() / 2)) {
                                if(blend) {
                                        blend = false;
                        } else {
                                blend = true;
                        }
                        }
                }
        }
       
        //
                return true;
        }
}

la classe world
Codice (Java): [Seleziona]
package com.Giovanni01;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;

import com.nea.nehe.lesson10.R;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.view.View.OnTouchListener;

/**
 * This class is our World representation and loads
 * the world from the textual representation, and
 * draws the World according to the read.
 *
 * @author Savas Ziplies (nea/INsanityDesign)
 */

public class World implements OnKeyListener, OnTouchListener
{      
        /** Our texture pointer */
        private int[] textures = new int[8];   
       
        /** The Activity Context */
        private Context context;       
        /** The World sector */
        private Sector sector1;
       
        /*
         * The following values are new values, used
         * to navigate the world and heading
         */

        private final float piover180 = 0.0174532925f;
        private float heading;
        private float xpos;
        private float zpos;
        private float yrot;                                     //Y Rotation
        private float walkbias = 0;
        private float walkbiasangle = 0;
        private float lookupdown = 0.0f;
       
        /* Variables and factor for the input handler */
        private float oldX;
    private float oldY;
        private final float TOUCH_SCALE = 0.2f;                 //Proved to be good for normal rotation
       
        /** The buffer holding the vertices */
        private FloatBuffer vertexBuffer;
        /** The buffer holding the texture coordinates */
        private FloatBuffer textureBuffer;
       
        /** The initial vertex definition */
        private float[] vertices;
        float []_g= new float[100];
        float []_x= new float[100];
        float []_y= new float[100];
        float []_z= new float[100];
       
        /** The texture coordinates (u, v) */  
        private float[] texture;
       
       
        private int numImmagini=0;
        private int [] ids;
       
        /**
         * The World constructor
         *
         * @param context - The Activity Context
         */

        public World(Context context) //costruttore
        {
                this.context = context;
        }
       
        /**
         * This method is a representation of the original SetupWorld().
         * Here, we load the world into the structure from the
         * original world.txt file, but in a Java way.
         *
         * Please note that this is not necessarily the way to got,
         * and definitely not the nicest way to do the reading and
         * loading from a file. But it is near to the original
         * and a quick solution for this example. It does not check
         * for anything NOT part of the original file and can easily
         * be corrupted by a changed file.
         *
         * @param fileName - The file name to load from the Asset directory
         */

        public void loadWorld(String fileName)
        {
                try {
                        //Some temporary variables
                        int numtriangles = 0;
                        int counter = 0;
                        sector1 = new Sector();
                       
                        List<String> lines = null;
                        StringTokenizer tokenizer;
                       
                        //Quick Reader for the input file
                        BufferedReader reader = new BufferedReader(new InputStreamReader(this.context.getAssets().
                                        open(fileName)));
                       
                        //Iterate over all lines
                        String line = null;
                        while((line = reader.readLine()) != null)
                        {
                                //Skip comments and empty lines
                                if(line.startsWith("//") || line.trim().equals(""))
                                {
                                        continue;
                                }                              
                                //Read how many polygons this file contains
                                if(line.startsWith("NUMPOLLIES"))
                                {
                                        numtriangles = Integer.valueOf(line.split(" ")[1]);                                    
                                        sector1.numtriangles = numtriangles;
                                        sector1.triangle = new Triangle[sector1.numtriangles]; 
                                        numImmagini=sector1.numtriangles;
                                //Read every other line
                                }
                                else
                                {
                                        if(lines == null)
                                        {
                                                lines = new ArrayList<String>();
                                        }                                      
                                        lines.add(line);
                                }
                        }                      
                        //Clean up!
                        reader.close();
                       
                        int conta=0;
                       
                        //Now iterate over all read lines...
                        for(int loop = 0; loop < numtriangles; loop++)
                        {
                                //...define triangles...
                                Triangle triangle = new Triangle();                            
                                //...and fill these triangles with the five read data
                                for(int vert = 0; vert < 3; vert++) {
                                        //
                                        line = lines.get(conta++);
                                        tokenizer = new StringTokenizer(line);                                 
                                        //
                                        triangle.vertex[vert] = new Vertex();
                                        //
                                        triangle.vertex[vert].x = Float.valueOf(tokenizer.nextToken());
                                        triangle.vertex[vert].y = Float.valueOf(tokenizer.nextToken());
                                        triangle.vertex[vert].z = Float.valueOf(tokenizer.nextToken());
                                        triangle.vertex[vert].u = Float.valueOf(tokenizer.nextToken());
                                        triangle.vertex[vert].v = Float.valueOf(tokenizer.nextToken());
                                }                              
                                //Finally, add the triangle to the sector
                                sector1.triangle[counter++] = triangle;
                               
                                        line=lines.get(conta++);
                                        tokenizer = new StringTokenizer(line);
                                        float g,x,y,z,zz;
                                        g=Float.valueOf(tokenizer.nextToken());
                                        x=Float.valueOf(tokenizer.nextToken());
                                        y=Float.valueOf(tokenizer.nextToken());
                                        z=Float.valueOf(tokenizer.nextToken());
                                        zz=Float.valueOf(tokenizer.nextToken());
                                       
                                        _g[loop]=g;
                                        _x[loop]=x;
                                        _y[loop]=y;
                                        _z[loop]=z;
                                       
                        }
                       
                //If anything should happen, write a log and return
                }
                catch(Exception e)
                  {
                        Log.e("World", "Could not load the World file!", e);
                        return;
                  }
               
                //
                 // Now, convert the original structure of the NeHe
                 // lesson to our classic buffer structure.
                 // Could/Should be done in one step above. Kept
                 // separated to stick near and clear to the original.
                 //
                 // This is a quick and not recommended solution.
                 // Just made to quickly present the tutorial.
                 //
                vertices = new float[sector1.numtriangles * 3 * 3];
                texture = new float[sector1.numtriangles * 3 * 2];
               
                int vertCounter = 0;
                int texCounter = 0;
                               
                //
                ByteBuffer byteBuf = ByteBuffer.allocateDirect(vertices.length * 4 * numImmagini);
                byteBuf.order(ByteOrder.nativeOrder());
                vertexBuffer = byteBuf.asFloatBuffer();
               
                for(Triangle triangle : sector1.triangle)
                {
                        //
                        for(Vertex vertex : triangle.vertex)
                        {
                                //
                                vertices[vertCounter++] = vertex.x;
                                vertices[vertCounter++] = vertex.y;
                                vertices[vertCounter++] = vertex.z;
                                //
                                texture[texCounter++] = vertex.u;
                                texture[texCounter++] = vertex.v;
                        }
                       
                        vertexBuffer.put(vertices);
                }                              
                vertexBuffer.position(0);
                //
                ByteBuffer byteBuf2 = ByteBuffer.allocateDirect(texture.length * 4 * numImmagini);
                byteBuf2.order(ByteOrder.nativeOrder());
                textureBuffer = byteBuf2.asFloatBuffer();
                for(int n=0;n<numImmagini;n++) textureBuffer.put(texture);
                textureBuffer.position(0);
        }      
       
        public void loadGLTexture(GL10 gl, Context context)
        {
                Bitmap [] bitmap = new Bitmap[numImmagini];
                ids = new int[numImmagini];
                ids[0]=R.drawable.img00;
                ids[1]=R.drawable.img01;
                ids[2]=R.drawable.img02;
                ids[3]=R.drawable.img03;
                ids[4]=R.drawable.img04;
                ids[5]=R.drawable.img05;
                ids[6]=R.drawable.img06;
                ids[7]=R.drawable.img07;
               
                //Get the texture from the Android resource directory
                for(int nn=0;nn<numImmagini;nn++)
                {
                        InputStream is = context.getResources().openRawResource(ids[nn]);
                        try
                                {
                                //BitmapFactory is an Android graphics utility for images
                                bitmap[nn] = BitmapFactory.decodeStream(is);
                                }
                        finally
                        {
                          //Always clear and close
                          try {
                                        is.close();
                                        is = null;
                                  }
                          catch (IOException e) {}
                        }
                }              
                       
                gl.glGenTextures(numImmagini, textures, 0);//Genera i puntatori alle texture           
               
        for (int imm=0;imm<numImmagini;imm++)
        {
                //Create Nearest Filtered Texture and bind it to texture 0
               
                gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[imm]);
                gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);
                gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
                GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap[imm], 0);
               
                if(gl instanceof GL11) {
                        gl.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_GENERATE_MIPMAP, GL11.GL_TRUE);
                        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap[imm], 0);                     
                } else {
                        buildMipmap(gl, bitmap[imm]);
                }                      
                //Clean up
                bitmap[imm].recycle();
        }
        }
        public void draw(GL10 gl, int filter)
        {
                gl.glFrontFace(GL10.GL_CCW);
                //Bind the texture based on the given filter
                //gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[filter]);

                float xtrans = -xpos;                                           //Used For Player Translation On The X Axis
                float ztrans = -zpos;                                           //Used For Player Translation On The Z Axis
                float ytrans = -walkbias - 0.25f;                       //Used For Bouncing Motion Up And Down
                float sceneroty = 360.0f - yrot;                        //360 Degree Angle For Player Direction
               
                //View
                gl.glRotatef(lookupdown, 1.0f, 0, 0);           //Rotate Up And Down To Look Up And Down
                gl.glRotatef(sceneroty, 0, 1.0f, 0);            //Rotate Depending On Direction Player Is Facing
                gl.glTranslatef(xtrans, ytrans, ztrans);        //Translate The Scene Based On Player Position
               
                //Enable the vertex, texture and normal state
                gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
                gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
                //Point to our buffers
                gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
                gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
               
                for(int n=0;n<numImmagini;n++)
                {      
                        gl.glPushMatrix();
                        gl.glRotatef(_g[n],_x[n],_y[n],_z[n]);
                        gl.glTranslatef(0.0f, 0.0f, 1.2f);
                        gl.glBindTexture(GL10.GL_TEXTURE_2D, ids[n]);
                        //Draw the vertices as triangles
                        gl.glDrawArrays(GL10.GL_TRIANGLES, 0, vertices.length / 3);    
                        gl.glPopMatrix();
                }
                //Disable the client state before leaving
                gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
                gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        }
       
       
        /**
         * Our own MipMap generation implementation.
         * Scale the original bitmap down, always by factor two,
         * and set it as new mipmap level.
         *
         * Thanks to Mike Miller (with minor changes)!
         *
         * @param gl - The GL Context
         * @param bitmap - The bitmap to mipmap
         */

        private void buildMipmap(GL10 gl, Bitmap bitmap) {
                //
                int level = 0;
                //
                int height = bitmap.getHeight();
                int width = bitmap.getWidth();

                //
                while(height >= 1 || width >= 1) {
                        //First of all, generate the texture from our bitmap and set it to the according level
                        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, level, bitmap, 0);
                       
                        //
                        if(height == 1 || width == 1) {
                                break;
                        }

                        //Increase the mipmap level
                        level++;

                        //
                        height /= 2;
                        width /= 2;
                        Bitmap bitmap2 = Bitmap.createScaledBitmap(bitmap, width, height, true);
                       
                        //Clean up
                        bitmap.recycle();
                        bitmap = bitmap2;
                }
        }
       
/* ***** Structure classes for the "World" ***** */    
        /**
         * A classic Vertex definition with
         * texture coordinates.
         */

        public class Vertex {
                //
                public float x, y, z;
                //
                public float u, v;
        }
       
        /**
         * The Triangle class, containing
         * all Vertices for the Triangle
         */

        public class Triangle {
                //
                public Vertex[] vertex = new Vertex[3];
        }

        /**
         * The Sector class holding the number and
         * all Triangles.
         */

        public class Sector {
                //
                public int numtriangles;
                //
                public Triangle[] triangle;
        }

       
/* ***** Listener Events ***** */      
        /**
         * Override the key listener to receive onKey events.
         *  
         */

        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
                //Handle key down events
                if(event.getAction() == KeyEvent.ACTION_DOWN) {
                        return onKeyDown(keyCode, event);
                }
               
                return false;
        }
       
        /**
         * Check for the DPad presses left, right, up and down.
         * Walk in the according direction or rotate the "head".
         *
         * @param keyCode - The key code
         * @param event - The key event
         * @return If the event has been handled
         */

        public boolean onKeyDown(int keyCode, KeyEvent event) {
                //
                /*if(keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
                        heading += 1.0f;       
                        yrot = heading;                                 //Rotate The Scene To The Left
                       
                } else if(keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
                        heading -= 1.0f;
                        yrot = heading;                                 //Rotate The Scene To The Right
                       
                } else if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
                        xpos -= (float)Math.sin(heading * piover180) * 0.05f;   //Move On The X-Plane Based On Player Direction
                        zpos -= (float)Math.cos(heading * piover180) * 0.05f;   //Move On The Z-Plane Based On Player Direction
                       
                        if(walkbiasangle >= 359.0f) {                                                   //Is walkbiasangle>=359?
                                walkbiasangle = 0.0f;                                                           //Make walkbiasangle Equal 0
                        } else {
                                walkbiasangle += 10;                                                            //If walkbiasangle < 359 Increase It By 10
                        }
                        walkbias = (float)Math.sin(walkbiasangle * piover180) / 20.0f;  //Causes The Player To Bounce

                } else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
                        xpos += (float)Math.sin(heading * piover180) * 0.05f;   //Move On The X-Plane Based On Player Direction
                        zpos += (float)Math.cos(heading * piover180) * 0.05f;   //Move On The Z-Plane Based On Player Direction
                       
                        if(walkbiasangle <= 1.0f) {                                                             //Is walkbiasangle<=1?
                                walkbiasangle = 359.0f;                                                         //Make walkbiasangle Equal 359
                        } else {
                                walkbiasangle -= 10;                                                            //If walkbiasangle > 1 Decrease It By 10
                        }
                        walkbias = (float)Math.sin(walkbiasangle * piover180) / 20.0f;  //Causes The Player To Bounce
                }*/


                //We handled the event
                return true;
        }

        /**
         * React to moves on the touchscreen.
         */

        @Override
        public boolean onTouch(View v, MotionEvent event) {
                //
                boolean handled = false;
               
                //
                float x = event.getX();
        float y = event.getY();
       
        //CONTROLLO DELLA DIREZIONE DELLO SGUARDO
        if(event.getAction() == MotionEvent.ACTION_MOVE)
      {
                //Calculate the change
                float dx = x - oldX;
                float dy = y - oldY;
                                       
                //Up and down looking through touch
            lookupdown -= dy * TOUCH_SCALE;
            //Look left and right through moving on screen
            heading += dx * TOUCH_SCALE;
            yrot = heading;

            //We handled the event
            handled = true;
        }
       
        //Remember the values
        oldX = x;
        oldY = y;
       
        //
                return handled;
        }
}

il file word.txt
Codice (Java): [Seleziona]
//NUMERO DEI TRIANGOLI
NUMPOLLIES 8

// Floor 1 PAVIMENTO
-3.0  0.0 -3.0 0.0 6.0
-3.0  0.0  3.0 0.0 0.0
 3.0  0.0  3.0 6.0 0.0
270.0 1.0 0.0 0.0  1.1
-3.0  0.0 -3.0 0.0 6.0
 3.0  0.0 -3.0 6.0 6.0
 3.0  0.0  3.0 6.0 0.0
270.0 1.0 0.0 0.0  1.1

// Ceiling 1  TETTO
-3.0  1.0 -3.0 0.0 6.0
-3.0  1.0  3.0 0.0 0.0
 3.0  1.0  3.0 6.0 0.0
90.0 1.0 0.0 0.0  1.1
-3.0  1.0 -3.0 0.0 6.0
 3.0  1.0 -3.0 6.0 6.0
 3.0  1.0  3.0 6.0 0.0
90.0 1.0 0.0 0.0 1.1

// A1 sinistra

-2.0  1.0  -2.0 0.0 1.0
-2.0  0.0  -2.0 0.0 0.0
-0.5  0.0  -2.0 1.5 0.0
270.0 0.0  1.0 0.0  1.1
-2.0  1.0  -2.0 0.0 1.0
-0.5  1.0  -2.0 1.5 1.0
-0.5  0.0  -2.0 1.5 0.0
270.0 0.0  1.0 0.0  1.1

// B1

-2.0  1.0  2.0 2.0  1.0
-2.0  0.0   2.0 2.0 0.0
-0.5  0.0   2.0 0.5 0.0
90.0 0.0 1.0 0.0 1.1
-2.0  1.0  2.0 2.0  1.0
-0.5  1.0  2.0 0.5  1.0
-0.5  0.0   2.0 0.5 0.0
90.0 0.0 1.0 0.0  1.1

qualcuno mi può aiutare o consigliare un metodo migliore e funzionante?
grazie e ciao a tutti.

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:Creare un programma che mi faccia muovere all'interno di una stanza
« Risposta #1 il: 26 Gennaio 2015, 15:22:02 CET »
+1
Nella draw della world prova a sostituire questa riga:
Codice (Java): [Seleziona]
gl.glBindTexture(GL10.GL_TEXTURE_2D, ids[n]);con questa:
Codice (Java): [Seleziona]
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[n]);
 :-)

Offline ottaviane

  • Nuovo arrivato
  • *
  • Post: 16
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    i9100
  • Sistema operativo:
    CM
Re:Creare un programma che mi faccia muovere all'interno di una stanza
« Risposta #2 il: 26 Gennaio 2015, 15:41:38 CET »
0
Nella draw della world prova a sostituire questa riga:
Codice (Java): [Seleziona]
gl.glBindTexture(GL10.GL_TEXTURE_2D, ids[n]);con questa:
Codice (Java): [Seleziona]
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[n]);
 :-)

Grazie mille per il tuo intervento.
fatto... ma è la stessa cosa: c'è tutto al buio.
forse non ho chiaro l'uso delle coordinate: quando creo un quadrato con due triangoli con le seguenti coordinate
nella funzione LoadWorld (tratte dal file world.txt)
-3.0  0.0 -3.0 0.0 6.0
-3.0  0.0  3.0 0.0 0.0
 3.0  0.0  3.0 6.0 0.0

-3.0  0.0 -3.0 0.0 6.0
 3.0  0.0 -3.0 6.0 6.0
 3.0  0.0  3.0 6.0 0.0
poi carico le texture nella funzione LoadTexture
Codice (Java): [Seleziona]
for (int imm=0;imm<numImmagini;imm++)
        {
                //Create Nearest Filtered Texture and bind it to texture 0
               
                gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[imm]);
                gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);
                gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
                GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap[imm], 0);
               
                if(gl instanceof GL11) {
                        gl.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_GENERATE_MIPMAP, GL11.GL_TRUE);
                        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap[imm], 0);                     
                } else {
                        buildMipmap(gl, bitmap[imm]);
                }                      
                //Clean up
                bitmap[imm].recycle();
        }
poi aggiusto le immagini nella funzione Draw
notare la funzione gl.glRotatef(g,x,y,z) dove uso le coordinate   270.0   1.0   0.0   0.0 
e poi         gl.glTranslatef(0.0f, 0.0f, 1.2f);   
Codice (Java): [Seleziona]
for(int n=0;n<numImmagini;n++)
                {      
                        gl.glPushMatrix();
                        gl.glRotatef(_g[n],_x[n],_y[n],_z[n]);
                        gl.glTranslatef(0.0f, 0.0f, 1.2f);
                        gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[n]);
                        //Draw the vertices as triangles
                        gl.glDrawArrays(GL10.GL_TRIANGLES, 0, vertices.length / 3);    
                        gl.glPopMatrix();
                }

forse è qui l'inghippo? Non riesco proprio a capire... sono arrivato e non trovo soluzione. sigh.
« Ultima modifica: 26 Gennaio 2015, 15:44:02 CET da ottaviane »

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:Creare un programma che mi faccia muovere all'interno di una stanza
« Risposta #3 il: 27 Gennaio 2015, 09:11:58 CET »
+1
Questo thread starebbe meglio nella sezione OpenGL  :-)

E' difficile a dirsi però vedo un altro problema.
Tu fai il bind dei vertici e delle coordinate delle texture.
Poi fai un loop 8 volte e fai la draw... ma dici ad OpenGL di disegnare ogni volta tutti i vertici.
Gli dai vertices.length come parametro alla draw... ma appunto questo disegna TUTTO.

Se vedessi qualcosa dovresti vedere tutto il "mondo" disegnato con l'ultima texture caricata.

A parte fixare il problema sopra descritto, se hai lo schermo nero hai altri problemi più urgenti da risolvere.

Solitamente quando ci sono problemi di questo tipo ci sono 3 possibili cause:
1- culling. Prova a disabilitare il backface culling
2- zbuffer. Prova a disabilitare lo z-test
3- posizionamento telecamera. Prova a spostare la telecamera.

Procedi in quest'ordine.

Quando vedi qualcosa a quel punto puoi intervenire (inverti il backface culling, inverti lo z-test, sposti la telecamera).

Se vedi qualcosa è meglio se posti uno screenshot... è più facile aiutarti.  :-)

Offline ottaviane

  • Nuovo arrivato
  • *
  • Post: 16
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    i9100
  • Sistema operativo:
    CM
Re:Creare un programma che mi faccia muovere all\'interno di una stanza
« Risposta #4 il: 27 Gennaio 2015, 09:40:55 CET »
0
Questo thread starebbe meglio nella sezione OpenGL  :-)

E' difficile a dirsi però vedo un altro problema.
Tu fai il bind dei vertici e delle coordinate delle texture.
Poi fai un loop ........ (inverti il backface culling, inverti lo z-test, sposti la telecamera).

Se vedi qualcosa è meglio se posti uno screenshot... è più facile aiutarti.  :-)

Grazie mille per il tuo intervento chiaro ed esaustivo.
Il problema è che non ho ben chiare le idee su come applicare le texture.
Mi sono messo di buona lena e ci sto studiando su.
Nel frattempo mi spieghi come faccio a spostare questo thread nella sezione OpenGL?
ciao e nuovamente grazie.

Post unito: 27 Gennaio 2015, 10:30:36 CET
ok, ho fatto un passo indietro e mi sono accorto da dove nasce il problema.
Il punto è che non riesco a risolverlo.
Mando il codice relativo al seguente programma tratto da qui https://www3.ntu.edu.sg/home/ehchua/programming/android/Android_3D.html
che dovrebbe disegnare un "Foto Cubo" cioè un cubo alle quali facce vi è applicata una serie di sei immagini.
Il punto è che non riesco a farlo funzionare.
Codice (Java): [Seleziona]
package com.nehe06a;

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivityNehe06a extends Activity {
         private GLSurfaceView glView;   // Use GLSurfaceView
         
           // Call back when the activity is started, to initialize the view
           @Override
           protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              glView = new GLSurfaceView(this);           // Allocate a GLSurfaceView
              glView.setRenderer(new MyRendererNehe06a(this)); // Use a custom renderer
              this.setContentView(glView);                // This activity sets to GLSurfaceView
           }
           
           // Call back when the activity is going into the background
           @Override
           protected void onPause() {
              super.onPause();
              glView.onPause();
           }
           
           // Call back after onPause()
           @Override
           protected void onResume() {
              super.onResume();
              glView.onResume();
           }
}

Codice (Java): [Seleziona]
package com.nehe06a;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
/*
 * A photo cube with 6 pictures (textures) on its 6 faces.
 */

public class PhotoCube {
   private FloatBuffer vertexBuffer;  // Vertex Buffer
   private FloatBuffer texBuffer;     // Texture Coords Buffer
   
   private int numFaces = 6;
   private int[] imageFileIDs =
   {  // Image file IDs
                      R.drawable.nehe01,
                      R.drawable.nehe02,
                      R.drawable.nehe03,
                      R.drawable.nehe04,
                      R.drawable.nehe05,
                      R.drawable.nehe06
   };
   private int[] textureIDs = new int[numFaces];
   private Bitmap[] bitmap = new Bitmap[numFaces];
   private float cubeHalfSize = 1.2f;
       
   // Constructor - Set up the vertex buffer
   public PhotoCube(Context context) {
      // Allocate vertex buffer. An float has 4 bytes
      ByteBuffer vbb = ByteBuffer.allocateDirect(12 * 4 * numFaces);
      vbb.order(ByteOrder.nativeOrder());
      vertexBuffer = vbb.asFloatBuffer();
 
      // Read images. Find the aspect ratio and adjust the vertices accordingly.
      for (int face = 0; face < numFaces; face++) {
         bitmap[face] = BitmapFactory.decodeStream(
               context.getResources().openRawResource(imageFileIDs[face]));
         int imgWidth = bitmap[face].getWidth();
         int imgHeight = bitmap[face].getHeight();
         float faceWidth = 2.0f;
         float faceHeight = 2.0f;
         // Adjust for aspect ratio
         if (imgWidth > imgHeight) {
            faceHeight = faceHeight * imgHeight / imgWidth;
         } else {
            faceWidth = faceWidth * imgWidth / imgHeight;
         }
         float faceLeft = -faceWidth / 2;
         float faceRight = -faceLeft;
         float faceTop = faceHeight / 2;
         float faceBottom = -faceTop;
         
         // Define the vertices for this face
         float[] vertices = {
            faceLeft,  faceBottom, 0.0f,  // 0. left-bottom-front
            faceRight, faceBottom, 0.0f,  // 1. right-bottom-front
            faceLeft,  faceTop,    0.0f,  // 2. left-top-front
            faceRight, faceTop,    0.0f,  // 3. right-top-front
         };
         vertexBuffer.put(vertices);  // Populate
      }
      vertexBuffer.position(0);    // Rewind
 
      // Allocate texture buffer. An float has 4 bytes. Repeat for 6 faces.
      float[] texCoords = {
         0.0f, 1.0f,  // A. left-bottom
         1.0f, 1.0f,  // B. right-bottom
         0.0f, 0.0f,  // C. left-top
         1.0f, 0.0f   // D. right-top
      };
      ByteBuffer tbb = ByteBuffer.allocateDirect(texCoords.length * 4 * numFaces);
      tbb.order(ByteOrder.nativeOrder());
      texBuffer = tbb.asFloatBuffer();
      for (int face = 0; face < numFaces; face++) {
         texBuffer.put(texCoords);
      }
      texBuffer.position(0);   // Rewind
   }
   
   // Render the shape
   public void draw(GL10 gl) {
      gl.glFrontFace(GL10.GL_CCW);
     
      gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
      gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
      gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
      gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texBuffer);
 
      // front
      gl.glPushMatrix();
      gl.glTranslatef(0f, 0f, cubeHalfSize);
      gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[0]);
      gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
      gl.glPopMatrix();
 
      // left
      gl.glPushMatrix();
      gl.glRotatef(270.0f, 0f, 1f, 0f);
      gl.glTranslatef(0f, 0f, cubeHalfSize);
      gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[1]);
      gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 4, 4);
      gl.glPopMatrix();
 
      // back
      gl.glPushMatrix();
      gl.glRotatef(180.0f, 0f, 1f, 0f);
      gl.glTranslatef(0f, 0f, cubeHalfSize);
      gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[2]);
      gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 8, 4);
      gl.glPopMatrix();
 
      // right
      gl.glPushMatrix();
      gl.glRotatef(90.0f, 0f, 1f, 0f);
      gl.glTranslatef(0f, 0f, cubeHalfSize);
      gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[3]);
      gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 12, 4);
      gl.glPopMatrix();
 
      // top
      gl.glPushMatrix();
      gl.glRotatef(270.0f, 1f, 0f, 0f);
      gl.glTranslatef(0f, 0f, cubeHalfSize);
      gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[4]);
      gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 16, 4);
      gl.glPopMatrix();
 
      // bottom
      gl.glPushMatrix();
      gl.glRotatef(90.0f, 1f, 0f, 0f);
      gl.glTranslatef(0f, 0f, cubeHalfSize);
      gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[5]);
      gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 20, 4);
      gl.glPopMatrix();
   
      gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
      gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
   }
 
   // Load images into 6 GL textures
   public void loadTexture(GL10 gl) {
      gl.glGenTextures(6, textureIDs, 0); // Generate texture-ID array for 6 IDs
 
      // Generate OpenGL texture images
      for (int face = 0; face < numFaces; face++) {
         gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[face]);
         // Build Texture from loaded bitmap for the currently-bind texture ID
         GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap[face], 0);
         bitmap[face].recycle();
      }
   }
}

Codice (Java): [Seleziona]
package com.nehe06a;

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

import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
   
public class MyRendererNehe06a implements GLSurfaceView.Renderer {
   private PhotoCube cube;     // (NEW)
   private static float angleCube = 0;     // rotational angle in degree for cube
   private static float speedCube = -1.5f; // rotational speed for cube
   
   // Constructor
   public MyRendererNehe06a(Context context)
   {
      cube = new PhotoCube(context);    // (NEW)
   }
   
   // Call back when the surface is first created or re-created.
   @Override
   public void onSurfaceCreated(GL10 gl, EGLConfig config) {
      gl.glClearColor(1.0f, 0.0f, 0.3f, 1.0f);  // Set color's clear-value to black
      gl.glClearDepthf(1.0f);            // Set depth's clear-value to farthest
      gl.glEnable(GL10.GL_DEPTH_TEST);   // Enables depth-buffer for hidden surface removal
      gl.glDepthFunc(GL10.GL_LEQUAL);    // The type of depth testing to do
      gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);  // nice perspective view
      gl.glShadeModel(GL10.GL_SMOOTH);   // Enable smooth shading of color
      gl.glDisable(GL10.GL_DITHER);      // Disable dithering for better performance
   
      // Setup Texture, each time the surface is created (NEW)
      cube.loadTexture(gl);             // Load images into textures (NEW)
      gl.glEnable(GL10.GL_TEXTURE_2D);  // Enable texture (NEW)
   }
   // Call back after onSurfaceCreated() or whenever the window's size changes
   @Override
   public void onSurfaceChanged(GL10 gl, int width, int height) {
      if (height == 0) height = 1;   // To prevent divide by zero
      float aspect = (float)width / height;
   
      // Set the viewport (display area) to cover the entire window
      gl.glViewport(0, 0, width, height);
 
      // Setup perspective projection, with aspect ratio matches viewport
      gl.glMatrixMode(GL10.GL_PROJECTION); // Select projection matrix
      gl.glLoadIdentity();                 // Reset projection matrix
      // Use perspective projection
      GLU.gluPerspective(gl, 45, aspect, 0.1f, 100.f);
 
      gl.glMatrixMode(GL10.GL_MODELVIEW);  // Select model-view matrix
      gl.glLoadIdentity();                 // Reset
 
      // You OpenGL|ES display re-sizing code here
      // ......
   }
   // Call back to draw the current frame.
   @Override
   public void onDrawFrame(GL10 gl) {
      // Clear color and depth buffers
      gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
 
      // ----- Render the Cube -----
      gl.glLoadIdentity();                  // Reset the model-view matrix
      gl.glTranslatef(0.0f, 0.0f, -6.0f);   // Translate into the screen
      gl.glRotatef(angleCube, 0.15f, 1.0f, 0.3f); // Rotate
      cube.draw(gl);
     
      // Update the rotational angle after each refresh.
      angleCube += speedCube;
   }
}

e questo è lo screenshot che mostra il "NON funzionamento del programma".



Se solo funzionasse avrei da dove partire.
grazie e ciao.
« Ultima modifica: 27 Gennaio 2015, 10:30:36 CET da ottaviane, Reason: Merged DoublePost »

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:Creare un programma che mi faccia muovere all'interno di una stanza
« Risposta #5 il: 27 Gennaio 2015, 12:45:23 CET »
+1
Lo Zbuffer sembra ok, così come il culling. Sembra a posto anche il punto di vista.

Che risoluzione hanno le texture?

Offline ottaviane

  • Nuovo arrivato
  • *
  • Post: 16
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    i9100
  • Sistema operativo:
    CM
Re:Creare un programma che mi faccia muovere all'interno di una stanza
« Risposta #6 il: 27 Gennaio 2015, 13:33:35 CET »
0
Lo Zbuffer sembra ok, così come il culling. Sembra a posto anche il punto di vista.

Che risoluzione hanno le texture?

sono immagini png da 256x256 pixel

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:Creare un programma che mi faccia muovere all'interno di una stanza
« Risposta #7 il: 27 Gennaio 2015, 14:01:41 CET »
+1
Nella loadtexture prova a aggiungere dopo il bind:

Codice (Java): [Seleziona]
gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

Offline ottaviane

  • Nuovo arrivato
  • *
  • Post: 16
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    i9100
  • Sistema operativo:
    CM
Re:Creare un programma che mi faccia muovere all'interno di una stanza
« Risposta #8 il: 27 Gennaio 2015, 15:20:33 CET »
0
Nella loadtexture prova a aggiungere dopo il bind:

Codice (Java): [Seleziona]
gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

GRAZIE!
Ho modificato un po' il codice così come segue:
Codice (Java): [Seleziona]
 for (int face = 0; face < numFaces; face++)
      {
         gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[face]);
         gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
             gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
         // Build Texture from loaded bitmap for the currently-bind texture ID
         GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap[face], 0);
         bitmap[face].recycle();
      }

così funziona!

Ora se volessi inserire un altro oggetto, ad esempio un secondo cubo come dovrei comportarmi?
Qual'è la strada giusta? se istanzio un secondo oggetto tipo cubo2 della classe PhotoCube il secondo cubo
si comporta come se fosse un clone del primo infatti la classe gl è in comune.
come dovrei fare?


« Ultima modifica: 27 Gennaio 2015, 15:26:42 CET da ottaviane »

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:Creare un programma che mi faccia muovere all\'interno di una stanza
« Risposta #9 il: 27 Gennaio 2015, 15:38:55 CET »
+1
Il problema banalmente era che non generi le mipmap quindi andavano disabilitate. Dovresti generarle quando carichi le texture e poi commentare le due righe che ho suggerito di aggiungere.  :-)

Post unito: 27 Gennaio 2015, 16:23:26 CET
Il modo più semplice è quello di istanziare un secondo cubo.
A quel punto dopo aver disegnato il primo cubo ricarichi la matrice identità, cambi i valori di traslazione e rotazione così da posizionare il secondo cubo in un altro posto e poi

disegni il secondo cubo.

Puoi anche duplicare la variabile che cambia angolo così li fai muovere a una velocità diversa.
« Ultima modifica: 27 Gennaio 2015, 16:23:26 CET da undead, Reason: Merged DoublePost »

Offline ottaviane

  • Nuovo arrivato
  • *
  • Post: 16
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    i9100
  • Sistema operativo:
    CM
Re:Creare un programma che mi faccia muovere all\'interno di una stanza
« Risposta #10 il: 28 Gennaio 2015, 07:18:47 CET »
0
Il problema banalmente era che non generi le mipmap quindi andavano disabilitate. Dovresti generarle quando carichi le texture e poi commentare le due righe che ho suggerito di aggiungere.  :-)
ok fatto! questa è la nuova parte di codice che funziona!
Codice: [Seleziona]
for (int face = 0; face < numFaces; face++)
      {
         gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[face]);
         //gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
                //gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
         // Build Texture from loaded bitmap for the currently-bind texture ID
                 
         if(gl instanceof GL11)
         {
                         gl.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_GENERATE_MIPMAP, GL11.GL_TRUE);
                         GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap[face], 0);
                  } else {
                         buildMipmap(gl, bitmap[face]);
                   }       
         
         bitmap[face].recycle();
      } 
sei proprio eccezionale. riesci con poche parole a risolvere con precisione chirurgica. sbalorditivo!

adesso dovrei visualizzare nella parte bassa dello schermo delle icone tre o quattro che restino ferme anche se
muovo il cubo. Sapresti indicarmi la giusta via da seguire?
se riusciamo a far funzionare il tutto possiamo fare una piccola guida...che ne dici?

Grazie sempre per la tua disponibilità .
ciao.
« Ultima modifica: 28 Gennaio 2015, 09:17:52 CET da ottaviane »

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:Creare un programma che mi faccia muovere all\'interno di una stanza
« Risposta #11 il: 28 Gennaio 2015, 09:20:09 CET »
+1
Non ho capito... forse perchè non so cosa sono le mipmap! :'(
Come faccio a generarle quando carico le texture? mi puoi fare un esempio?  :D
Le mipmap sono versioni ridotte delle texture. Nella versione più semplice le mipmap sono divise in livelli ottenuti scalando l'immagine per 2 in ogni direzione fino ad arrivare alla risoluzione 1x1. In pratica tu hai caricato una immagine a 256x256 e quello è un livello delle mipmap. Il prossimo sarà 128x128 poi 64x64 poi 32x32 fino all'ultimo livello che è 1x1.

Per generarle, sempre nella versione più semplice, subito dopo aver caricato la texture nella loadtexture devi aggiungere questo comando:

glGenerateMipmap(GL_TEXTURE_2D);

https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGenerateMipmap.xml

A quel punto commenti le due righe che ho inserito e vedrai il cubo.

La domanda è: a cosa servono le mipmap?

Immagina di avere un poligono piccolo che è largo 50 pixel sullo schermo. Tu hai una texture di 256 pixel.
In pratica viene disegnato un pixel ogni 5. Questo genera un effetto "flickering", cioè se la tua texture ha dei dettagli (contrasti di colore, scritte, una scacchiera) questi non solo vengono "persi" perché il poligono è troppo piccolo ma ogni movimento crea un effetto brutto con pixel di colori diversi che saltano fuori. Questo si verifica anche per un poligono grosso che rappresenta un pavimento a scacchi (l'esempio classico). Risulterà perfetto vicino al tuo punto di vista e farà sempre più schifo via via che ti allontani fino ad avere pixel del tutto "casuali" che spuntano fuori. Ma se tu hai una versione della texture a 64x64 o 32x32 o 1x1 riesci invece a mantenere queto dettaglio ed evitare le brutture perché il sistema sceglierà il livello di mipmap corretto.

Immagine classica che mostra in (a) il rendering senza mipmap e in (b) quello con mipmap:




Citazione
Nel mio codice  qual'è la parte che fa ciò? cos'è la matrice identità?
Codice (Java): [Seleziona]
 // ----- Render the Cube -----
      gl.glLoadIdentity();                  // Reset the model-view matrix
      gl.glTranslatef(0.0f, 0.0f, -6.0f);   // Translate into the screen
      gl.glRotatef(angleCube, 0.15f, 1.0f, 0.3f); // Rotate
      cube.draw(gl);
Ogni poligono è fatto da N punti, nel tuo caso 3.
Questo oggetto "esiste" in delle coordinate tridimensionali.
Le matrici servono per applicare le trasformazioni a queste coordinate in modo da passare da coordinate 3d del mondo virtuale a quelle 2d del tuo schermo.
La matrice identità è una matrice che non cambia le coordinate. Diciamo che è la matrice che resetta la trasformazione.
Nel caso semplice che stiamo esaminando con LoadIdentity resetti la matrice.
Poi con Translatef stai spostando il cubo di 6 unità all'indietro.
Poi con Rotatef ruoti il cubo di angleCube (cambia ogni frame) attorno all'asse definito dagli altri parametri (mi sembra sia l'asse, non ricordo).

Quindi dopo aver fatto la draw tu puoi aggiungere un cubo resettando la matrice identità, mettendo altre trasformazioni e così via:

Codice (Java): [Seleziona]
 // ----- Render the Cube -----
      gl.glLoadIdentity();                  // Reset the model-view matrix
      gl.glTranslatef(0.0f, 0.0f, -6.0f);   // Translate into the screen
      gl.glRotatef(angleCube, 0.15f, 1.0f, 0.3f); // Rotate
      cube.draw(gl);
 // ----- Render the second Cube -----
      gl.glLoadIdentity();                  // Reset the model-view matrix
      gl.glTranslatef(1.5f, 1.5f, -6.0f);   // QUI FAI QUALCHE PROVA.. POSIZIONALO DOVE PUOI VEDERLO...
      gl.glRotatef(-angleCube/2.0f, 0.15f, 1.0f, 0.3f); // RUOTA PIU' LENTAMENTE E IN SENSO INVERSO
      cube.draw(gl); // PUOI RIDISEGNARE ANCHE LO STESSO SE VUOI!!

Offline ottaviane

  • Nuovo arrivato
  • *
  • Post: 16
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    i9100
  • Sistema operativo:
    CM
Re:Creare un programma che mi faccia muovere all'interno di una stanza
« Risposta #12 il: 28 Gennaio 2015, 09:33:05 CET »
0

ok fatto! questa è la nuova parte di codice che funziona!
Codice: [Seleziona]
for (int face = 0; face < numFaces; face++)
      {
         gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[face]);
         //gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
                //gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
         // Build Texture from loaded bitmap for the currently-bind texture ID
                 
         if(gl instanceof GL11)
         {
                         gl.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_GENERATE_MIPMAP, GL11.GL_TRUE);
                         GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap[face], 0);
                  } else {
                         buildMipmap(gl, bitmap[face]);
                   }       
         
         bitmap[face].recycle();
      } 
sei proprio eccezionale. riesci con poche parole a risolvere con precisione chirurgica. sbalorditivo!

adesso dovrei visualizzare nella parte bassa dello schermo delle icone tre o quattro che restino ferme anche se
muovo il cubo. Sapresti indicarmi la giusta via da seguire?
se riusciamo a far funzionare il tutto possiamo fare una piccola guida...che ne dici?

Grazie sempre per la tua disponibilità .
ciao.

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:Creare un programma che mi faccia muovere all\'interno di una stanza
« Risposta #13 il: 28 Gennaio 2015, 10:53:10 CET »
+1
adesso dovrei visualizzare nella parte bassa dello schermo delle icone tre o quattro che restino ferme anche se
muovo il cubo. Sapresti indicarmi la giusta via da seguire?
Devi creare un quadrato con due triangoli che sia rivolto verso la telecamera. In pratica devi duplicare una faccia del cubo, quella che ha i due triangoli con la coordinata z costante (una delle due).
Visto che tu stai muovendo gli oggetti ma il punto di vista rimane fisso, dopo aver disegnato il cubo resetti la matrice identità e vai a disegnare questo quadrato nella posizione che preferisci (il cubo si sposta perché cambi angleCube, quindi se posizioni un oggetto senza usare variabili questo sta fermo).

Questa la logica, ma la pratica è un'altra storia: ci sono due problemi.

1- le icone devono stare davanti. Pe garantire che stiano davanti al resto degli oggetti devi disabilitare lo z-buffering. In pratica prima disegni gli oggetti 3d come al solito, poi prima di disegnare le icone disabiliti il test sulla z. Ovviamente lo devi riabilitare prima di ridisegnare i cubi nel prossimo frame. In questo modo le icone staranno sempre davanti a tutto il resto.
2- per trasformare le coordinate tridimensionali sullo schermo e dare l'effetto profondità si utilizza la prospettiva. In pratica data una linea che unisce due punti, questa man mano che si allontana tende a rimpicciolirsi ed avvicinarsi al centro dello schermo (la via di fuga). Oppure pensa a due binari di un treno che via via tendono ad avvicinarsi. Il fatto è che questo effetto prospettiva viene applicato con una matrice "nascosta" detta projection matrix. La matrice che hai manipolato finora è quella che manipola l'oggetto nello spazio tridimensionale, dopo aver spostato l'oggetto OpenGL applica questa matrice di proiezione prospettica. Ma le icone devono essere bidimensionali, non tridimensionali. Quindi prima di disegnare le icone devi impostare una matrice di proiezione che lavori su proiezioni ORTOGONALI. Poi nel frame successivo rimetterai la matrice di proiezione PROSPETTICA prima di disegnare i cubi e così via.

In breve:
- disabilita z buffer
- imposta la matrice di proiezione ortogonale (cerca su Google glortho)

 :-)

Post unito: 28 Gennaio 2015, 14:33:27 CET
Edito perchè c'è un'altra soluzione.
La soluzione è utilizzare la UI di android.

In pratica (credo usando framelayout) puoi creare un layer "normale" sopra alla glsurfaceview.
In quel modo hai il vantaggio di usare tutto quello che è a disposizione su una app normale.

Lo svantaggio è che usi due metodi di rendering completamente diversi e che la gestione del touch può diventare complicata.
In pratica il layer normale ti intercetta i click.
« Ultima modifica: 28 Gennaio 2015, 14:33:27 CET da undead, Reason: Merged DoublePost »

Offline ottaviane

  • Nuovo arrivato
  • *
  • Post: 16
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    i9100
  • Sistema operativo:
    CM
Re:Creare un programma che mi faccia muovere all'interno di una stanza
« Risposta #14 il: 29 Gennaio 2015, 10:42:53 CET »
0
Sempre grazie pre le tue eccezionali dritte.
Adesso mi trovo dentro la stanza e tutto sembra funzionare.
Il problema è che per guardarmi attorno ruoto tutti gli oggetti mediante il codice
Codice: [Seleziona]
public void draw(GL10 gl)
   {
       gl.glFrontFace(GL10.GL_CCW);
           gl.glRotatef(lookupdown, 1f,0f,0f);
           gl.glRotatef(yrot,0f,1f,0f);
      .............
Questo metodo vorrei sostituirlo con il metodo di girare la telecamera.
Ma come si fa? ho letto che si usa la funzione GLUlookAt ma dove dovrei metterla?

Inoltre per il pannellino frontale ho pensato che una volta risolto il problema appena affrontato mi
verrà più facile posizionarlo davanti a me e spostarlo al contrario di come si sposta la telecamera...o mi sbaglio?
ciao