package classwork;

import javax.media.opengl.*;
import jocode.*;

/**
 * GLART_5_textured_cube.java
 *
 * Map a texture onto a cube, with different parts of the texture
 * mapped to different faces of the cube.
 *
 * Look at renderCube() for plain texture coordinates,
 * Look at renderCubeUVWmapped() for a "skin" approach.
 */
public class GLART_5_textured_cube  extends JOApp {
    private float rotation = 0f;

    // texture handle (a number that refers to an allocated texture)
    int myTextureHandle = 0;

    /**
     * Main function just creates and runs the application.
     */
    public static void main(String args[]) {
    	GLART_5_textured_cube app = new GLART_5_textured_cube();
    	displayWidth = 800;
    	displayHeight = 600;
        app.run();
    }

    /**
     * Initialize OpenGL
     *
     */
    public void setup() {
        // Select the Projection Matrix (controls perspective)
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glLoadIdentity();    // Reset The Projection Matrix

        // Define perspective
        glu.gluPerspective(
            45.0f,        // Field Of View
            (float)getWidth() / (float)getHeight(), // aspect ratio
            0.1f,         // near Z clipping plane
            100.0f);      // far Z clipping plane

        // Select The Modelview Matrix (controls model orientation)
        gl.glMatrixMode(GL.GL_MODELVIEW);

        // enable texturing
        gl.glEnable(GL.GL_TEXTURE_2D);

        // enable depth test
        gl.glEnable(GL.GL_DEPTH_TEST);
        
        // Load the image as RGBA pixels
        JOImage textureImg = new JOImage("images/cube_uvw_map_dice.png");

        // Allocate and configure a texture based on the image
        myTextureHandle = makeTexture(textureImg);
    }

    /**
     * Render the scene.
     */
    public void draw() {
    	rotation += .5f;

        // Clear screen and depth buffer
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

        // Reset the Modelview matrix
        // this resets the coordinate system to center of screen
        gl.glLoadIdentity();

        // Where is the 'eye'
        glu.gluLookAt(
            0f, 0f, 4f,   // eye position
            0f, 0f, 0f,    // target to look at
            0f, 1f, 0f);   // which way is up
        // rotate scene
        gl.glRotatef(rotation, .6f,1,0);

        // "select" our texture
    	gl.glBindTexture(GL.GL_TEXTURE_2D,myTextureHandle);

    	// draw a cube with texture coordinates
        //renderCube();
    	renderCubeUVWmapped();
    }

