⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 renderer.java

📁 NeHe用java与OpenGL结合教程源码
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
package demos.nehe.lesson30;

import demos.common.ResourceRetriever;
import demos.common.TextureReader;
import demos.nehe.lesson30.math.Tuple3d;
import javax.media.opengl.*;
import javax.media.opengl.glu.GLUquadric;
import javax.media.opengl.glu.GLU;

import java.io.IOException;

class Renderer implements GLEventListener {
    private static final float EPSILON = 1e-8f;

    private Tuple3d[] arrayVel = new Tuple3d[10];            //holds velocity of balls
    private Tuple3d[] arrayPos = new Tuple3d[10];            //position of balls
    private Tuple3d[] oldPos = new Tuple3d[10];            //old position of balls
    private Tuple3d veloc = new Tuple3d(.5, -.1, .5);  //initial velocity of balls
    private Tuple3d accel = new Tuple3d(0, -.05, 0);  //acceleration ie. gravity of balls
    private Tuple3d dir = new Tuple3d(0, 0, -10);  //initial direction of camera
    private Tuple3d cameraPosition = new Tuple3d(0, -50, 1000);  //initial position of cameraT
    private boolean increaseCameraZ;
    private boolean decreaseCameraZ;

    private double timeStep = .6;                               //timestep of simulation
    private boolean increaseTimeStep;
    private boolean decreaseTimeStep;

    private float cameraRotation = 0;                           //holds rotation around the Y axis
    private boolean increaseCameraRotation;
    private boolean decreaseCameraRotation;

    private float[] spec = {1.0f, 1.0f, 1.0f, 1.0f};      //sets specular highlight of balls
    private float[] posl = {0.0f, 400f, 0.0f, 1.0f};      //position of ligth source
    private float[] amb2 = {0.3f, 0.3f, 0.3f, 1.0f};      //ambient of lightsource
    private float[] amb = {0.2f, 0.2f, 0.2f, 1.0f};      //global ambient

    private int dlist;                       //stores display list
    private int[][] texture = new int[2][2];//stores texture objects
    private int nrOfBalls;                   //sets the number of balls,
    private boolean cameraAttachedToBall = false;            //hook camera on ball, and sound on/off
    private boolean soundsEnabled = true;            //hook camera on ball, and sound on/off

    private Plane pl1,pl2,pl3,pl4,pl5;                  //the 5 planes of the room
    private Cylinder cyl1,cyl2,cyl3;                       //the 2 cylinders of the room
    private Explosion[] explosions = new Explosion[20]; //holds max 20 explosions at once
    private GLUquadric cylinder;                         //Quadratic object to render the cylinders

    private AudioSample audioSample;

    private GLU glu = new GLU();

    public void zoomOut(boolean increase) {
        increaseCameraZ = increase;
    }

    public void zoomIn(boolean decrease) {
        decreaseCameraZ = decrease;
    }

    public void increaseTimeStep(boolean increase) {
        increaseTimeStep = increase;
    }

    public void decreaseTimeStep(boolean decrease) {
        decreaseTimeStep = decrease;
    }

    public boolean isSoundsEnabled() {
        return soundsEnabled;
    }

    public void toggleSounds() {
        this.soundsEnabled = !soundsEnabled;
    }

    public boolean isCameraAttachedToBall() {
        return cameraAttachedToBall;
    }

    public void toggleCameraAttachedToBall() {
        this.cameraAttachedToBall = !cameraAttachedToBall;
        cameraRotation = 0;
    }

    public void increaseCameraRotation(boolean increase) {
        increaseCameraRotation = increase;
    }

    public void decreaseCameraRotation(boolean decrease) {
        decreaseCameraRotation = decrease;
    }

    public void init(GLAutoDrawable drawable) {
        GL gl = drawable.getGL();

        float df[] = {100f};

        gl.glClearDepth(1.0f);                                      // Depth Buffer Setup
        gl.glEnable(GL.GL_DEPTH_TEST);                              // Enables Depth Testing
        gl.glDepthFunc(GL.GL_LEQUAL);                               // The Type Of Depth Testing To Do
        gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST); // Really Nice Perspective Calculations

        gl.glClearColor(0, 0, 0, 0);
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glLoadIdentity();

        gl.glShadeModel(GL.GL_SMOOTH);
        gl.glEnable(GL.GL_CULL_FACE);
        gl.glEnable(GL.GL_DEPTH_TEST);

        gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, spec, 0);
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_SHININESS, df, 0);

        gl.glEnable(GL.GL_LIGHTING);
        gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, posl, 0);
        gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, amb2, 0);
        gl.glEnable(GL.GL_LIGHT0);

        gl.glLightModelfv(GL.GL_LIGHT_MODEL_AMBIENT, amb, 0);
        gl.glEnable(GL.GL_COLOR_MATERIAL);
        gl.glColorMaterial(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE);

        gl.glEnable(GL.GL_BLEND);
        gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE);

        gl.glEnable(GL.GL_TEXTURE_2D);
        loadGLTextures(gl);

        //Construct billboarded explosion primitive as display list
        //4 quads at right angles to each other
        gl.glNewList(dlist = gl.glGenLists(1), GL.GL_COMPILE);
        gl.glBegin(GL.GL_QUADS);
        gl.glRotatef(-45, 0, 1, 0);
        gl.glNormal3f(0, 0, 1);
        gl.glTexCoord2f(0.0f, 0.0f);
        gl.glVertex3f(-50, -40, 0);
        gl.glTexCoord2f(0.0f, 1.0f);
        gl.glVertex3f(50, -40, 0);
        gl.glTexCoord2f(1.0f, 1.0f);
        gl.glVertex3f(50, 40, 0);
        gl.glTexCoord2f(1.0f, 0.0f);
        gl.glVertex3f(-50, 40, 0);
        gl.glNormal3f(0, 0, -1);
        gl.glTexCoord2f(0.0f, 0.0f);
        gl.glVertex3f(-50, 40, 0);
        gl.glTexCoord2f(0.0f, 1.0f);
        gl.glVertex3f(50, 40, 0);
        gl.glTexCoord2f(1.0f, 1.0f);
        gl.glVertex3f(50, -40, 0);
        gl.glTexCoord2f(1.0f, 0.0f);
        gl.glVertex3f(-50, -40, 0);

        gl.glNormal3f(1, 0, 0);
        gl.glTexCoord2f(0.0f, 0.0f);
        gl.glVertex3f(0, -40, 50);
        gl.glTexCoord2f(0.0f, 1.0f);
        gl.glVertex3f(0, -40, -50);
        gl.glTexCoord2f(1.0f, 1.0f);
        gl.glVertex3f(0, 40, -50);
        gl.glTexCoord2f(1.0f, 0.0f);
        gl.glVertex3f(0, 40, 50);
        gl.glNormal3f(-1, 0, 0);
        gl.glTexCoord2f(0.0f, 0.0f);
        gl.glVertex3f(0, 40, 50);
        gl.glTexCoord2f(0.0f, 1.0f);
        gl.glVertex3f(0, 40, -50);
        gl.glTexCoord2f(1.0f, 1.0f);
        gl.glVertex3f(0, -40, -50);
        gl.glTexCoord2f(1.0f, 0.0f);
        gl.glVertex3f(0, -40, 50);
        gl.glEnd();
        gl.glEndList();

        try {
            audioSample = new AudioSample(
                    ResourceRetriever.getResourceAsStream("demos/data/samples/explode.wav")
            );
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        initVars(glu);
    }

    private void loadGLTextures(GL gl) {
        TextureReader.Texture image1 = null;
        TextureReader.Texture image2 = null;
        TextureReader.Texture image3 = null;
        TextureReader.Texture image4 = null;
        try {
            image1 = TextureReader.readTexture("demos/data/images/marble.bmp");
            image2 = TextureReader.readTexture("demos/data/images/spark.bmp");
            image3 = TextureReader.readTexture("demos/data/images/boden.bmp");
            image4 = TextureReader.readTexture("demos/data/images/wand.bmp");
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }

        /* Create Texture	*****************************************/
        gl.glGenTextures(2, texture[0], 0);
        gl.glBindTexture(GL.GL_TEXTURE_2D, texture[0][0]);   /* 2d texture (x and y size)*/

        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); /* scale linearly when image bigger than texture*/
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); /* scale linearly when image smalled than texture*/
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);

        /* 2d texture, level of detail 0 (normal), 3 components (red, green, blue), x size from image, y size from image, */
        /* border 0 (normal), rgb color data, unsigned byte data, and finally the data itself.*/
        gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, 3, image1.getWidth(), image1.getHeight(), 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, image1.getPixels());

        /* Create Texture	******************************************/
        gl.glBindTexture(GL.GL_TEXTURE_2D, texture[0][1]);   /* 2d texture (x and y size)*/

        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); /* scale linearly when image bigger than texture*/
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); /* scale linearly when image smalled than texture*/
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);

        /* 2d texture, level of detail 0 (normal), 3 components (red, green, blue), x size from image, y size from image, */
        /* border 0 (normal), rgb color data, unsigned byte data, and finally the data itself.*/
        gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, 3, image2.getWidth(), image2.getHeight(), 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, image2.getPixels());


        /* Create Texture	********************************************/
        gl.glGenTextures(2, texture[1], 0);
        gl.glBindTexture(GL.GL_TEXTURE_2D, texture[1][0]);   /* 2d texture (x and y size)*/

        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); /* scale linearly when image bigger than texture*/
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); /* scale linearly when image smalled than texture*/
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);

        /* 2d texture, level of detail 0 (normal), 3 components (red, green, blue), x size from image, y size from image, */
        /* border 0 (normal), rgb color data, unsigned byte data, and finally the data itself.*/
        gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, 3, image3.getWidth(), image3.getHeight(), 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, image3.getPixels());

        /* Create Texture	*********************************************/
        gl.glBindTexture(GL.GL_TEXTURE_2D, texture[1][1]);   /* 2d texture (x and y size)*/

        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); /* scale linearly when image bigger than texture*/
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); /* scale linearly when image smalled than texture*/
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);

        /* 2d texture, level of detail 0 (normal), 3 components (red, green, blue), x size from image, y size from image, */
        /* border 0 (normal), rgb color data, unsigned byte data, and finally the data itself.*/
        gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, 3, image4.getWidth(), image4.getHeight(), 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, image4.getPixels());
    }

    private void initVars(GLU glu) {
        //create palnes
        pl1 = new Plane();
        pl1.position = new Tuple3d(0, -300, 0);
        pl1.normal = new Tuple3d(0, 1, 0);

        pl2 = new Plane();
        pl2.position = new Tuple3d(300, 0, 0);
        pl2.normal = new Tuple3d(-1, 0, 0);

        pl3 = new Plane();
        pl3.position = new Tuple3d(-300, 0, 0);
        pl3.normal = new Tuple3d(1, 0, 0);

        pl4 = new Plane();
        pl4.position = new Tuple3d(0, 0, 300);
        pl4.normal = new Tuple3d(0, 0, -1);

        pl5 = new Plane();
        pl5.position = new Tuple3d(0, 0, -300);
        pl5.normal = new Tuple3d(0, 0, 1);

        cyl1 = new Cylinder();
        cyl1.position = new Tuple3d(0, 0, 0);
        cyl1.axis = new Tuple3d(0, 1, 0);
        cyl1.radius = 60 + 20;

        cyl2 = new Cylinder();
        cyl2.position = new Tuple3d(200, -300, 0);
        cyl2.axis = new Tuple3d(0, 0, 1);
        cyl2.radius = 60 + 20;

        cyl3 = new Cylinder();
        cyl3.position = new Tuple3d(-200, 0, 0);
        cyl3.axis = new Tuple3d(0, 1, 1);
        cyl3.axis.normalize();
        cyl3.radius = 30 + 20;

        //create quadratic object to render cylinders
        cylinder = glu.gluNewQuadric();
        glu.gluQuadricTexture(cylinder, true);

        //Set initial positions and velocities of balls
        //also initialize array which holds explosions
        nrOfBalls = 10;
        arrayVel[0] = new Tuple3d(veloc);
        arrayPos[0] = new Tuple3d(199, 180, 10);

        explosions[0] = new Explosion();
        explosions[0].alpha = 0;
        explosions[0].scale = 1;
        arrayVel[1] = new Tuple3d(veloc);
        arrayPos[1] = new Tuple3d(0, 150, 100);

        explosions[1] = new Explosion();
        explosions[1].alpha = 0;
        explosions[1].scale = 1;
        arrayVel[2] = new Tuple3d(veloc);
        arrayPos[2] = new Tuple3d(-100, 180, -100);

        explosions[2] = new Explosion();
        explosions[2].alpha = 0;
        explosions[2].scale = 1;

        for (int i = 3; i < 10; i++) {
            arrayVel[i] = new Tuple3d(veloc);
            arrayPos[i] = new Tuple3d(-500 + i * 75, 300, -500 + i * 50);

            explosions[i] = new Explosion();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -