实例化了两个类,但只使用了一个

时间:2011-01-14 13:56:53

标签: java opengl jogl

嗨,我正在创建一个水景,并有一个名为drawWater的课程。该类采用等式来改变它的外观。当我尝试创建

drawater water = new drawWater();
drawater water2 = new drawWater();

它们似乎都是使用正确的值创建的,但是当我将它们绘制到屏幕上时,只会显示一个值。两个值都不同。

我不知道我哪里出错了。它似乎不是JOGL问题,而是我设置课程的方式?

谁能看到我哪里出错?

这是主要课程:

package waterAttempt41;

import Common.GLDisplay;

public class Lesson27 {
    public static void main(String[] args) {
        GLDisplay neheGLDisplay = GLDisplay.createGLDisplay("Current water attempt");
        Renderer renderer = new Renderer();
        //InputHandler inputHandler = new InputHandler(renderer, neheGLDisplay);
        neheGLDisplay.addGLEventListener(renderer);
        //neheGLDisplay.addKeyListener(inputHandler);
        neheGLDisplay.start();
    }
}

这是渲染器类:

package waterAttempt41;

import Common.TextureReader;
import java.io.IOException;
import java.util.logging.Logger;

import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;

class Renderer implements GLEventListener {

    private static final Logger logger = Logger.getLogger(Renderer.class.getName());
    drawWater water;
    drawWater water2;
    private int[] textures = new int[3];            // Storage For 3 Textures
    private boolean aDown = false;
    private boolean up = false;
    private GLU glu = new GLU();

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


        try {
            loadGLTextures(drawable);
        } catch (IOException e) {
            logger.info("Exception loading textures or Objects");
            System.out.println("Couldn't load model/Texture");
            throw new RuntimeException(e);
        }


        gl.glEnable(GL.GL_DEPTH_TEST);
        gl.glShadeModel(GL.GL_SMOOTH);
        gl.glLightModeli(GL.GL_LIGHT_MODEL_TWO_SIDE, GL.GL_TRUE);

