使用Java和openGL的圆柱模型无法按预期工作

时间:2017-12-03 16:41:34

标签: java opengl jframe computational-geometry jogl

我有这个代码用于显示两个数字使用他们的类Scylinder和SSphere。但是,屏幕上仅显示球体,并且不显示错误。任何想法为什么它只显示第一个对象并跳过第二个但没有显示错误?提前谢谢。我是初学者,不知道我的错误在哪里。

这是我的圆柱代码:

package Objects;


public class SCylinder extends SObject{
private float radius;
private int slices;
private int stacks;

public SCylinder(){ 
    super();
    init();
    update();
}

public SCylinder(float radius){
    super();
    init();
    this.radius = radius;
    update();
}

public SCylinder(float radius, int slices, int stacks){
    super();
    this.radius = radius;
    this.slices = slices;
    this.stacks = stacks;
    update();
}

private void init(){
    this.radius = 1;
    this.slices = 20;
    this.stacks = 20;
}

@Override
protected void genData() {
        int i,j,k;
            // stacks = no. of Latitude lines,
                              // slices = no. of Longitude lines
            numVertices = 10000; 

            //double deltaLong = PI * 2 / slices;
            //double deltaLat = PI / stacks;


            //numVertices = (slices + 1) * (stacks - 1) + 2;
             vertices = new float[numVertices * 3];
             normals = new float[numVertices * 3];
            //textures = new float[numVertices * 2];


            int theta = 0;
                        // vertices body 
              k = 1; 
              for (i = 0; i < slices; i++) { 
                 normals[3 * k] = cos(theta * i); 
                 normals[3 * k + 1] = sin(theta * i); 
                 normals[3 * k + 2] = 0; 

                 vertices[3 * k] = radius * normals[3 * k]; 
                 vertices[3 * k + 1] = radius * normals[3 * k + 1]; 
                 vertices[3 * k + 2] = .50f; 
                 k++; 
               // end of for vertices on body 
              }
              for (i = 0; i < slices; i++) { 
                 normals[3 * k] = cos(theta * i); 
                 normals[3 * k + 1] = sin(theta * i); 
                 normals[3 * k + 2] = 0; 

                 vertices[3 * k] = radius * normals[3 * k]; 
                 vertices[3 * k + 1] = radius * normals[3 * k + 1]; 
                 vertices[3 * k + 2] = -.50f; 

                 k++; 
              } // end of for vertices on body 

                    // Generate indices for triangular mesh 
             numIndices = 100000; 
             indices = new  int[numIndices]; 

            k = 0; 

            for (i = 0; i < slices; ++i) {

                 int i1 = i; 
                 int i2 = (i1 + 1) % slices; 
                 int i3 = i1 + slices; 
                 int i4 = i2 + slices; 

                 indices[k++] = i1; 
                 indices[k++] = i3; 
                 indices[k++] = i2;


                 indices[k++] = i4; 
                 indices[k++] = i2; 
                 indices[k++] = i3;


            }






public void setRadius(float radius){
    this.radius = radius;
    updated = false;
}

public void setSlices(int slices){
    this.slices = slices;
    updated = false;
}

public void setStacks(int stacks){
    this.stacks = stacks;
    updated = false;
}

public float getRadius(){
    return radius;
}

public int getSlices(){
    return slices;
}

public int getStacks(){
    return stacks;
}   
 }                                                                           

下一部分是主文件:

public class CGCW02 extends JFrame{

final GLCanvas canvas; //Define a canvas 
final FPSAnimator animator=new FPSAnimator(60, true);
final Renderer renderer = new Renderer();

public CGCW02() {
    GLProfile glp = GLProfile.get(GLProfile.GL3);
    GLCapabilities caps = new GLCapabilities(glp);
    canvas = new GLCanvas(caps);

    add(canvas, java.awt.BorderLayout.CENTER); // Put the canvas in the frame
    canvas.addGLEventListener(renderer); //Set the canvas to listen GLEvents

    animator.add(canvas);

    setTitle("Coursework 2");
    setSize(500,500);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);

    animator.start();
    canvas.requestFocus();
    }

public static void main(String[] args) {
             new CGCW02();

}

class Renderer implements GLEventListener {

    private Transform T = new Transform(); //model_view transform

    //VAOs and VBOs parameters
    private int idPoint=0, numVAOs = 2;
    private int idBuffer=0, numVBOs = 2;
    private int idElement=0, numEBOs = 2;
    private int[] VAOs = new int[numVAOs];
    private int[] VBOs = new int[numVBOs];
    private int[] EBOs = new int[numEBOs];

    //Model parameters
    private int[] numElements = new int[numEBOs];
    private long vertexSize; 
    private long normalSize; 
    private int vPosition;
    private int vNormal;

    //Transformation parameters
    private int ModelView;
    private int NormalTransform;
    private int Projection; 

    //Lighting parameter
    private int AmbientProduct;
    private int DiffuseProduct;
    private int SpecularProduct;            
    private int Shininess;

