需要帮助在JOGL中为不同的对象添加不同的纹理

时间:2017-10-06 20:37:13

标签: java jogl texture-mapping opengl-4

所以我已经用我从老师那里获得的代码工作了两晚。我一直在寻找在JOGL上找到一些好的Javadoc而没有太大的成功。所以我一直在使用try / fail方法来改变变量。我已经学会了如何控制旋转,距离和大小。所以我给了我一点"太阳系" - 但是这里出现了我的问题 - 如何为我所制作的不同星球实现多个纹理?继承我的代码:

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

1 个答案:

答案 0 :(得分: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);