/***
 * Wyciąg z książki "Hello, Android!",
 * opublikowanej przez wydawnictwo Helion S.A.
 * Niniejszy kod jest chroniony prawami autorskimi. Nie może zostać wykorzystany do utworzenia 
 * materiałów treningowych, kursów, książek, artykułów, itp. Prosimy o kontakt w razie
 * pojawienia się wątpliwości.
 * Nie gwarantujemy, że niniejszy kod będzie się nadawał do jakiegokolwiek celu. 
 * Więcej informacji można znaleźć na stronie http://www.pragmaticprogrammer.com/titles/eband.
***/

package org.przyklad.opengl;

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.util.Log;

class RendererGL implements GLSurfaceView.Renderer {
    private static final String ZNACZNIK = "RendererGL" ;
    private final Context kontekst;
    
    private final SzescianGL szescian = new SzescianGL();
    
    private long czasStartu;
    private long czasStartuKlatki;
    private long iloscRamek;

    

    RendererGL(Context kontekst) {
        this.kontekst = kontekst;
    }

    public void onSurfaceCreated(GL10 gl, EGLConfig konfig) {
        	  
    boolean PRZESWITUJACY = true;
        	  
        czasStartu = System.currentTimeMillis();
        czasStartuKlatki = czasStartu;
        iloscRamek = 0;
        	  
    // Definiuje oświetlenie
    float oswietlenieDook[] = new float[] { 0.2f, 0.2f, 0.2f, 1 };
    float oswietlenieRozp[] = new float[] { 1, 1, 1, 1 };
    float[] pozSwiatla = new float[] { 1, 1, 1, 1 };
    gl.glEnable(GL10.GL_LIGHTING);
    gl.glEnable(GL10.GL_LIGHT0);
    gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, oswietlenieDook, 0);
    gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, oswietlenieRozp, 0);
    gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, pozSwiatla, 0);
        	  
    // Z jakiego materiału jest wykonany sześcian?
    float matDook[] = new float[] { 1, 1, 1, 1 };
    float matRozp[] = new float[] { 1, 1, 1, 1 };
    gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT,
        matDook, 0);
    gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE,
        matRozp, 0);
        	  
    // Konfiguruje wymagane przez nas opcje środowiska OpenGL
    gl.glEnable(GL10.GL_DEPTH_TEST);
    gl.glDepthFunc(GL10.GL_LEQUAL);
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    	
    // Opcjonalne: wyłącza rozpraszanie (ang. dither) w celu zwiększenia wydajności
    // gl.glDisable(GL10.GL_DITHER);
    	                     	                 
    if (PRZESWITUJACY) {
        gl.glDisable(GL10.GL_DEPTH_TEST);
    	gl.glEnable(GL10.GL_BLEND);
    	gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE);
    }
    	                 
    // Uruchamia obsługę tekstur
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    gl.glEnable(GL10.GL_TEXTURE_2D);

    // Wczytuje teksturę sześcianu z bitmapy
    SzescianGL.wczytajTeksture(gl, kontekst, R.drawable.android);
    }

    public void onSurfaceChanged(GL10 gl, int szerokosc, int wysokosc) {
        // Definiuje ostrosłup widzenia
        gl.glViewport(0, 0, szerokosc, wysokosc);
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        float proporcje = (float) szerokosc / wysokosc;
        GLU.gluPerspective(gl, 45.0f, proporcje, 1, 100f);
    }

    public void onDrawFrame(GL10 gl) {
        // Czyści ekran na czarny kolor
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT
            | GL10.GL_DEPTH_BUFFER_BIT);

        // Pozycjonuje obiekt w taki sposób, abyśmy mogli go widzieć
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
        gl.glTranslatef(0, 0, -3.0f);

        // Tutaj wprowadzamy pozostałe polecenia rysowania...            
                    
        // Ustanawia kąt obrotu w oparciu o czas
        long szacowany = System.currentTimeMillis() - czasStartu;
        gl.glRotatef(szacowany * (30f / 1000f), 0, 1, 0);
        gl.glRotatef(szacowany * (15f / 1000f), 1, 0, 0);
     
        // Rysuje model
        szescian.rysuj(gl);
                    
        // Śledzi ilość rysowanych klatek
        iloscRamek++;
        long szacowanaIloscKlatek = System.currentTimeMillis() - czasStartuKlatki;
        if (szacowanaIloscKlatek> 5 * 1000) { // co 5 sekund
            float fps = (iloscRamek * 1000.0F) / szacowanaIloscKlatek;
            Log.d(ZNACZNIK, "Ilosc klatek na sekunde: " + fps + " (" + iloscRamek
                + " klatek w " + szacowanaIloscKlatek + " ms)" );
            czasStartuKlatki = System.currentTimeMillis();
            iloscRamek = 0;
        }            
    }
}