    private float[] ambient1; 
            private float[] diffuse1;
            private float[] specular1;
            private float  materialShininess1;

    private float[] ambient2; 
            private float[] diffuse2;
            private float[] specular2;
            private float  materialShininess2;

    @Override
    public void display(GLAutoDrawable drawable) {
        GL3 gl = drawable.getGL().getGL3(); // Get the GL pipeline object this 

        gl.glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
                    //gl.glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

        //Transformation for the first object (sphere)
        T.initialize();
        T.scale(0.5f, 0.5f, 0.5f);
                    T.rotateX(-90);
        T.translate(0, -0.4f, 0);


        //Locate camera
        T.lookAt(0, 0, 0, 0, 0, -100, 0, 1, 0);     //Default                   

        //Send model_view and normal transformation matrices to shader. 
        //Here parameter 'true' for transpose means to convert the row-major  
        //matrix to column major one, which is required when vertices'
        //location vectors are pre-multiplied by the model_view matrix.
        //Note that the normal transformation matrix is the inverse-transpose
        //matrix of the vertex transformation matrix
        gl.glUniformMatrix4fv( ModelView, 1, true, T.getTransformv(), 0 );          
        gl.glUniformMatrix4fv( NormalTransform, 1, true, T.getInvTransformTv(), 0 );            

        //send other uniform variables to shader
        gl.glUniform4fv( AmbientProduct, 1, ambient1,0 );
                    gl.glUniform4fv( DiffuseProduct, 1, diffuse1, 0 );
                    gl.glUniform4fv( SpecularProduct, 1, specular1, 0 );            
                    gl.glUniform1f( Shininess, materialShininess1);

        //binding and draw the first object
        idPoint=0;
        idBuffer=0;
        idElement=0;
        bindObject(gl);
            gl.glDrawElements(GL_TRIANGLES, numElements[idElement], GL_UNSIGNED_INT, 0);    

        //Add code here to transform the second object (a cylinder) into the position
        //as suggested in the coursework description, and draw it

                    T.scale(0.5f, 1.4f,0.5f);
                    T.translate(10, 0.7f, 0);

        //binding and draw the second object
        idPoint=1;
        idBuffer=1;
        idElement=1;
                    bindObject(gl);     

        gl.glDrawElements(GL_TRIANGLES, numElements[idElement], GL_UNSIGNED_INT, 0);    //for solid sphere      
    }       

    @Override
    public void init(GLAutoDrawable drawable) {
        GL3 gl = drawable.getGL().getGL3(); // Get the GL pipeline object this 

        System.out.print("GL_Version: " + gl.glGetString(GL_VERSION));

        gl.glEnable(GL_CULL_FACE); 

        //compile and use the shader program
        ShaderProg shaderproc = new ShaderProg(gl, "Gouraud.vert", "Gouraud.frag");
        int program = shaderproc.getProgram();
        gl.glUseProgram(program);

            // Initialize the vertex position and normal attribute in the vertex shader    
        vPosition = gl.glGetAttribLocation( program, "vPosition" );
        vNormal = gl.glGetAttribLocation( program, "vNormal" );

        // Get connected with the ModelView, NormalTransform, and Projection matrices
        // in the vertex shader
        ModelView = gl.glGetUniformLocation(program, "ModelView");
        NormalTransform = gl.glGetUniformLocation(program, "NormalTransform");
        Projection = gl.glGetUniformLocation(program, "Projection");

        // Get connected with uniform variables AmbientProduct, DiffuseProduct, 
        // SpecularProduct, and Shininess in the vertex shader          
        AmbientProduct = gl.glGetUniformLocation(program, "AmbientProduct");
        DiffuseProduct = gl.glGetUniformLocation(program, "DiffuseProduct");
        SpecularProduct = gl.glGetUniformLocation(program, "SpecularProduct");          
        Shininess = gl.glGetUniformLocation(program, "Shininess");

        // Generate VAOs, VBOs, and EBOs
            gl.glGenVertexArrays(numVAOs,VAOs,0);
        gl.glGenBuffers(numVBOs, VBOs,0);
        gl.glGenBuffers(numEBOs, EBOs,0);

        // Initialize shader lighting parameters
        float[] lightPosition = {10.0f, 15.0f, 20.0f, 1.0f};
        Vec4 lightAmbient = new Vec4(0.7f, 0.7f, 0.7f, 1.0f);
        Vec4 lightDiffuse = new Vec4(1.0f, 1.0f, 1.0f, 1.0f);
        Vec4 lightSpecular = new Vec4(1.0f, 1.0f, 1.0f, 1.0f);

        gl.glUniform4fv( gl.glGetUniformLocation(program, "LightPosition"),
              1, lightPosition, 0 );

        //create the first object: a sphere-----------------------------------
        SObject sphere = new SSphere(1,40,40);
        idPoint=0;
        idBuffer=0;
        idElement=0;
        createObject(gl, sphere);


        // Set Sphere material
        Vec4 materialAmbient1 = new Vec4(0.5f, 0.0f, 0.0f, 1.0f);
        Vec4 materialDiffuse1 = new Vec4(0.7f, 0.0f, 0.0f, 1.0f);
        Vec4 materialSpecular1 = new Vec4(1.0f, 1.0f, 1.0f, 1.0f);
        materialShininess1 = 64.0f;

        Vec4 ambientProduct = lightAmbient.times(materialAmbient1);
        ambient1 = ambientProduct.getVector();
        Vec4 diffuseProduct = lightDiffuse.times(materialDiffuse1);
        diffuse1 = diffuseProduct.getVector();
        Vec4 specularProduct = lightSpecular.times(materialSpecular1);
        specular1 = specularProduct.getVector();

                //Create the second object (a cylinder) here, and set the ----------------------- 
        //cylinder material different to the sphere
                //Vertices below are in Clockwise orientation
                //Default setting for glFrontFace is Counter-clockwise


                   SObject cylinder = new SCylinder(20,40,40);
                    idPoint=1;
        idBuffer=1;
        idElement=1;
        createObject (gl,cylinder);

                    // Set Cylinder's material
        Vec4 materialAmbient2 = new Vec4(0.0215f, 0.1745f, 0.0215f, 0.55f);
        Vec4 materialDiffuse2 = new Vec4(0.07568f, 0.61424f, 0.07568f, 0.55f);
        Vec4 materialSpecular2 = new Vec4(0.633f, 0.727f, 0.633f, 0.55f);
        materialShininess1 = 76.8f;

        Vec4 ambientProduct2= lightAmbient.times(materialAmbient2);
        ambient2 = ambientProduct2.getVector();
        Vec4 diffuseProduct2 = lightDiffuse.times(materialDiffuse2);
        diffuse2 = diffuseProduct2.getVector();
        Vec4 specularProduct2 = lightSpecular.times(materialSpecular2);
        specular2 = specularProduct2.getVector();


        gl.glEnable(GL_DEPTH_TEST);         
    }

