2011-01-14 2 views
0

Je n'ai aucune idée comment je voudrais texturer quelque chose dessiné en utilisant glDrawElements? D'après ce que je comprends, vous devez utiliser glTexCoordPointer? mais je suis toujours vraiment confus.Comment faire pour structurer glDrawElements

Je vais mettre tout le programme ici afin que vous puissiez voir ce que je fais

public class DrawWater { 

    public 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(). 
    public boolean dataIsValid; // Set to true whenever data needs to be recomputed. 
    public double xMax = 5; 
    public double yMax = 5; 
    private int[] textures = new int[3];   // Storage For 3 Textures 
    // This is checked in the display() method before drawing. 
    /* 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) { 

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

    public void draw(GL gl) { 

     version_1_5 = gl.isExtensionAvailable("GL_VERSION_1_5"); 

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

     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.dataIsValid = false; // Force recomputation of data with new graph definition. 

     if (func != null) { 

      gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, new float[]{0.7f, 0.7f, 1}, 0); 
      gl.glMaterialfv(GL.GL_BACK, GL.GL_AMBIENT_AND_DIFFUSE, new float[]{0.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); 


    } 



    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 = -xMax; 
     double xmax = xMax; 
     double ymin = -yMax; 
     double ymax = yMax; 
     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; 
       func.setVariable('x', x); 
       func.setVariable('y', y1); 
       double z1 = 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]; 
      } 
      vBuf.put(surfaceData, 0, 201 * 3); 
      nBuf.put(normalData, 0, 201 * 3); 
     } 
     vBuf.rewind(); 
     nBuf.rewind(); 
     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.glTexCoordPointer(3, GL.GL_TRIANGLE_STRIP, 402, nBuf); 
       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++) { 
       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; 
     func.setVariable('x', x); 
     func.setVariable('y', y); 
     double z = this.func.value(); 
     func.setVariable('x', x + epsilon); 
     double z1 = func.value(); 
     func.setVariable('x', x); 
     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)}; 
     } 

    } 

    private void loadGLTextures(GLAutoDrawable gldrawable) throws IOException { 
     TextureReader.Texture texture = null; 
     texture = TextureReader.readTexture("data/images/04.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()); 
    } 
} 

Toute aide ou des conseils aiderait je suis confus?


Ya c'est le tampon de tableau

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

je peux ajouter tout le programme si vous souhaitez voir?

+0

N'oubliez jamais de spécifier votre version OpenGL cible dans la question. – Kos

Répondre

1

Comme vous l'avez créé (je l'espère) un GL_ARRAY_BUFFER avec vos sommets et définissez avec glVertexPointer, vous devez créer un GL_ARRAY_BUFFER avec vos coordonnées de texture et définir à l'aide glTexCoordPointer. Pourriez-vous copier coller votre appel glVertexPointer?