对模型进行绘制核心还是进行坐标变换,将模型坐标最终变换为屏幕像素坐标,而变换主要有三种模式,模型视图变换,投影变换和纹理变换!
模型视图变换细分为模型变换和视图变换,模型变换方法就是设置平移,旋转,缩放矩阵,视图变换可以通过方法gluLookAt来设置相机的方位,从而得到视图变换矩阵用于视图变换,当然本质上是得到了视图变换矩阵,内部也是利用参数计算出了矩阵左乘当前矩阵模式的变换矩阵,所以,worldwind直接计算出视图变化矩阵ModeViewMatrix,利用glLoadMatrix设置为变换矩阵后进行模型视图变换。
投影变换可以通过gluPerspective来设置用于透视投影的视景体的大小和形状,本质上当然也是设置了ProjectionMatrix,所以,worldwind也直接根据相关参数计算出了投影矩阵,通过glLoadMatrix设置为投影变换矩阵进行投影变换!
//BasicOrbitView
protected void doApply(DrawContext dc)
{
if (dc == null)
{
String message = Logging.getMessage("nullValue.DrawContextIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (dc.getGL() == null)
{
String message = Logging.getMessage("nullValue.DrawingContextGLIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (dc.getGlobe() == null)
{
String message = Logging.getMessage("nullValue.DrawingContextGlobeIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
// Update the draw context and the globe, then re-apply the current view property limits. Apply view property
// limits after updating the globe so that globe-specific property limits are applied correctly.
this.dc = dc;
this.globe = this.dc.getGlobe();
this.center = this.getOrbitViewLimits().limitCenterPosition(this, this.center);
this.heading = this.getOrbitViewLimits().limitHeading(this, this.heading);
this.pitch = this.getOrbitViewLimits().limitPitch(this, this.pitch);
this.roll = this.getOrbitViewLimits().limitRoll(this, this.roll);
this.zoom = this.getOrbitViewLimits().limitZoom(this, this.zoom);
//========== modelview matrix state ==========//
// Compute the current modelview matrix.
this.modelview = OrbitViewInputSupport.computeTransformMatrix(this.globe, this.center,
this.heading, this.pitch, this.roll, this.zoom);
if (this.modelview == null)
this.modelview = Matrix.IDENTITY;
// Compute the current inverse-modelview matrix.
this.modelviewInv = this.modelview.getInverse();
if (this.modelviewInv == null)
this.modelviewInv = Matrix.IDENTITY;
//========== projection matrix state ==========//
// Get the current OpenGL viewport state.
int[] viewportArray = new int[4];
this.dc.getGL().glGetIntegerv(GL.GL_VIEWPORT, viewportArray, 0);
this.viewport = new java.awt.Rectangle(viewportArray[0], viewportArray[1], viewportArray[2], viewportArray[3]);
// Compute the current clip plane distances. The near distance depends on the far distance, so we must compute
// the far distance first.
this.farClipDistance = computeFarClipDistance();
this.nearClipDistance = computeNearClipDistance();
// Compute the current viewport dimensions.
double viewportWidth = this.viewport.getWidth() <= 0.0 ? 1.0 : this.viewport.getWidth();
double viewportHeight = this.viewport.getHeight() <= 0.0 ? 1.0 : this.viewport.getHeight();
// Compute the current projection matrix.
this.projection = Matrix.fromPerspective(this.fieldOfView,
viewportWidth, viewportHeight,
this.nearClipDistance, this.farClipDistance);
// Compute the current frustum.
this.frustum = Frustum.fromPerspective(this.fieldOfView,
(int) viewportWidth, (int) viewportHeight,
this.nearClipDistance, this.farClipDistance);
//========== load GL matrix state ==========//
loadGLViewState(dc, this.modelview, this.projection);
//========== after apply (GL matrix state) ==========//
afterDoApply();
}
这里有一个问题,在一个场景中绘制多个图形,相机的状态是否共享,唯一,还是在绘制每个图形时都可以独立设置?
简单的测试证明是唯一的,也就是在一个场景下的所有图形都是一个观察点观察的效果!
这一点是如何做到的呢?绘制图形时的状态不是可以改变吗?难道说投影矩阵是唯一的吗?
import javax.swing.JFrame;
import com.jogamp.opengl.GL2;
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.glu.GLU;
import com.jogamp.opengl.util.FPSAnimator;
public class TestDiffStat implements GLEventListener {
GLU glu= new GLU();
private float rtri; //for angle of rotation
@Override
public void display( GLAutoDrawable drawable ) {
//drawtriangle(drawable);
drawRectangle(drawable);
}
@Override
public void dispose( GLAutoDrawable drawable ) {
//method body
}
@Override
public void init( GLAutoDrawable drawable ) {
// method body
}
@Override
public void reshape( GLAutoDrawable drawable, int x, int y, int width, int height ) {
// method body
GL2 gl = drawable.getGL().getGL2();
gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluPerspective(45.0, width/ height, 1.0, 20.0);
}
public void drawtriangle(GLAutoDrawable drawable){
glu.gluLookAt(0, 0, 5, 1, 1, 0, 0, 1, 0);
GL2 gl = drawable.getGL().getGL2();
gl.glMatrixMode(GL2.GL_MODELVIEW);
gl.glPushMatrix();
/* double[] params= new double[16];
gl.glGetDoublev(GL2.GL_CURRENT_MATRIX_ARB, params, 0);
for(int i =0;i<16;i++){
System.out.print(params[i]+",");
}*/
gl.glClear (GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT );
// Clear The Screen And The Depth Buffer
gl.glLoadIdentity();
// Reset The View
// gl.glRotatef( rtri, 0.0f, 1.0f, 0.0f );//triangle rotation
gl.glBegin( GL2.GL_TRIANGLES ); // Drawing Using Triangles
gl.glColor3f( 1.0f, 0.0f, 0.0f ); //Red
gl.glVertex3f( 0.5f,0.5f,0.0f ); // Top
gl.glColor3f( 0.0f,1.0f,0.0f ); //blue
gl.glVertex3f( -0.5f,0.5f,0.0f ); // Bottom Left
gl.glColor3f( 0.0f,0.0f,1.0f ); //green
gl.glVertex3f( 0f,-0.5f,0.0f ); // Bottom Right
gl.glEnd();
gl.glFlush();
rtri +=0.2f; //assigning the angle
gl.glPopMatrix();
}
public void drawRectangle(GLAutoDrawable drawable){
glu.gluLookAt(0, 0, 5, 0, 0, 0, 0, 1, 0);
GL2 gl = drawable.getGL().getGL2();
gl.glMatrixMode(GL2.GL_MODELVIEW);
gl.glPushMatrix();
/* double[] params= new double[16];
gl.glGetDoublev(GL2.GL_CURRENT_MATRIX_ARB, params, 0);
for(int i =0;i<16;i++){
System.out.print(params[i]+",");
}*/
gl.glClear (GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT );
// Clear The Screen And The Depth Buffer
gl.glLoadIdentity();
// Reset The View
// gl.glRotatef( rtri, 0.0f, 1.0f, 0.0f );//triangle rotation
gl.glBegin( GL2.GL_TRIANGLES ); // Drawing Using Triangles
gl.glColor3f( 1.0f, 0.0f, 0.0f ); //Red
gl.glVertex3f( 0.5f,0.5f,0.0f ); // Top
gl.glColor3f( 0.0f,1.0f,0.0f ); //blue
gl.glVertex3f( -0.5f,0.5f,0.0f ); // Bottom Left
gl.glColor3f( 0.0f,0.0f,1.0f ); //green
gl.glVertex3f( 0f,-0.5f,0.0f ); // Bottom Right
gl.glEnd();
gl.glFlush();
rtri +=0.2f; //assigning the angle
gl.glPopMatrix();
}
public static void main( String[] args ) {
//getting the capabilities object of GL2 profile
final GLProfile profile = GLProfile.get( GLProfile.GL2 );
GLCapabilities capabilities = new GLCapabilities( profile );
// The canvas
final GLCanvas glcanvas = new GLCanvas( capabilities );
TestDiffStat testDiffStat = new TestDiffStat();
glcanvas.addGLEventListener( testDiffStat );
glcanvas.setSize( 400, 400 );
//creating frame
final JFrame frame = new JFrame ( "Test LookAt" );
//adding canvas to it
frame.getContentPane().add( glcanvas );
frame.setSize( frame.getContentPane().getPreferredSize() );
frame.setVisible( true );
//Instantiating and Initiating Animator
final FPSAnimator animator = new FPSAnimator( glcanvas, 300,true );
//animator.start();
}//end of main
}