2017-10-06 167 views
1

所以我一直在工作2個晚上,這個代碼是我從老師那裏得到的。我一直在尋找在JOGL上找到一些好的Javadoc,但沒有取得太大的成功。所以我一直在使用try/fail方法來改變這裏和那裏的變量。我學會了如何控制旋轉,距離和大小。所以我讓我有點「太陽系」 - 但是這裏出現了我的問題 - 我如何爲我製作的不同行星實現多個紋理?繼承人我的代碼:需要幫助爲JOGL中的不同對象添加不同的紋理

public class RelativeTransformation implements GLEventListener, KeyListener { 

    // OpenGL window reference 
    private static GLWindow window; 

    // The animator is responsible for continuous operation 
    private static Animator animator; 

    // The program entry point 
    public static void main(String[] args) { 
     new RelativeTransformation().setup(); 
    } 

    // Vertex data 
    private float[] vertexData;  

    // Triangle data 
    private short[] elementData; 

    // Light properties (4 valued vectors due to std140 see OpenGL 4.5 reference) 
    private float[] lightProperties = { 
     // Position 
     2f, 0f, 3f, 0f, 
     // Ambient Color 
     0.2f, 0.2f, 0.2f, 0f, 
     // Diffuse Color 
     0.5f, 0.5f, 0.5f, 0f, 
     // Specular Color 
     1f, 1f, 1f, 0f 
    }; 

    private float[] materialProperties = { 
     // Shininess 
     8f 
    }; 

    // Camera properties 
    private float[] cameraProperties = { 
     0f, 0f, 2f 
    }; 

    // The OpenGL profile 
    GLProfile glProfile; 

    // The texture filename 
    private final String textureFilename = "src/relative_transformation/sun.jpg"; 
    private final String textureFilename2 = "src/relative_transformation/earth.jpg"; 

    // Create buffers for the names 
    private IntBuffer bufferNames = GLBuffers.newDirectIntBuffer(Buffer.MAX); 
    private IntBuffer vertexArrayName = GLBuffers.newDirectIntBuffer(1); 
    private IntBuffer textureNames = GLBuffers.newDirectIntBuffer(1); 

    // Create buffers for clear values 
    private FloatBuffer clearColor = GLBuffers.newDirectFloatBuffer(new float[] {0, 0, 0, 0}); 
    private FloatBuffer clearDepth = GLBuffers.newDirectFloatBuffer(new float[] {1}); 

    // Create references to buffers for holding the matrices 
    private ByteBuffer globalMatricesPointer, modelMatrixPointer1, modelMatrixPointer2, modelMatrixPointer3; 

    // Program instance reference 
    private Program program; 

    // Variable for storing the start time of the application 
    private long start; 


    // Application setup function 
    private void setup() { 

     // Get a OpenGL 4.x profile (x >= 0) 
     glProfile = GLProfile.get(GLProfile.GL4); 

     // Get a structure for definining the OpenGL capabilities with default values 
     GLCapabilities glCapabilities = new GLCapabilities(glProfile); 

     // Create the window with default capabilities 
     window = GLWindow.create(glCapabilities); 

     // Set the title of the window 
     window.setTitle("Relative Transformation"); 

     // Set the size of the window 
     window.setSize(1024, 768); 

     // Set debug context (must be set before the window is set to visible) 
     window.setContextCreationFlags(GLContext.CTX_OPTION_DEBUG); 

     // Make the window visible 
     window.setVisible(true); 

     // Add OpenGL and keyboard event listeners 
     window.addGLEventListener(this); 
     window.addKeyListener(this); 

     // Create and start the animator 
     animator = new Animator(window); 
     animator.start(); 

     // Add window event listener 
     window.addWindowListener(new WindowAdapter() { 
      // Window has been destroyed 
      @Override 
      public void windowDestroyed(WindowEvent e) { 
       // Stop animator and exit 
       animator.stop(); 
       System.exit(1); 
      } 
     }); 
    } 


