此任务的目的是使用键盘输入实现交互式模型视图转换。需要修改源代码CGCW01.java。初始程序已实现对象(茶壶)的渲染并允许交互对象的放大。程序中的注释显示了您应该在哪为任务 (b) 和 (c) 添加代码,但您应该自己找到任务 (a) 的位置。您需要(a) 在程序中找到合适的位置,为转换所需的附加参数添加合适的定义;(b) 在函数keyPressed()中填入代码计算参数;(c) 在函数 display() 中填写代码以执行转换。
要实施的转变包括:‧ 在按下“M”键时,对象应该展开;‧ 在按“N”键时,对象应该缩小;‧ 按左/右箭头键,对象应左/右移动;‧ 在按下向上/向下箭头键时,对象应该向上/向下移动;‧ 在按下“X”/“C”键时,对象应围绕x轴顺时针/反旋转顺时针;‧ 按下 Y/U键时,对象应绕\y轴顺时针/反旋转顺时针。
import static com.jogamp.opengl.GL3.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import javax.swing.JFrame;
import Basic.ShaderProg;
import Basic.Transform;
import Basic.Vec4;
import Objects.STeapot;
import com.jogamp.opengl.GL3;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.awt.GLCanvas;
import com.jogamp.opengl.util.FPSAnimator;
public class CGCW01 extends JFrame{
final GLCanvas canvas; //Define a canvas
final FPSAnimator animator=new FPSAnimator(60, true);
final Renderer renderer = new Renderer();
public CGCW01() {
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
canvas.addKeyListener(renderer);
animator.add(canvas);
setTitle("Coursework 1");
setSize(500,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
animator.start();
canvas.requestFocus();
}
public static void main(String[] args) {
new CGCW01();
}
class Renderer implements GLEventListener, KeyListener{
private Transform T = new Transform();
//VAOs and VBOs parameters
private int idPoint=0, numVAOs = 1;
private int idBuffer=0, numVBOs = 1;
private int idElement=0, numEBOs = 1;
private int[] VAOs = new int[numVAOs];
private int[] VBOs = new int[numVBOs];
private int[] EBOs = new int[numEBOs];
//Model parameters
private int numElements;
private int vPosition;
private int vNormal;
//Transformation parameters
private int ModelView;
private int Projection;
private int NormalTransform;
private float scale = 1;
@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.glPointSize(5);
gl.glLineWidth(5);
T.initialize();
//Key control interaction
T.scale(scale, scale, scale);
/* Task 1.c: Fill in transformation code here*/
//Locate camera
T.lookAt(0, 0, 0, 0, 0, -1, 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 );
gl.glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); //default
gl.glDrawElements(GL_TRIANGLES, numElements, GL_UNSIGNED_INT, 0); //for solid teapot
}
@Override
public void dispose(GLAutoDrawable drawable) {
// TODO Auto-generated method stub
}
@Override
public void init(GLAutoDrawable drawable) {
GL3 gl = drawable.getGL().getGL3(); // Get the GL pipeline object this
gl.glEnable(GL_PRIMITIVE_RESTART);
gl.glPrimitiveRestartIndex(0xFFFF);
gl.glEnable(GL_CULL_FACE);
STeapot teapot = new STeapot(2);
float [] vertexArray = teapot.getVertices();
float [] normalArray = teapot.getNormals();
int [] vertexIndexs =teapot.getIndices();
numElements = teapot.getNumIndices();
gl.glGenVertexArrays(numVAOs,VAOs,0);
gl.glBindVertexArray(VAOs[idPoint]);
FloatBuffer vertices = FloatBuffer.wrap(vertexArray);
FloatBuffer normals = FloatBuffer.wrap(normalArray);
gl.glGenBuffers(numVBOs, VBOs,0);
gl.glBindBuffer(GL_ARRAY_BUFFER, VBOs[idBuffer]);
// Create an empty buffer with the size we need
// and a null pointer for the data values
long vertexSize = vertexArray.length*(Float.SIZE/8);
long normalSize = normalArray.length*(Float.SIZE/8);
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);
gl.glGenBuffers(numEBOs, EBOs,0);
gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBOs[idElement]);
long indexSize = vertexIndexs.length*(Integer.SIZE/8);
gl.glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexSize,
elements, GL_STATIC_DRAW); // pay attention to *Float.SIZE/8
ShaderProg shaderproc = new ShaderProg(gl, "Gouraud.vert", "Gouraud.frag");
int program = shaderproc.getProgram();
gl.glUseProgram(program);
// Initialize the vertex position attribute in the vertex shader
vPosition = gl.glGetAttribLocation( program, "vPosition" );
gl.glEnableVertexAttribArray(vPosition);
gl.glVertexAttribPointer(vPosition, 3, GL_FLOAT, false, 0, 0L);
// Initialize the vertex color attribute in the vertex shader.
// The offset is the same as in the glBufferSubData, i.e., vertexSize
// It is the starting point of the color data
vNormal = gl.glGetAttribLocation( program, "vNormal" );
gl.glEnableVertexAttribArray(vNormal);
gl.glVertexAttribPointer(vNormal, 3, GL_FLOAT, false, 0, vertexSize);
//Get connected with the ModelView matrix in the vertex shader
ModelView = gl.glGetUniformLocation(program, "ModelView");
NormalTransform = gl.glGetUniformLocation(program, "NormalTransform");
Projection = gl.glGetUniformLocation(program, "Projection");
// Initialize shader lighting parameters
float[] lightPosition = {10.0f, 10.0f, -10.0f, 0.0f};
Vec4 lightAmbient = new Vec4(1.0f, 1.0f, 1.0f, 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);
//Brass material
Vec4 materialAmbient = new Vec4(0.329412f, 0.223529f, 0.027451f, 1.0f);
Vec4 materialDiffuse = new Vec4(0.780392f, 0.568627f, 0.113725f, 1.0f);
Vec4 materialSpecular = new Vec4(0.992157f, 0.941176f, 0.807843f, 1.0f);
float materialShininess = 27.8974f;
Vec4 ambientProduct = lightAmbient.times(materialAmbient);
float[] ambient = ambientProduct.getVector();
Vec4 diffuseProduct = lightDiffuse.times(materialDiffuse);
float[] diffuse = diffuseProduct.getVector();
Vec4 specularProduct = lightSpecular.times(materialSpecular);
float[] specular = specularProduct.getVector();
gl.glUniform4fv( gl.glGetUniformLocation(program, "AmbientProduct"),
1, ambient,0 );
gl.glUniform4fv( gl.glGetUniformLocation(program, "DiffuseProduct"),
1, diffuse, 0 );
gl.glUniform4fv( gl.glGetUniformLocation(program, "SpecularProduct"),
1, specular, 0 );
gl.glUniform4fv( gl.glGetUniformLocation(program, "LightPosition"),
1, lightPosition, 0 );
gl.glUniform1f( gl.glGetUniformLocation(program, "Shininess"),
materialShininess );
// This is necessary. Otherwise, the The color on back face may display
// gl.glDepthFunc(GL_LESS);
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 keyPressed(KeyEvent ke) {
int keyEvent = ke.getKeyCode();
switch (keyEvent){
case KeyEvent.VK_ESCAPE:
System.exit(0);
break;
case KeyEvent.VK_M:
scale *= 1.1;
break;
/* Task 1.a: Define some parameters for transformations
* somewhere else in this program.
*
* Task 1.b: Fill in code here to calculate the parameters to
* respond to some key events.
*
// scale down the object when the key 'N' is pressed
// move the object left when the Left arrow key is pressed
// move the object right when the Right arrow key is pressed
// move the object up when the Up arrow key is pressed
// move the object down when the down arrow key is pressed
// rotate the object around X axis clockwise or anti-clockwise
// when the key 'X' or 'C' is pressed
// rotate the object around Y axis clockwise or anti-clockwise
// when the key 'Y' or 'U' is pressed
*/
}
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent ke) {
// TODO Auto-generated method stub
}
}
}
有说明问题不直接说?
可以把问题说清楚一点