    /**
     * Render 2 unit cube with texture coordinates.
     * @param o
     */
    public static void renderCube()
    {
        gl.glBegin(GL.GL_QUADS);
        // Front Face
        gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f,  1.0f);	// Bottom Left
        gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f,  1.0f);	// Bottom Right
        gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f( 1.0f,  1.0f,  1.0f);	// Top Right
        gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f(-1.0f,  1.0f,  1.0f);	// Top Left
        // Back Face
        gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, -1.0f);	// Bottom Right
        gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f(-1.0f,  1.0f, -1.0f);	// Top Right
        gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f( 1.0f,  1.0f, -1.0f);	// Top Left
        gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f, -1.0f);	// Bottom Left
        // Top Face
        gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f(-1.0f,  1.0f, -1.0f);	// Top Left
        gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f(-1.0f,  1.0f,  1.0f);	// Bottom Left
        gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f( 1.0f,  1.0f,  1.0f);	// Bottom Right
        gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f( 1.0f,  1.0f, -1.0f);	// Top Right
        // Bottom Face
        gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f(-1.0f, -1.0f, -1.0f);	// Top Right
        gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f( 1.0f, -1.0f, -1.0f);	// Top Left
        gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f,  1.0f);	// Bottom Left
        gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f,  1.0f);	// Bottom Right
        // Right face
        gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f, -1.0f);	// Bottom Right
        gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f( 1.0f,  1.0f, -1.0f);	// Top Right
        gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f( 1.0f,  1.0f,  1.0f);	// Top Left
        gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f,  1.0f);	// Bottom Left
        // Left Face
        gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, -1.0f);	// Bottom Left
        gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f,  1.0f);	// Bottom Right
        gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f(-1.0f,  1.0f,  1.0f);	// Top Right
        gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f(-1.0f,  1.0f, -1.0f);	// Top Left
        gl.glEnd();
    }

    /**
     * Render 2 unit cube with texture coordinates, mapped to 8 separate faces
     * in texture image.
     *              ___________
     *             |   | T |   |
     *             |___|___|___|
     *             | L | F | R |
     *             |___|___|___|
     *             |   | B | BB|
     *             |___|___|___|
     */
    public static void renderCubeUVWmapped()
    {
        gl.glBegin(GL.GL_QUADS);
        // Left Face
        gl.glTexCoord2f(0.0f, .33f); gl.glVertex3f(-1.0f, -1.0f, -1.0f);	// Bottom Left
        gl.glTexCoord2f(.33f, .33f); gl.glVertex3f(-1.0f, -1.0f,  1.0f);	// Bottom Right
        gl.glTexCoord2f(.33f, .66f); gl.glVertex3f(-1.0f,  1.0f,  1.0f);	// Top Right
        gl.glTexCoord2f(0.0f, .66f); gl.glVertex3f(-1.0f,  1.0f, -1.0f);	// Top Left
        // Front Face
        gl.glTexCoord2f(.33f, .33f); gl.glVertex3f(-1.0f, -1.0f,  1.0f);	// Bottom Left
        gl.glTexCoord2f(.66f, .33f); gl.glVertex3f( 1.0f, -1.0f,  1.0f);	// Bottom Right
        gl.glTexCoord2f(.66f, .66f); gl.glVertex3f( 1.0f,  1.0f,  1.0f);	// Top Right
        gl.glTexCoord2f(.33f, .66f); gl.glVertex3f(-1.0f,  1.0f,  1.0f);	// Top Left
        // Right face
        gl.glTexCoord2f(.66f, .33f); gl.glVertex3f( 1.0f, -1.0f,  1.0f);	// Bottom Left
        gl.glTexCoord2f(1.0f, .33f); gl.glVertex3f( 1.0f, -1.0f, -1.0f);	// Bottom Right
        gl.glTexCoord2f(1.0f, .66f); gl.glVertex3f( 1.0f,  1.0f, -1.0f);	// Top Right
        gl.glTexCoord2f(.66f, .66f); gl.glVertex3f( 1.0f,  1.0f,  1.0f);	// Top Left
        // Top Face
        gl.glTexCoord2f(.33f, .66f); gl.glVertex3f(-1.0f,  1.0f,  1.0f);	// Bottom Left
        gl.glTexCoord2f(.66f, .66f); gl.glVertex3f( 1.0f,  1.0f,  1.0f);	// Bottom Right
        gl.glTexCoord2f(.66f, 1.0f); gl.glVertex3f( 1.0f,  1.0f, -1.0f);	// Top Right
        gl.glTexCoord2f(.33f, 1.0f); gl.glVertex3f(-1.0f,  1.0f, -1.0f);	// Top Left
        // Bottom Face
        gl.glTexCoord2f(.66f, .33f); gl.glVertex3f( 1.0f, -1.0f,  1.0f);	// Bottom Left
        gl.glTexCoord2f(.33f, .33f); gl.glVertex3f(-1.0f, -1.0f,  1.0f);	// Bottom Right
        gl.glTexCoord2f(.33f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, -1.0f);	// Top Right
        gl.glTexCoord2f(.66f, 0.0f); gl.glVertex3f( 1.0f, -1.0f, -1.0f);	// Top Left
        // Back Face
        gl.glTexCoord2f(.66f, 0.0f); gl.glVertex3f( 1.0f, -1.0f, -1.0f);	// Bottom Left
        gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, -1.0f);	// Bottom Right
        gl.glTexCoord2f(1.0f, .33f); gl.glVertex3f(-1.0f,  1.0f, -1.0f);	// Top Right
        gl.glTexCoord2f(.66f, .33f); gl.glVertex3f( 1.0f,  1.0f, -1.0f);	// Top Left
        gl.glEnd();
    }

}