        gl.glCullFace(GL.GL_BACK);                                  // Set Culling Face To Back Face
        gl.glEnable(GL.GL_CULL_FACE);                               // Enable Culling
        gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);                    // Set Clear Color (Greenish Color)

        float spot_ambient[] = {0.2f, 0.2f, 0.2f, 1.0f};
        float spot_diffuse[] = {10.2f, 10.2f, 10.2f, 10.0f};
        float spot_specular[] = {10.2f, 10.2f, 10.2f, 10.0f};

        gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, spot_ambient, 1);
        gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, spot_diffuse, 1);
        gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, spot_specular, 1);

        gl.glEnable(GL.GL_LIGHTING);
        gl.glEnable(GL.GL_LIGHT0);

        water = new drawWater();
        water.setup(gl, "a*sin( y *(x-b) )");
        water.setFuncVar('a', 1.103);
        water.setFuncVar('b', 1.103);
        water.setMax(5);

        water2 = new drawWater();
        water2.setup(gl, "a*sin( y *(x-b) )");
        water2.setFuncVar('a', 0.05);
        water2.setFuncVar('b', 10.0);
        water2.setMax(25);

    }

    public void display(GLAutoDrawable drawable) {

        GL gl = drawable.getGL();

        // Clear Color Buffer, Depth Buffer, Stencil Buffer
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_BUFFER_BIT);

        logger.info("\nWater: a = " + water.getFuncVar('a') + "   b =" + water.getFuncVar('b') + "\n"
                + "Water2: a = " + water2.getFuncVar('a') + "   b =" + water2.getFuncVar('b')
                + "\nWater:  = " + water.getEqu() + "   \nWater2 =" + water2.getEqu()
                + "\nWater: max = " + water.getMax() + "  Water2: max = " + water2.getMax());

        gl.glPushMatrix();

        gl.glTranslatef(0.0f, -20.50f, 0.0f);
        gl.glTranslatef(0.0f, 0.0f, -31.0f);

        gl.glRotatef(90, 0.0f, 0.0f, 1.0f);              // Rotate By -yrot On Y Axis
        gl.glRotatef(90, 0.0f, 1.0f, 0.0f);

        water.draw(gl);

        gl.glTranslatef(0.0f, -20.0f, 0.0f);

        water2.draw(gl);

        gl.glPopMatrix();

        gl.glPushMatrix();

        gl.glTranslatef(0.0f, 0.0f, -20.0f);                // Zoom Into The Screen 20 Units
        gl.glEnable(GL.GL_TEXTURE_2D);              // Enable Texture Mapping ( NEW )

        drawRoom(gl);                                       // Draw The Room

        gl.glPopMatrix();

        gl.glFlush();                                       // Flush The OpenGL Pipeline
    }

    private void drawRoom(GL gl) {                        // Draw The Room (Box)
        gl.glBegin(GL.GL_QUADS);                // Begin Drawing Quads

        /*
        // Floor
        gl.glNormal3f(0.0f, 1.0f, 0.0f);      // Normal Pointing Up
        gl.glVertex3f(-20.0f, -20.0f, -40.0f);  // Back Left
        gl.glVertex3f(-20.0f, -20.0f, 40.0f);  // Front Left
        gl.glVertex3f(20.0f, -20.0f, 40.0f);  // Front Right
        gl.glVertex3f(20.0f, -20.0f, -40.0f);  // Back Right

        // Ceiling

        gl.glNormal3f(0.0f, -1.0f, 0.0f);      // Normal Point Down
        gl.glVertex3f(-10.0f, 10.0f, 20.0f);  // Front Left
        gl.glVertex3f(-10.0f, 10.0f, -20.0f);  // Back Left
        gl.glVertex3f(10.0f, 10.0f, -20.0f);  // Back Right
        gl.glVertex3f(10.0f, 10.0f, 20.0f);  // Front Right

        // Back Wall

        gl.glNormal3f(0.0f, 0.0f, -1.0f);      // Normal Pointing Towards Viewer
        gl.glVertex3f(20.0f, 20.0f, 30.0f);  // Top Right
        gl.glVertex3f(20.0f, -20.0f, 30.0f);  // Bottom Right
        gl.glVertex3f(-20.0f, -20.0f, 30.0f);  // Bottom Left
        gl.glVertex3f(-20.0f, 20.0f, 30.0f);  // Top Left
        // Left Wall
        gl.glNormal3f(1.0f, 0.0f, 0.0f);      // Normal Pointing Right
        gl.glVertex3f(-20.0f, 20.0f, 30.0f);  // Top Front
        gl.glVertex3f(-20.0f, -20.0f, 30.0f);  // Bottom Front
        gl.glVertex3f(-20.0f, -20.0f, -30.0f);  // Bottom Back
        gl.glVertex3f(-20.0f, 20.0f, -30.0f);  // Top Back

        // Right Wall

        gl.glNormal3f(-1.0f, 0.0f, 0.0f);     // Normal Pointing Left
        gl.glVertex3f(20.0f, 20.0f, -30.0f);  // Top Back
        gl.glVertex3f(20.0f, -20.0f, -30.0f);  // Bottom Back
        gl.glVertex3f(20.0f, -20.0f, 30.0f);  // Bottom Front
        gl.glVertex3f(20.0f, 20.0f, 30.0f);  // Top Front
         */

        // Front Wall

        gl.glNormal3f(0.0f, 0.0f, 1.0f);      // Normal Pointing Away From Viewer
        gl.glTexCoord2f(1, 1);
        gl.glVertex3f(-20.0f, 20.0f, -30.0f);  // Top Left
        gl.glTexCoord2f(1, 0);
        gl.glVertex3f(-20.0f, -20.0f, -30.0f);  // Bottom Left
        gl.glTexCoord2f(0, 0);
        gl.glVertex3f(20.0f, -20.0f, -30.0f);  // Bottom Right
        gl.glTexCoord2f(0, 1);
        gl.glVertex3f(20.0f, 20.0f, -30.0f);  // Top Right

        gl.glPopMatrix();

        gl.glEnd();                             // Done Drawing Quads
    }

    public void reshape(GLAutoDrawable drawable, int xstart, int ystart, int width, int height) {
        GL gl = drawable.getGL();

        height = (height == 0) ? 1 : height;

        gl.glViewport(0, 0, width, height);
        gl.glMatrixMode(GL.GL_PROJECTION);

        gl.glLoadIdentity();
        gl.glRotatef(90, 0.0f, 0.0f, 1.0f);
        glu.gluPerspective(60, (float) width / height, 1, 1000);

        glu.gluLookAt(1.0f, 0.0f, 25.0f,
                0.0f, 0.0f, 0.0f,
                0.0f, 0.0f, 1.0f);

        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glLoadIdentity();


    }

    public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
    }

    private void loadGLTextures(GLAutoDrawable gldrawable) throws IOException {
        TextureReader.Texture texture = null;
        texture = TextureReader.readTexture("data/images/042.bmp");

        GL gl = gldrawable.getGL();

        //Create Nearest Filtered Texture
        gl.glGenTextures(1, textures, 0);
        gl.glBindTexture(GL.GL_TEXTURE_2D, textures[0]);

        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);

        gl.glTexImage2D(GL.GL_TEXTURE_2D,
                0,
                3,
                texture.getWidth(),
                texture.getHeight(),
                0,
                GL.GL_RGB,
                GL.GL_UNSIGNED_BYTE,
                texture.getPixels());
    }
}

