2011-01-14 12 views
0

こんにちは私は水面を作り、drawWaterというクラスを持っています。クラスは、その外観を変えるために方程式を取ります。私は2つのクラスがインストールされていますが、1つだけが使用されます

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

を作成しようとする彼らの両方が正しい値で作成されているように見えるが、私は、画面上にそれらを描画するときだけ1が示されています。両方の値が異なっています。

どこが間違っているのか分かりません。それはJOGLの問題ではないようですが、クラスを設定する方法は?

誰かが間違っていた場所を見ることができますか?

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クラス::任意の助けをいただければ幸いです

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

    } 
} 

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

これはレンダラークラスがある:

これはメインのクラスです。これは大学での私の最後の1年間のプロジェクトの一部です。だから、どんな助けも素晴らしいだろう。

+2

いくつかのコメント:(1)クラス名に大文字を使用します(慣例による)。 (2)後壁、前壁、床などを引き出す方法を作る。 (3)デフォルトパッケージ(すなわち、「drawWater」)にクラスを入れないようにする。 (4)アスペクト指向プログラミングを研究する - 特にロギングに関係するように - あまりにも長い時間を要する。 –

+0

あなたのコメントをありがとうDave私はそれらを取る。私をより良くする何か、もう一度ありがとう! – Hallinan13

答えて

0

ドローごとに、セットアップごとにglVertexPointer/glNormalPointerへの呼び出しは行われません。

したがって、2つのdrawWaterオブジェクトを作成すると、最後のオブジェクトはその頂点とGLにバインドされた通常のデータを残します。これにより、glDrawElementsのすべての呼び出しが使用されます。

glVertexPointer/glNormalPointer(描画に伴うglBindBuffer呼び出しとともに)が描画ごとに行われるようにコードを変更する必要があります。

+0

ありがとうございました。 – Hallinan13

+0

これに加えて、レンダリングは非常に遅いです。どんなアイデアをより効率的にするか。 – Hallinan13

関連する問題