    // GLEventListener.init implementation 
    @Override 
    public void init(GLAutoDrawable drawable) { 

     // Get OpenGL 4 reference 
     GL4 gl = drawable.getGL().getGL4(); 

     // Initialize debugging 
     initDebug(gl); 

     // Initialize buffers 
     initBuffers(gl); 

     // Initialize vertex array 
     initVertexArray(gl); 

     // Initialize texture 
     initTexture(gl); 

     // Set up the program 
     program = new Program(gl, "relative_transformation", "shader", "shader"); 

     // Enable Opengl depth buffer testing 
     gl.glEnable(GL_DEPTH_TEST); 


     // Store the starting time of the application 
     start = System.currentTimeMillis(); 
    } 

    // GLEventListener.display implementation 
    @Override 
    public void display(GLAutoDrawable drawable) { 

     // Get OpenGL 4 reference 
     GL4 gl = drawable.getGL().getGL4(); 


     // Copy the view matrix to the server 
     { 
      // Create identity matrix 
      float[] view = FloatUtil.makeTranslation(new float[16], 0, false, -cameraProperties[0], -cameraProperties[1], -cameraProperties[2]); 
      // Copy each of the values to the second of the two global matrices 
      for (int i = 0; i < 16; i++) 
       globalMatricesPointer.putFloat(16 * 4 + i * 4, view[i]); 
     } 


     // Clear the color and depth buffers 
     gl.glClearBufferfv(GL_COLOR, 0, clearColor); 
     gl.glClearBufferfv(GL_DEPTH, 0, clearDepth); 

     // Copy the model matrices to the server 
     { 
      // Find a time delta for the time passed since the start of execution 
      long now = System.currentTimeMillis(); 
      float diff = (float) (now - start)/2000; 


      // Create a rotation matrix around the z axis based on the time delta 
      // Lag 2 rotate inni hverandre, relater den 2. til den 1. og sett speed opp! Se Universe.java (model og modelPos?) 
      float[] rotate1  = FloatUtil.makeRotationAxis(new float[16], 0, 00.5f*diff, 0f, 1f, 0f, new float[3]); 
      float[] rotate2  = FloatUtil.makeRotationAxis(new float[16], 0, 01.0f*diff, 0f, 1f, 0f, new float[3]); 
      float[] rotate3  = FloatUtil.makeRotationAxis(new float[16], 0, 15.0f*diff, 0f, 1f, 0f, new float[3]); 

      float[] translate2 = FloatUtil.makeTranslation(new float[16], false, 1.4f, 0f, 0f); 
      float[] translate3 = FloatUtil.makeTranslation(new float[16], false, 0.0f, 0f, 0f); 

      float[] modelPos2 = FloatUtil.multMatrix(rotate1, FloatUtil.multMatrix(rotate2, translate2, new float[16]), new float[16]); 
      float[] model2  = FloatUtil.multMatrix(modelPos2, FloatUtil.makeScale(new float[16], false, 0.1f, 0.1f, 0.1f), new float[16]); 

      float[] modelPos3 = FloatUtil.multMatrix(modelPos2, FloatUtil.multMatrix(rotate3, translate3, new float[16]), new float[16]); 
      float[] model3  = FloatUtil.multMatrix(modelPos3, FloatUtil.makeScale(new float[16], false, 0.5f, 0.5f, 0.5f), new float[16]); 


      // Copy the entire matrix to the server 
      modelMatrixPointer1.asFloatBuffer().put(rotate1); 
      modelMatrixPointer2.asFloatBuffer().put(model2); 
      modelMatrixPointer3.asFloatBuffer().put(model3); 
     } 

     // Activate the vertex program and vertex array 
     gl.glUseProgram(program.name); 
     gl.glBindVertexArray(vertexArrayName.get(0)); 
     gl.glBindTexture(gl.GL_TEXTURE_2D, textureNames.get(0)); 

     // Bind the global matrices buffer to a specified index within the uniform buffers 
     gl.glBindBufferBase(
       GL_UNIFORM_BUFFER, 
       Semantic.Uniform.TRANSFORM0, 
       bufferNames.get(Buffer.GLOBAL_MATRICES)); 

     // Bind the light properties buffer to a specified uniform index 
     gl.glBindBufferBase(
       GL_UNIFORM_BUFFER, 
       Semantic.Uniform.LIGHT0, 
       bufferNames.get(Buffer.LIGHT_PROPERTIES)); 

     // Bind the light properties buffer to a specified uniform index 
     gl.glBindBufferBase(
       GL_UNIFORM_BUFFER, 
       Semantic.Uniform.MATERIAL, 
       bufferNames.get(Buffer.MATERIAL_PROPERTIES)); 

     // Bind the light properties buffer to a specified uniform index 
     gl.glBindBufferBase(
       GL_UNIFORM_BUFFER, 
       Semantic.Uniform.CAMERA, 
       bufferNames.get(Buffer.CAMERA_PROPERTIES)); 

     // Bind the model matrix buffer to a specified index within the uniform buffers 
     gl.glBindBufferBase(
       GL_UNIFORM_BUFFER, 
       Semantic.Uniform.TRANSFORM1, 
       bufferNames.get(Buffer.MODEL_MATRIX1)); 

     // Draw the triangle 
     gl.glDrawElements(
       GL_TRIANGLES, 
       elementData.length, 
       GL_UNSIGNED_SHORT, 
       0); 

     // Bind the model matrix buffer to a specified index within the uniform buffers 
     gl.glBindBufferBase(
       GL_UNIFORM_BUFFER, 
       Semantic.Uniform.TRANSFORM1, 
       bufferNames.get(Buffer.MODEL_MATRIX2)); 

     // Draw the triangle 
     gl.glDrawElements(
       GL_TRIANGLES, 
       elementData.length, 
       GL_UNSIGNED_SHORT, 
       0); 

     // Bind the model matrix buffer to a specified index within the uniform buffers 
     gl.glBindBufferBase(
       GL_UNIFORM_BUFFER, 
       Semantic.Uniform.TRANSFORM1, 
       bufferNames.get(Buffer.MODEL_MATRIX3)); 

     // Draw the triangle 
     gl.glDrawElements(
       GL_TRIANGLES, 
       elementData.length, 
       GL_UNSIGNED_SHORT, 
       0); 

     // Deactivate the program and vertex array 
     gl.glUseProgram(0); 
     gl.glBindVertexArray(0); 
     gl.glBindTexture(gl.GL_TEXTURE_2D, 0); 
    } 

