namespace sharpGLTest03 { // 主表单类 public partial class SharpGLForm : Form { /// <summary> /// Initializes a new instance of the <see cref="SharpGLForm"/> class. /// </summary> public SharpGLForm() { InitializeComponent(); } // 处理OpenGL控件的OpenGLDraw事件 // "sender":事件的来源 // "e":包含事件数据的实例 private void openGLControl_OpenGLDraw(object sender, RenderEventArgs e) { // 获取OpenGL对象 OpenGL gl = openGLControl.OpenGL; // 清除颜色和深度缓冲区 gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT); // 加载单位矩阵 gl.LoadIdentity(); // 围绕Y轴旋转 //gl.Rotate(rotation, 0.0f, 1.0f, 0.0f); // 画一个彩色的金字塔 gl.Begin(OpenGL.GL_TRIANGLES); { // 画三角形 gl.Vertex(0.0f, 0f, 0.0f); gl.Vertex(-1.0f, -1f, 0.0f); gl.Vertex(1.0f, -1f, 0.0f); } //gl.Color(1.0f, 0.0f, 0.0f); //gl.Vertex(0.0f, 1.0f, 0.0f); //gl.Color(0.0f, 1.0f, 0.0f); //gl.Vertex(-1.0f, -1.0f, 1.0f); //gl.Color(0.0f, 0.0f, 1.0f); //gl.Vertex(1.0f, -1.0f, 1.0f); //gl.Color(1.0f, 0.0f, 0.0f); //gl.Vertex(0.0f, 1.0f, 0.0f); //gl.Color(0.0f, 0.0f, 1.0f); //gl.Vertex(1.0f, -1.0f, 1.0f); //gl.Color(0.0f, 1.0f, 0.0f); //gl.Vertex(1.0f, -1.0f, -1.0f); //gl.Color(1.0f, 0.0f, 0.0f); //gl.Vertex(0.0f, 1.0f, 0.0f); //gl.Color(0.0f, 1.0f, 0.0f); //gl.Vertex(1.0f, -1.0f, -1.0f); //gl.Color(0.0f, 0.0f, 1.0f); //gl.Vertex(-1.0f, -1.0f, -1.0f); //gl.Color(1.0f, 0.0f, 0.0f); //gl.Vertex(0.0f, 1.0f, 0.0f); //gl.Color(0.0f, 0.0f, 1.0f); //gl.Vertex(-1.0f, -1.0f, -1.0f); //gl.Color(0.0f, 1.0f, 0.0f); //gl.Vertex(-1.0f, -1.0f, 1.0f); gl.End(); // 轻推旋转 //rotation += 3.0f; } // 处理OpenGL控件的OpenGLInitialized事件 private void openGLControl_OpenGLInitialized(object sender, EventArgs e) { // TODO: 在这里初始化OpenGL // 获取OpenGL对象 OpenGL gl = openGLControl.OpenGL; // 设置清晰的颜色 gl.ClearColor(0, 0, 0, 0); } // 处理OpenGL控件的Resized事件 private void openGLControl_Resized(object sender, EventArgs e) { // 在此设置投影矩阵 // 获取OpenGL对象 OpenGL gl = openGLControl.OpenGL; // 设置投影矩阵;设置当前矩阵模式,对投影矩阵应用随后的矩阵操作 gl.MatrixMode(OpenGL.GL_PROJECTION); // 加载身份;重置当前指定的矩阵为单位矩阵,将当前的用户坐标系的原点移到了屏幕中心 gl.LoadIdentity(); // 创建透视投影变换 /* * 创建透视效果的函数名和原型 * Perspective(double fovy, double aspect, double zNerar, double zFar) * fovy:是控制视野子在XY平面的角度,范围是0——180度。视野度数 * aspect:是窗口的纵横比 * zNerar,zFar:分别是近处和远处的裁面位置 * * */ //gl.Perspective(60.0f, (double)Width / (double)Height, 0.01, 100.0); //创建正射投影变换 /* * Ortho(double left, double right, double bottom, double top,double near,double far) * near:近平面距离;far:远平面距离 * near、far 可以认为是Z轴方向上的近裁剪平面和远裁剪平面 * 正射投影的最大特点:无论物体距离相机有多远,投影后的物体大小尺寸不变 * */ /* * 正射投影之后,三角形就被置于这个矩阵长方体(-2,2,-3,3,-2,-5)的视景中了,以后LookAt就是在看这个视影体中的内容, * 如果摄像机的视点设置有超出这个视景体的部分将看不到,相当于被裁剪了 * */ gl.Ortho(-2,2,-3,3,-2,-5); // 视点变换 /* * 视点变换的函数LookAt的原形为: * LookAt(double eyex.double eyey,double eyez,double centerx,double centery,double centerz,double upx,double upy,double upz); * 这个函数是做视点变换用的,你可以认为它是设置摄像机的函数 * 在OpenGL中,默认时视点定位于坐标系的原点,初始方向指向Z轴负方向,前面说过,默认的三维模型也是贴着世界坐标系的Z轴0的深度上 * 放置的,因此,如果不进行视点变换,则摄像机正好贴着物体,什么也看不见。这就是为什么在上一节的代码里面要有一句代码gl.Transkate() * 用于把物体往Z轴负方向移动一定距离的原因 * eyex,eyey, eyez ; 表示摄像机本身位于世界坐标系中的位置 * centerx,centery,centerz ;相当于调整了摄像机目标点的位置 * upx,upy,upz ;相当于在旋转3dmax目标摄像机;这个参数的值并不是角度值,而是向量,数值的大小没意义, * 正负值才有意义。upx,upy只能在上下,左右,45度这几个角度中变换,而且upz取值似乎没什么意义 ; * */ // 透视投影——从后左方看画出的三维三角形 //gl.LookAt(-5, 5, -5, 0, 0, 0, 0, 1, 0); // 透视投影——从正前方看画出的三维三角形 gl.LookAt(0, 0, 1, 0, 0, -10, 0, 1, 0); // 正射投影——gl.Ortho(-2,2,-3,3,-2,-5);LookAt第三个参数eyez要位于Ortho参数near、far(即-2,-5)之间的原因 gl.LookAt(0, 0, -3, 0, 0, -10, 0, 1, 0); // 设置当前矩阵为模型视图矩阵 gl.MatrixMode(OpenGL.GL_MODELVIEW); } // 当前的轮换 //private float rotation = 0.0f; } }