namespace sharpGLTest06
{
public partial class SharpGLForm : Form
{
public SharpGLForm()
{
InitializeComponent();
}
private void openGLControl_OpenGLDraw(object sender, RenderEventArgs e)
{
OpenGL gl = openGLControl.OpenGL;
gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
gl.LoadIdentity();
double[] eqn = new double[4] { 1f, 0f, 1f, 0f };
//白色
gl.Color(1.0, 1.0, 1.0);
//建立模型堆栈,将当前位置保存起来(入栈)
/* 详解
* 当你做一些移动或旋转等变换后,使用glPushMatrix(),OpenGL会把这个变换后的位置和角度保存起来;
* 然后你再随便坐第二次移动或旋转变换,再用glPopMatrix(),OpenGL就会把刚刚保存的那个位置和角度恢复;
* 消除上一次变换对本次变换的影响
* */
gl.PushMatrix();
{
gl.Translate(2, -2, -3);
gl.Rotate(-90.0, 1.0, 0.0, 0.0);
drawSphere(gl);
}
// 将保存的位置放出(出栈)
gl.PopMatrix();
gl.PushMatrix();
{
// 定义一个裁剪平面
/*
* ClipPlane(OpenGL.GL_CLIP_PLANE0, double[] equation);
* equation 是一个拥有4个系数的数组,它定义一个裁剪平面。equation参数指向平面方程 Ax+By+Cz+D=0 的4个系数
* equation=(0,-1,0,0),前三个参数(0,-1,0)可以理解为法线向下,只有向下的,即Y<0的才能显示,最后一个参数0表示从
* z=0平面开始。这样就是裁剪掉上半平面。
* 相应的
* equation=(0,1,0,0)表示裁剪掉下半平面
* equation=(1,0,0,0)表示裁剪掉左半平面
* equation=(-1,0,0,0)表示裁剪掉右半平面
* equation=(0,0,-1,0)表示裁剪掉前半平面
* equation=(0,0,1,0)表示裁剪掉后半平面
* */
gl.ClipPlane(OpenGL.GL_CLIP_PLANE0, eqn);
gl.Enable(OpenGL.GL_CLIP_PLANE0);
drawGrid(gl);
}
gl.PopMatrix();
gl.Flush();
}
//曲面绘制
void drawSphere(OpenGL gl)
{
//画二次曲面球体绘制过程
gl.PushMatrix();
gl.Translate(2f, 1f, 2f);
//绘制二次曲面
var sphere = gl.NewQuadric();
//设置二次却面绘制风格。gluQuadricDrawStyle。一般都是选用GLU_FILL风格,采用多边形来模拟
gl.QuadricDrawStyle(sphere, OpenGL.GLU_LINE);
//设置法线风格。gluQuadricNormals。一般都是使用GLU_SMOOTH风格,对每个顶点都计算法线向量,是默认方式
gl.QuadricNormals(sphere, OpenGL.GLU_SMOOTH);
//设置二次曲面的绘制方向。gluQuadricOrientation。一般使用GLU_OUTSIDE, 按照所有的法线都指向外面的方式绘制。是默认方式
gl.QuadricOrientation(sphere, (int)OpenGL.GLU_OUTSIDE);
//设置纹理。gluQuadricTexture。设置是否自动计算纹理。默认是GLU_FALSE。当需要使用纹理时应修改为GLU_TRUE.
gl.QuadricTexture(sphere, (int)OpenGL.GLU_FALSE);
gl.Sphere(sphere, 3f, 20, 10);
gl.DeleteQuadric(sphere);
gl.PopMatrix();
}
void drawGrid(OpenGL gl)
{
//绘制栅格线过程
gl.PushAttrib(OpenGL.GL_CURRENT_BIT); //保存当前属性
gl.PushMatrix(); //压入堆栈
gl.Translate(0f, 0f, 0f);
gl.Color(0f, 0f, 1f);
//在X,Z平面上绘制网格
for (float i = -50; i <= 50; i += 1)
{
//绘制线
gl.Begin(OpenGL.GL_LINES);
//X轴方向
gl.Vertex(-50f, 0f, i);
gl.Vertex(50f, 0f, i);
//Z轴方向
gl.Vertex(i, 0f, -50f);
gl.Vertex(i, 0f, 50f);
gl.End();
}
gl.PopMatrix();
gl.PopAttrib();
}
private void openGLControl_OpenGLInitialized(object sender, EventArgs e)
{
OpenGL gl = openGLControl.OpenGL;
gl.ClearColor(0, 0, 0, 0);
}
private void openGLControl_Resized(object sender, EventArgs e)
{
OpenGL gl = openGLControl.OpenGL;
gl.MatrixMode(OpenGL.GL_PROJECTION);
gl.LoadIdentity();
gl.Perspective(60.0f, (double)Width / (double)Height, 0.01, 100.0);
gl.LookAt(0, 5, 10, 0, 0, 0, 0, 1, 0);
gl.MatrixMode(OpenGL.GL_MODELVIEW);
}
}
}