drawWater Class:

import com.sun.opengl.util.BufferUtil;

import javax.media.opengl.GL;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

/**
 *
 * @author Shane
 */
public class drawWater {

    private Expr2 func;  // The function that is being drawn.
    private String functionInput;
    private boolean version_1_5;  // Check is OpenGL 1.5 is available; set in init().
    private boolean dataIsValid;  // Set to true whenever data needs to be recomputed.
    // This is checked in the display() method before drawing.
    private int max;
    /* Buffers to hold the points and normals for the surface. */
    private FloatBuffer vBuf = BufferUtil.newFloatBuffer(201 * 201 * 3);
    private FloatBuffer nBuf = BufferUtil.newFloatBuffer(201 * 201 * 3);

    /* Buffers to hold the indices for drawing the surface and lines with glDrawElements*/
    private IntBuffer surfaceIndexBuffer = BufferUtil.newIntBuffer(200 * 201 * 2);
    private IntBuffer xLineIndexBuffer = BufferUtil.newIntBuffer(21 * 201);
    private IntBuffer yLineIndexBuffer = BufferUtil.newIntBuffer(21 * 201);

    /* VBO ID numbers for holding the data when OpenGL version is 1.5 or higher */
    private int vertexVBO, normalVBO;            // VBO IDs for surface data.
    private int xLineVBO, yLineVBO, surfaceVBO;  // VBO IDs for index data.

    public drawWater() {
    }