    // GLEventListener.reshape implementation 
    @Override 
    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { 

     // Get OpenGL 4 reference 
     GL4 gl = drawable.getGL().getGL4(); 

     // Create an orthogonal projection matrix 
     float[] ortho = FloatUtil.makePerspective(new float[16], 0, false, (float)Math.PI/2f, (float)width/height, 0.1f, 100f); 

     // Copy the projection matrix to the server 
     globalMatricesPointer.asFloatBuffer().put(ortho); 

     // Set the OpenGL viewport 
     gl.glViewport(x, y, width, height); 
    } 

    // GLEventListener.dispose implementation 
    @Override 
    public void dispose(GLAutoDrawable drawable) { 

     // Get OpenGL 4 reference 
     GL4 gl = drawable.getGL().getGL4(); 

     // Delete the program 
     gl.glDeleteProgram(program.name); 

     // Delete the vertex array 
     gl.glDeleteVertexArrays(1, vertexArrayName); 

     // Delete the buffers 
     gl.glDeleteBuffers(Buffer.MAX, bufferNames); 

     gl.glDeleteTextures(1, textureNames); 
    } 

    // KeyListener.keyPressed implementation 
    @Override 
    public void keyPressed(KeyEvent e) { 
     // Destroy the window if the esape key is pressed 
     if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { 
      new Thread(() -> { 
       window.destroy(); 
      }).start(); 
     } 
    } 

    // KeyListener.keyPressed implementation 
    @Override 
    public void keyReleased(KeyEvent e) { 
    } 

    // Function for initializing OpenGL debugging 
    private void initDebug(GL4 gl) { 

     // Register a new debug listener 
     window.getContext().addGLDebugListener(new GLDebugListener() { 
      // Output any messages to standard out 
      @Override 
      public void messageSent(GLDebugMessage event) { 
       System.out.println(event); 
      } 
     }); 

     // Ignore all messages 
     gl.glDebugMessageControl(
       GL_DONT_CARE, 
       GL_DONT_CARE, 
       GL_DONT_CARE, 
       0, 
       null, 
       false); 

     // Enable messages of high severity 
     gl.glDebugMessageControl(
       GL_DONT_CARE, 
       GL_DONT_CARE, 
       GL_DEBUG_SEVERITY_HIGH, 
       0, 
       null, 
       true); 

     // Enable messages of medium severity 
     gl.glDebugMessageControl(
       GL_DONT_CARE, 
       GL_DONT_CARE, 
       GL_DEBUG_SEVERITY_MEDIUM, 
       0, 
       null, 
       true); 
    } 

    // Function fo initializing OpenGL buffers 
    private void initBuffers(GL4 gl) { 

     // Create a new float direct buffer for the vertex data 
     vertexData = createSphereVertices(0.5f, 16, 16); 
     FloatBuffer vertexBuffer = GLBuffers.newDirectFloatBuffer(vertexData); 

     // Create a new short direct buffer for the triangle indices 
     elementData = createSphereElements(16, 16); 
     ShortBuffer elementBuffer = GLBuffers.newDirectShortBuffer(elementData); 

     // Create a direct buffer for the light properties 
     FloatBuffer lightBuffer = GLBuffers.newDirectFloatBuffer(lightProperties); 

     // Create a direct buffer for the material properties 
     FloatBuffer materialBuffer = GLBuffers.newDirectFloatBuffer(materialProperties); 

     // Create a direct buffer for the light properties 
     FloatBuffer cameraBuffer = GLBuffers.newDirectFloatBuffer(cameraProperties); 


     // Create the OpenGL buffers names 
     gl.glCreateBuffers(Buffer.MAX, bufferNames); 

     // Create and initialize a buffer storage for the vertex data 
     gl.glBindBuffer(GL_ARRAY_BUFFER, bufferNames.get(Buffer.VERTEX)); 
     gl.glBufferStorage(GL_ARRAY_BUFFER, vertexBuffer.capacity() * Float.BYTES, vertexBuffer, 0); 
     gl.glBindBuffer(GL_ARRAY_BUFFER, 0); 

     // Create and initialize a buffer storage for the triangle indices 
     gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferNames.get(Buffer.ELEMENT)); 
     gl.glBufferStorage(GL_ELEMENT_ARRAY_BUFFER, elementBuffer.capacity() * Short.BYTES, elementBuffer, 0); 
     gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 