    @Override
    public void reshape(GLAutoDrawable drawable, int x, int y, int w,
            int h) {

        GL3 gl = drawable.getGL().getGL3(); // Get the GL pipeline object this 

        gl.glViewport(x, y, w, h);

        T.initialize();

        //projection
        if(h<1){h=1;}
        if(w<1){w=1;}           
        float a = (float) w/ h;   //aspect 
        if (w < h) {
            T.ortho(-1, 1, -1/a, 1/a, -1, 1);
        }
        else{
            T.ortho(-1*a, 1*a, -1, 1, -1, 1);
        }

        // Convert right-hand to left-hand coordinate system
        T.reverseZ();
        gl.glUniformMatrix4fv( Projection, 1, true, T.getTransformv(), 0 );         

    }

    @Override
    public void dispose(GLAutoDrawable drawable) {
        // TODO Auto-generated method stub

    }

    public void createObject(GL3 gl, SObject obj) {
        float [] vertexArray = obj.getVertices();
        float [] normalArray = obj.getNormals();
        int [] vertexIndexs =obj.getIndices();
        numElements[idElement] = obj.getNumIndices();

        bindObject(gl);

        FloatBuffer vertices = FloatBuffer.wrap(vertexArray);
        FloatBuffer normals = FloatBuffer.wrap(normalArray);

                    // Create an empty buffer with the size we need 
        // and a null pointer for the data values

        vertexSize = vertexArray.length*(Float.SIZE/0x8);
        normalSize = normalArray.length*(Float.SIZE/0x8);
        gl.glBufferData(GL_ARRAY_BUFFER, vertexSize +normalSize, 
                null, GL_STATIC_DRAW); // pay attention to *Float.SIZE/8

        // Load the real data separately.  We put the colors right after the vertex coordinates,
        // so, the offset for colors is the size of vertices in bytes
        gl.glBufferSubData( GL_ARRAY_BUFFER, 0, vertexSize, vertices );
        gl.glBufferSubData( GL_ARRAY_BUFFER, vertexSize, normalSize, normals );

        IntBuffer elements = IntBuffer.wrap(vertexIndexs);          

        long indexSize = vertexIndexs.length*(Integer.SIZE/8);
        gl.glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexSize, 
                elements, GL_STATIC_DRAW); // pay attention to *Float.SIZE/8                        
        gl.glEnableVertexAttribArray(vPosition);
        gl.glVertexAttribPointer(vPosition, 3, GL_FLOAT, false, 0, 0L);
        gl.glEnableVertexAttribArray(vNormal);
        gl.glVertexAttribPointer(vNormal, 3, GL_FLOAT, false, 0, vertexSize);
    }

    public void bindObject(GL3 gl){
        gl.glBindVertexArray(VAOs[idPoint]);
        gl.glBindBuffer(GL_ARRAY_BUFFER, VBOs[idBuffer]);
        gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBOs[idElement]);          
    };
}
}

0 个答案:

没有答案