    public void setup(GL gl, String equ) {
        version_1_5 = gl.isExtensionAvailable("GL_VERSION_1_5");

        if (gl.isExtensionAvailable("GL_VERSION_1_3")) {
            gl.glEnable(GL.GL_MULTISAMPLE);
        }

        this.makeElementBuffers();  // Generate lists of indices for glDrawElements.  This data never changes.

        if (version_1_5) {
            // Generate VBOs for the data, and fill the ones that are for index data with
            // data from Java nio buffers.  The VBOs for index data won't change again and
            // so use GL.GL_STATIC_DRAW.
            int[] ids = new int[5];
            gl.glGenBuffers(5, ids, 0);

            this.vertexVBO = ids[0];
            this.normalVBO = ids[1];
            this.xLineVBO = ids[2];
            this.yLineVBO = ids[3];
            this.surfaceVBO = ids[4];

            gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vertexVBO);
            gl.glVertexPointer(3, GL.GL_FLOAT, 0, 0);
            gl.glBindBuffer(GL.GL_ARRAY_BUFFER, normalVBO);
            gl.glNormalPointer(GL.GL_FLOAT, 0, 0);
            gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
            gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, surfaceVBO);
            gl.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, 4 * 2 * 200 * 201, surfaceIndexBuffer, GL.GL_STATIC_DRAW);
            gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, xLineVBO);
            gl.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, 4 * 21 * 201, xLineIndexBuffer, GL.GL_STATIC_DRAW);
            gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, yLineVBO);
            gl.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, 4 * 21 * 201, yLineIndexBuffer, GL.GL_STATIC_DRAW);
            gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0);

        } else {

            gl.glVertexPointer(3, GL.GL_FLOAT, 0, vBuf);
            gl.glNormalPointer(GL.GL_FLOAT, 0, nBuf);

        }

        this.functionInput = equ;
        this.func = new Expr2(equ);

        this.dataIsValid = false;  // Force recomputation of data with new graph definition.

    }

    public void draw(GL gl) {


        if (func != null) {

            gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, new float[]{0.7f, 10.7f, 1}, 0);
            gl.glMaterialfv(GL.GL_BACK, GL.GL_AMBIENT_AND_DIFFUSE, new float[]{10.8f, 0.8f, 0.5f}, 0);

            if (!dataIsValid) {
                this.computeSurfaceData();
                if (version_1_5) {
                    // Set up VBOs for surface points and normals. Since these change
                    // pretty regularly, use GL.GL_DYNAMIC_DRAW.
                    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vertexVBO);
                    gl.glBufferData(GL.GL_ARRAY_BUFFER, 4 * 3 * 201 * 201, vBuf, GL.GL_DYNAMIC_DRAW);
                    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, normalVBO);
                    gl.glBufferData(GL.GL_ARRAY_BUFFER, 4 * 3 * 201 * 201, nBuf, GL.GL_DYNAMIC_DRAW);
                    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
                }
            }
            gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
            gl.glEnableClientState(GL.GL_NORMAL_ARRAY);

            this.drawSurface(gl);  // Just draw the surface.

            gl.glPolygonOffset(1, 1);
            gl.glEnable(GL.GL_POLYGON_OFFSET_FILL);

            this.drawSurface(gl);

            gl.glDisable(GL.GL_POLYGON_OFFSET_FILL);
            gl.glDisable(GL.GL_LIGHTING);
            gl.glColor3f(0, 0, 0);
            gl.glDisableClientState(GL.GL_NORMAL_ARRAY);

            gl.glEnable(GL.GL_LIGHTING);
        }
        gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
        gl.glDisableClientState(GL.GL_NORMAL_ARRAY);


    }

    public void setIsVaild(boolean bool) {
        this.dataIsValid = bool;
    }

    public void setMax(int max) {
        this.max = max;
    }

    public int getMax() {
        return this.max;
    }

    public double getFuncVar(char var) {

        return this.func.getVariable(var);
    }

    public void setFuncVar(char var, double value) {

        this.func.setVariable(var, value);
    }

    public void setFunc(String func) {

        this.func.parse(func);
    }

    public String getEqu() {
        return this.functionInput;
    }

    private void makeElementBuffers() {
        for (int i = 0; i < 201; i += 10) {  // indices for drawing lines in x-direction
            for (int j = 0; j < 201; j++) {
                this.xLineIndexBuffer.put(201 * i + j);
            }
        }
        for (int i = 0; i < 201; i += 10) {  // indices for drawing lines in y-direction
            for (int j = 0; j < 201; j++) {
                this.yLineIndexBuffer.put(201 * j + i);
            }
        }
        for (int i = 0; i < 200; i++) {   // indices for drawing surface with GL_TRIANGLE_STRIPs
            for (int j = 0; j < 201; j++) {
                this.surfaceIndexBuffer.put(201 * (i + 1) + j);
                this.surfaceIndexBuffer.put(201 * i + j);
            }
        }
        this.xLineIndexBuffer.rewind();
        this.yLineIndexBuffer.rewind();
        this.surfaceIndexBuffer.rewind();
    }

    private void computeSurfaceData() {
        double xmin = -5;
        double xmax = 5;
        double ymin = -5;
        double ymax = 5;
        double xRes = 200;
        double yRes = 200;
        float[] surfaceData = new float[301 * 3];
        float[] normalData = new float[301 * 3];
        double dx = (xmax - xmin) / xRes;
        double dy = (ymax - ymin) / yRes;

        for (int i = 0; i <= xRes; i++) {
            int v = 0;
            int n = 0;
            double y1 = ymin + dy * i;

            for (int j = 0; j <= yRes; j++) {
                double x = xmin + dx * j;
                this.func.setVariable('x', x);
                this.func.setVariable('y', y1);
                double z1 = this.func.value();
                float[] normal1 = computeUnitNormal(x, y1);
                surfaceData[v++] = (float) x;
                surfaceData[v++] = (float) y1;
                surfaceData[v++] = (float) z1;
                normalData[n++] = normal1[0];
                normalData[n++] = normal1[1];
                normalData[n++] = normal1[2];
            }
            this.vBuf.put(surfaceData, 0, 201 * 3);
            this.nBuf.put(normalData, 0, 201 * 3);
        }
        this.vBuf.rewind();
        this.nBuf.rewind();
        this.dataIsValid = true;
    }

    /**
     * Draw the surface as a series of triangle strips.
     */
    private void drawSurface(GL gl) {
        if (version_1_5) {
            gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, surfaceVBO);
            for (int i = 0; i < 200; i++) {
                gl.glDrawElements(GL.GL_TRIANGLE_STRIP, 402, GL.GL_UNSIGNED_INT, 402 * i * 4);
            }
            gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0);
        } else {
            for (int i = 0; i < 200; i++) {
                this.surfaceIndexBuffer.position(402 * i);
                gl.glDrawElements(GL.GL_TRIANGLE_STRIP, 402, GL.GL_UNSIGNED_INT, surfaceIndexBuffer);
            }
        }
    }

    /**
     * Compute a unit normal to the graph of z = func(x,y).
     * This is only an approximation, using nearby points instead
     * of exact derivatives.
     */
    private float[] computeUnitNormal(double x, double y) {
        double epsilon = 0.00001;
        this.func.setVariable('x', x);
        this.func.setVariable('y', y);
        double z = this.func.value();
        this.func.setVariable('x', x + epsilon);
        double z1 = func.value();
        this.func.setVariable('x', x);
        this.func.setVariable('y', y + epsilon);
        double z2 = this.func.value();
        // normal is (epsilon,0,z1-z) X (0,epsilon,z2-z)
        double a = -epsilon * (z1 - z);
        double b = -epsilon * (z2 - z);
        double c = epsilon * epsilon;
        double length = Math.sqrt(a * a + b * b + c * c);

        if (Double.isNaN(length) || Double.isInfinite(length)) {
            return new float[]{0, 0, 1};
        } else {
            return new float[]{(float) (a / length), (float) (b / length), (float) (c / length)};
        }

    }
}

任何帮助都会受到赞赏。这是我大学最后一年项目的一部分。所以任何帮助都会很棒。

1 个答案:

答案 0 :(得分:0)

glVertexPointer/glNormalPointer的调用不是每次绘制,而是按照设置完成。

因此,当你创建2个drawWater对象时,最后一个将其顶点和普通数据绑定到GL,所有对glDrawElements的调用都将使用。

你需要修改代码,以便每次绘制glVertexPointer / glNormalPointer(以及伴随它们的glBindBuffer调用)。