     // Retrieve the uniform buffer offset alignment minimum 
     IntBuffer uniformBufferOffset = GLBuffers.newDirectIntBuffer(1); 
     gl.glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, uniformBufferOffset); 
     // Set the required bytes for the matrices in accordance to the uniform buffer offset alignment minimum 
     int globalBlockSize = Math.max(16 * 4 * 2, uniformBufferOffset.get(0)); 
     int modelBlockSize = Math.max(16 * 4, uniformBufferOffset.get(0)); 
     int lightBlockSize = Math.max(12 * Float.BYTES, uniformBufferOffset.get(0)); 
     int materialBlockSize = Math.max(3 * Float.BYTES, uniformBufferOffset.get(0)); 
     int cameraBlockSize = Math.max(3 * Float.BYTES, uniformBufferOffset.get(0)); 


     // Create and initialize a named storage for the global matrices 
     gl.glBindBuffer(GL_UNIFORM_BUFFER, bufferNames.get(Buffer.GLOBAL_MATRICES)); 
     gl.glBufferStorage(GL_UNIFORM_BUFFER, globalBlockSize, null, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); 
     gl.glBindBuffer(GL_UNIFORM_BUFFER, 0); 

     // Create and initialize a named storage for the model matrix 
     // NUMERO 1 
     gl.glBindBuffer(GL_UNIFORM_BUFFER, bufferNames.get(Buffer.MODEL_MATRIX1)); 
     gl.glBufferStorage(GL_UNIFORM_BUFFER, modelBlockSize, null, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); 
     gl.glBindBuffer(GL_UNIFORM_BUFFER, 0); 

     // NUMERO 2 
     gl.glBindBuffer(GL_UNIFORM_BUFFER, bufferNames.get(Buffer.MODEL_MATRIX2)); 
     gl.glBufferStorage(GL_UNIFORM_BUFFER, modelBlockSize, null, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); 
     gl.glBindBuffer(GL_UNIFORM_BUFFER, 0); 

     // NUMERO 3 
     gl.glBindBuffer(GL_UNIFORM_BUFFER, bufferNames.get(Buffer.MODEL_MATRIX3)); 
     gl.glBufferStorage(GL_UNIFORM_BUFFER, modelBlockSize, null, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); 
     gl.glBindBuffer(GL_UNIFORM_BUFFER, 0); 

     // Create and initialize a named buffer storage for the light properties 
     gl.glBindBuffer(GL_UNIFORM_BUFFER, bufferNames.get(Buffer.LIGHT_PROPERTIES)); 
     gl.glBufferStorage(GL_UNIFORM_BUFFER, lightBlockSize, lightBuffer, 0); 
     gl.glBindBuffer(GL_UNIFORM_BUFFER, 0); 

     // Create and initialize a named buffer storage for the camera properties 
     gl.glBindBuffer(GL_UNIFORM_BUFFER, bufferNames.get(Buffer.MATERIAL_PROPERTIES)); 
     gl.glBufferStorage(GL_UNIFORM_BUFFER, materialBlockSize, materialBuffer, 0); 
     gl.glBindBuffer(GL_UNIFORM_BUFFER, 0); 

     // Create and initialize a named buffer storage for the camera properties 
     gl.glBindBuffer(GL_UNIFORM_BUFFER, bufferNames.get(Buffer.CAMERA_PROPERTIES)); 
     gl.glBufferStorage(GL_UNIFORM_BUFFER, cameraBlockSize, cameraBuffer, 0); 
     gl.glBindBuffer(GL_UNIFORM_BUFFER, 0); 

     // map the global matrices buffer into the client space 
     // NUMERO 1 
     globalMatricesPointer = gl.glMapNamedBufferRange(
       bufferNames.get(Buffer.GLOBAL_MATRICES), 
       0, 
       16 * 4 * 2, 
       GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); 

     // NUMERO 2 
     modelMatrixPointer1 = gl.glMapNamedBufferRange(
       bufferNames.get(Buffer.MODEL_MATRIX1), 
       0, 
       16 * 4, 
       GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); 

     // NUMERO 3 
     modelMatrixPointer2 = gl.glMapNamedBufferRange(
       bufferNames.get(Buffer.MODEL_MATRIX2), 
       0, 
       16 * 4, 
       GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); 

     // NUMERO 4 
     modelMatrixPointer3 = gl.glMapNamedBufferRange(
       bufferNames.get(Buffer.MODEL_MATRIX3), 
       0, 
       16 * 4, 
       GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); 
    } 

    // Function for initializing the vertex array 
    private void initVertexArray(GL4 gl) { 

     // Create a single vertex array object 
     gl.glCreateVertexArrays(1, vertexArrayName); 

     // Associate the vertex attributes in the vertex array object with the vertex buffer 
     gl.glVertexArrayAttribBinding(vertexArrayName.get(0), Semantic.Attr.POSITION, Semantic.Stream.A); 
     gl.glVertexArrayAttribBinding(vertexArrayName.get(0), Semantic.Attr.NORMAL, Semantic.Stream.A); 
     gl.glVertexArrayAttribBinding(vertexArrayName.get(0), Semantic.Attr.TEXCOORD, Semantic.Stream.A); 

     // Set the format of the vertex attributes in the vertex array object 
     gl.glVertexArrayAttribFormat(vertexArrayName.get(0), Semantic.Attr.POSITION, 3, GL_FLOAT, false, 0); 
     gl.glVertexArrayAttribFormat(vertexArrayName.get(0), Semantic.Attr.NORMAL, 3, GL_FLOAT, false, 3 * 4); 
     gl.glVertexArrayAttribFormat(vertexArrayName.get(0), Semantic.Attr.TEXCOORD, 2, GL_FLOAT, false, 6 * 4); 

     // Enable the vertex attributes in the vertex object 
     gl.glEnableVertexArrayAttrib(vertexArrayName.get(0), Semantic.Attr.POSITION); 
     gl.glEnableVertexArrayAttrib(vertexArrayName.get(0), Semantic.Attr.NORMAL); 
     gl.glEnableVertexArrayAttrib(vertexArrayName.get(0), Semantic.Attr.TEXCOORD); 


     // Bind the triangle indices in the vertex array object the triangle indices buffer 
     gl.glVertexArrayElementBuffer(vertexArrayName.get(0), bufferNames.get(Buffer.ELEMENT)); 

     // Bind the vertex array object to the vertex buffer 
     gl.glVertexArrayVertexBuffer(vertexArrayName.get(0), Semantic.Stream.A, bufferNames.get(Buffer.VERTEX), 0, (3+3+2) * 4); 
    } 

    private void initTexture(GL4 gl) { 
     try { 
      // Load texture 
      TextureData textureData = TextureIO.newTextureData(glProfile, new File(textureFilename), false, TextureIO.JPG); 

      // Generate texture name 
      gl.glGenTextures(1, textureNames); 

      // Bind the texture 
      gl.glBindTexture(gl.GL_TEXTURE_2D, textureNames.get(0)); 

      // Specify the format of the texture 
      gl.glTexImage2D(gl.GL_TEXTURE_2D, 
       0, 
       textureData.getInternalFormat(), 
       textureData.getWidth(), 
       textureData.getHeight(), 
       textureData.getBorder(), 
       textureData.getPixelFormat(), 
       textureData.getPixelType(), 
       textureData.getBuffer()); 

      // Set the sampler parameters 
      gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
      gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 
      gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
      gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 

      // Generate mip maps 
      gl.glGenerateMipmap(GL_TEXTURE_2D); 

      // Deactivate texture 
      gl.glBindTexture(GL_TEXTURE_2D, 0); 

     } 
     catch (IOException io) { 
      io.printStackTrace(); 
     } 
    } 

    private float[] createSphereVertices(float radius, int numH, int numV) { 
     // Variables needed for the calculations 
     float t1, t2; 
     float pi = (float)Math.PI; 
     float pi2 = (float)Math.PI*2f; 
     float d1 = pi2/numH; 
     float d2 = pi/numV; 

     // Allocate the data needed to store the necessary positions, normals and texture coordinates 
     int numVertices = (numH*(numV-1)+2); 
     int numFloats = (3+3+2); 
     float[] data = new float[numVertices*numFloats]; 

     data[0] = 0f; data[1] = radius; data[2] = 0f; 
     data[3] = 0f; data[4] = 1f; data[5] = 0f; 
     data[6] = 0.5f; data[7] = 1f; 
     for (int j=0; j<numV-1; j++) { 
      for (int i=0; i<numH; i++) { 
       // Position 
       data[(j*numH+i+1)*numFloats] = radius*(float)(Math.sin(i*d1)*Math.sin((j+1)*d2)); 
       data[(j*numH+i+1)*numFloats+1] = radius*(float)Math.cos((j+1)*d2); 
       data[(j*numH+i+1)*numFloats+2] = radius*(float)(Math.cos(i*d1)*Math.sin((j+1)*d2)); 
       // Normal 
       data[(j*numH+i+1)*numFloats+3] = (float)(Math.sin(i*d1)*Math.sin((j+1)*d2)); 
       data[(j*numH+i+1)*numFloats+4] = (float)Math.cos((j+1)*d2); 
       data[(j*numH+i+1)*numFloats+5] = (float)(Math.cos(i*d1)*Math.sin((j+1)*d2)); 
       // UV 
       data[(j*numH+i+1)*numFloats+6] = (float)(Math.asin(data[(j*numH+i+1)*numFloats+3])/Math.PI) + 0.5f; 
       data[(j*numH+i+1)*numFloats+7] = (float)(Math.asin(data[(j*numH+i+1)*numFloats+4])/Math.PI) + 0.5f; 
      } 
     } 
     data[(numVertices-1)*numFloats] = 0f; data[(numVertices-1)*numFloats+1] = -radius; data[(numVertices-1)*numFloats+2] = 0f; 
     data[(numVertices-1)*numFloats+3] = 0f; data[(numVertices-1)*numFloats+4] = -1f; data[(numVertices-1)*numFloats+5] = 0f; 
     data[(numVertices-1)*numFloats+6] = 0.5f; data[(numVertices-1)*numFloats+7] = 0f; 

     return data; 
    } 

    private short[] createSphereElements(int numH, int numV) { 

     // Allocate the data needed to store the necessary elements 
     int numTriangles = (numH*(numV-1)*2); 
     short[] data = new short[numTriangles*3]; 

     for (int i=0; i<numH; i++) { 
      data[i*3] = 0; data[i*3+1] = (short)(i+1); data[i*3+2] = (short)((i+1)%numH+1); 
     } 
     for (int j=0; j<numV-2; j++) { 
      for (int i=0; i<numH; i++) { 
       data[((j*numH+i)*2+numH)*3] = (short)(j*numH+i+1); 
       data[((j*numH+i)*2+numH)*3+1] = (short)((j+1)*numH+i+1); 
       data[((j*numH+i)*2+numH)*3+2] = (short)((j+1)*numH+(i+1)%numH+1); 

       data[((j*numH+i)*2+numH)*3+3] = (short)((j+1)*numH+(i+1)%numH+1); 
       data[((j*numH+i)*2+numH)*3+4] = (short)(j*numH+(i+1)%numH+1); 
       data[((j*numH+i)*2+numH)*3+5] = (short)(j*numH+i+1); 
      } 
     } 
     int trianglIndex = (numTriangles-numH); 
     int vertIndex = (numV-2)*numH+1; 
     for (short i=0; i<numH; i++) { 
      data[(trianglIndex+i)*3] = (short)(vertIndex+i); 
      data[(trianglIndex+i)*3+1] = (short)((numH*(numV-1)+1)); 
      data[(trianglIndex+i)*3+2] = (short)(vertIndex+(i+1)%numH); 
     } 

     return data; 
    } 

    // Private class representing a vertex program 
    private class Program { 

     // The name of the program 
     public int name = 0; 

     // Constructor 
     public Program(GL4 gl, String root, String vertex, String fragment) { 

      // Instantiate a complete vertex shader 
      ShaderCode vertShader = ShaderCode.create(gl, GL_VERTEX_SHADER, this.getClass(), root, null, vertex, 
        "vert", null, true); 

      // Instantiate a complete fragment shader 
      ShaderCode fragShader = ShaderCode.create(gl, GL_FRAGMENT_SHADER, this.getClass(), root, null, fragment, 
        "frag", null, true); 

      // Create the shader program 
      ShaderProgram shaderProgram = new ShaderProgram(); 

      // Add the vertex and fragment shader 
      shaderProgram.add(vertShader); 
      shaderProgram.add(fragShader); 

      // Initialize the program 
      shaderProgram.init(gl); 

      // Store the program name (nonzero if valid) 
      name = shaderProgram.program(); 

      // Compile and link the program 
      shaderProgram.link(gl, System.out); 
     } 
    } 

    // Interface for creating final static variables for defining the buffers 
    private interface Buffer { 
     int VERTEX = 0; 
     int ELEMENT = 1; 
     int GLOBAL_MATRICES = 2; 
     int MODEL_MATRIX1 = 3; 
     int MODEL_MATRIX2 = 4; 
     int MODEL_MATRIX3 = 5; 
     int LIGHT_PROPERTIES = 6; 
     int MATERIAL_PROPERTIES = 7; 
     int CAMERA_PROPERTIES = 8; 
     int MAX = 9; 
    } 

    // Private class to provide an semantic interface between Java and GLSL 
    private static class Semantic { 

     public interface Attr { 
      int POSITION = 0; 
      int NORMAL = 1; 
      int TEXCOORD = 2; 
     } 

     public interface Uniform { 
      int TRANSFORM0 = 1; 
      int TRANSFORM1 = 2; 
      int LIGHT0 = 3; 
      int MATERIAL = 4; 
      int CAMERA = 5; 
     } 

     public interface Stream { 
      int A = 0; 
     } 
    } 
} 
+0

