开发者

Two classes instaniated but only one is be used

Hi I'm creating a water scene and have a class called drawWater. The class takes in a equation to alter it's appearance. When I try to create

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

They both seem to be created with the correct values but when I draw them onto the screen only one is shown. Both the values are different.

I don't know where I'm going wrong. It doesn't seem to be a JOGL problem but the way I'm setting up the class?

Can anyone see where I went wrong?

This is the main class:

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();
    }
}

This is the renderer class:

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 Pip开发者_开发技巧eline
    }

    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());
    }
}

The 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)};
        }

    }
}

Any help would be a appreciated. This is part of my final year project in college. So any help would be great.


The calls to glVertexPointer/glNormalPointer are not done per draw, but per setup.

So, when you create the 2 drawWater objects, the last one leaves its vertex and normal data bound to the GL, which all the calls to glDrawElements will use.

You need to modify the code so that glVertexPointer/glNormalPointer (along with the glBindBuffer calls that accompany them) are done per draw.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