我有这个代码用于显示两个数字使用他们的类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]);
};
}
}