在繪製('gl.glDrawElements')行星之前,您必須綁定('gl.glBindTexture')正確的紋理。 – Rabbid76

+0

好的,我很難看到每個物體和紋理之間的聯繫。我不知道/理解發送到glBindTexture的變量,如「IntBuffer textureNames = GLBuffers.newDirectIntBuffer(0)」。我看到的唯一連接是在initTexture-method中的textureData中使用的textureFilename女巫。所以這就是我一直試圖編輯而沒有運氣的地方。 –

回答

1

您需要每個紋理的紋理對象。爲此,您必須創建適當大小的容器。

private IntBuffer textureNames = GLBuffers.newDirectIntBuffer(noOfTextures); 

,你必須創建紋理對象,你必須載入紋理:

gl.glGenTextures(noOfTextures , textureNames); 

for (int i=0; i<noOfTextures; i++) { 

    TextureData textureData = TextureIO.newTextureData(glProfile, 
     new File(textureFilename[i]), false, TextureIO.JPG); 

    gl.glBindTexture(gl.GL_TEXTURE_2D, textureNames.get(i)); 

    gl.glTexImage2D(.....);  

    ..... 
} 

最後,你有你畫網格權之前綁定正確的質地:

gl.glBindTexture(gl.GL_TEXTURE_2D, textureNames.get(texture_index1)); 
gl.glDrawElements(.....); 

..... 

gl.glBindTexture(gl.GL_TEXTURE_2D, textureNames.get(texture_index2)); 
gl.glDrawElements(.....); 

考慮到生成紋理的數量,刪除它們時:

gl.glDeleteTextures(noOfTextures , textureNames); 
+0

好的,謝謝你的詳細描述。現在我按照你的描述編輯了。我認爲texture_index應該是變量i?但是我仍然只獲得了textureFileName數組中的第一個紋理。 –

+0

好吧,現在我明白了!你必須使用gl.glBindTexture(gl.GL_TEXTURE_2D,textureNames.get(texture_index));在繪圖之間,以便您選擇紋理,繪製,選擇新紋理,然後再次繪製。非常感謝你的幫助! –