三、SharpGL的功能应用--图形绘制

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

三、SharpGL的功能应⽤--图形绘制
三、SharpGL的功能应⽤--图形绘制 
本节主要讲诉图形绘制的原理,使⽤介绍和代码演⽰。

原理介绍
我们先来讲讲OpenGL的图形绘制。

其实,所有的图形都是由许多个⼩图形连接⽽成的。

你可以理解为是图⽚的像素,⼀张彩图是由很多个⾊彩不⼀的像素点组合⽽成。

要实现⾊彩绚丽的图形设计,你需要理解两点成线,三点成⾯,多⾯成形的原理。

在这⾥,我们通过简单的程序演⽰⼀下点到线,线到⾯,⾯到形的过程。

在此,先介绍⼀下⼏个常⽤的函数和绘制原理。

1. 坐标原点变换:Translate(float x, float y, float z) ,你也可以理解为是坐标轴变换。

默认设定的视⾓和世界坐标都是在同个原点,打个⽐⽅:我们看⼿机,假设⼿机是原点,我们视⾓默认也是原点的话,我们脑壳都得钻⼿机⾥⾯。

对吧,我们不这么看⼿机,基本都是把⼿机拉远,以⼀种舒服的⾓度进⾏操作,这就是在物品的变换了。

所以我们,在绘制图形前最好设定合适的坐标轴位置,同时也需要考虑视点变换的设置值。

我们输⼊图形的坐标仍是按照原点来输⼊的,不会受到Translate的影响;他影响的只是整体的坐标轴变换,他的值是不需要做改变的。

当然了,你也可以直接全部修改图形的坐标值,不过这样就太⿇烦了,没必要;直接修改初始化的视⾓变换值也是可以的。

2. 绘制点,线,⾯的⽅式:以Begin(BeginMode mode)为⾸开始绘制mode类型的图形,Vertex(float x, float y, float z)为图形顶点,依次连接各个顶点形成图形,以End()结束绘制。

理论上来说,只要你给出图形的所有顶点,⽜⿁蛇神都给你搞出来,⼀点问题也没有(除了可能会卡之外)。

以画线为例:
gl.Begin(OpenGL.GL_LINES);
gl.Vertex(-1.0f, 0.0f, 0.0f);
gl.Vertex(1.0f, 0.0f, 0.0f);
gl.End();
3. 赋予颜⾊:Color(float red, float green, float blue)
在每个图形顶点前加上设定颜⾊,图形的绘制选择就更加多样;同时,不同顶点间采⽤不同的颜⾊会产⽣渐变⾊差,⾮常好看。

演⽰代码
我们先添加⼀个坐标系变化,然后。

选择绘制⼀条线,接着绘制⼀个三⾓形,最后绘制⼀个⾓锥。

这就是由点到线,线到⾯,⾯到形的过程,所有的图形都是这样组合衔接⽽来的。

1.⾸先,画⼀条线,颜⾊设定为⽩⾊(背景是⿊⾊)
#region点到线
gl.Begin(OpenGL.GL_LINES);
gl.Color(1.0f, 1.0f, 1.0f);
gl.Vertex(-2.0f, 0.0f, 0.0f);//左顶点
gl.Vertex(2.0f, 2.0f, 0.0f);//右顶点
gl.End();
#endregion
2.接着,来画个⾯,再稍微加点颜⾊变化
#region线成⾯(三⾓形)
gl.Begin(OpenGL.GL_TRIANGLES);//第⼀个⾯
gl.Color(1.0f, 0.0f, 0.0f);
gl.Vertex(0.0f, 1f, 0.0f);//顶点
gl.Color(0.0f, 1.0f, 0.0f);
gl.Vertex(-1.0f, -1.0f, 0.0f);//左顶点
gl.Color(0.0f, 0.0f, 1.0f);
gl.Vertex(1.0f, -1.0f, 0.0f);//右顶点
gl.End();
#endregion
3.接着,来画个⾓锥,第四个点颜⾊选择⽩⾊区分开。

⾓锥也就是由四个⾯组合⽽成的,所以我们再加上三个⾯(注意每个点坐标和对应颜⾊要相同)
#region⾯组合成体
gl.Begin(OpenGL.GL_TRIANGLES);//第⼆个⾯
gl.Color(1.0f, 1.0f, 1.0f);
gl.Vertex(0.0f, 0.0f, -2.0f);//第四个点
gl.Color(0.0f, 1.0f, 0.0f);
gl.Vertex(-1.0f, -1.0f, 0.0f);//左顶点
gl.Color(0.0f, 0.0f, 1.0f);
gl.Vertex(1.0f, -1.0f, 0.0f);//右顶点
gl.End();
gl.Begin(OpenGL.GL_TRIANGLES);//第三个⾯
gl.Color(1.0f, 1.0f, 1.0f);
gl.Vertex(0.0f, 0.0f, -2.0f);//第四个点
gl.Color(0.0f, 1.0f, 0.0f);
gl.Vertex(-1.0f, -1.0f, 0.0f);//左顶点
gl.Color(1.0f, 0.0f, 0.0f);
gl.Vertex(0.0f, 1f, 0.0f);//顶点
gl.End();
gl.Begin(OpenGL.GL_TRIANGLES);//第四个⾯
gl.Color(1.0f, 1.0f, 1.0f);
gl.Vertex(0.0f, 0.0f, -2.0f);//第四个点
gl.Color(0.0f, 0.0f, 1.0f);
gl.Vertex(1.0f, -1.0f, 0.0f);//右顶点
gl.Color(1.0f, 0.0f, 0.0f);
gl.Vertex(0.0f, 1f, 0.0f);//顶点
gl.End();
#endregion
我们会发现,界⾯没什么变化。

嗯,⼤伙看看我们的第四个顶点在哪⾥。

坐标(0,0,-2),相对于其他四个点,他的位置是靠⾥⾯的。

因为我们此时的视⾓是在正值的。

额,对了,还得说说视⾓的事,视⾓受到初始化设置的视点变换设置。

// 设置当前矩阵模式,对投影矩阵应⽤随后的矩阵操作
gl.MatrixMode(OpenGL.GL_PROJECTION);
// 创建透视投影变换
gl.Perspective(30.0f, (double)Width / (double)Height, 5, 100.0);
// 视点变换
gl.LookAt(0, 5, 0, 0, 0, 0, 0, 1, 0);
//此时的视⾓在这⾥,可以理解为是坐标点(0,5,0)往空间原点处看
程序的前端添加了Translate(0.0f, 0.0f, -5.0f) ,相当于把绘制的图形往屏幕内移动。

这样会有利于我们查看图形。

(Z轴的话法线是垂直屏幕往外的)
说回正题,第四个顶点是在已经画好的三⾓形的⾥⾯,所以我们看不到,那我们就稍微的旋转⼀下看看效果,如下图所⽰。

附上代码:
using System;
using System.Collections.Generic;
using ponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using SharpGL;
namespace test
{
public partial class Form1 : Form
{
private bool drawLine = false;
private bool drawArea = false;
private bool drawVolume = false;
private bool flagRotateX = false;
private bool flagRotateY = false;
private bool flagRotateZ = false;
private float rotation_X = 0.0f;
private float rotation_Y = 0.0f;
private float rotation_Z = 0.0f;
public Form1()
{
InitializeComponent();
}
private void openGLControl1_OpenGLDraw(object sender, RenderEventArgs args)
{
SharpGL.OpenGL gl = this.openGLControl1.OpenGL;
//清除深度缓存
gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
//重置当前指定的矩阵为单位矩阵,将当前的⽤户坐标系的原点移到了屏幕中⼼
gl.LoadIdentity();
//坐标轴变换位置到(0.0f, 0.0f, -5.0f),这样我们的坐标轴就相当于往屏幕内⾛5个单位
gl.Translate(0.0f, 0.0f, -5.0f);
if (flagRotateX)
{
rotation_X += 1f;
gl.Rotate(rotation_X, 1.0f, 0.0f, 0.0f);//rotationX:⾓度
}
if (flagRotateY)
{
rotation_Y += 1f;
gl.Rotate(rotation_Y, 0.0f, 1.0f, 0.0f);//rotationY:⾓度
}
if (flagRotateZ)
{
rotation_Z += 1f;
gl.Rotate(rotation_Z, 0.0f, 0.0f, 1.0f);//rotationZ:⾓度
}
if (drawLine)
{
#region点到线
gl.Begin(OpenGL.GL_LINES);
gl.Color(1.0f, 1.0f, 1.0f);
gl.Vertex(-2.0f, 0.0f, 0.0f);//左顶点
gl.Vertex(2.0f, 2.0f, 0.0f);//右顶点
gl.End();
#endregion
}
if (drawArea)
{
#region线成⾯(三⾓形)
gl.Begin(OpenGL.GL_TRIANGLES);//第⼀个⾯
gl.Color(1.0f, 0.0f, 0.0f);
gl.Vertex(0.0f, 1f, 0.0f);//顶点
gl.Color(0.0f, 1.0f, 0.0f);
gl.Vertex(-1.0f, -1.0f, 0.0f);//左顶点
gl.Color(0.0f, 0.0f, 1.0f);
gl.Vertex(1.0f, -1.0f, 0.0f);//右顶点
gl.End();
#endregion
}
if (drawVolume)
{
#region⾯组合成体
gl.Begin(OpenGL.GL_TRIANGLES);//第⼆个⾯
gl.Color(1.0f, 1.0f, 1.0f);
gl.Vertex(0.0f, 0.0f, -2.0f);//第四个点
gl.Color(0.0f, 1.0f, 0.0f);
gl.Vertex(-1.0f, -1.0f, 0.0f);//左顶点
gl.Color(0.0f, 0.0f, 1.0f);
gl.Vertex(1.0f, -1.0f, 0.0f);//右顶点
gl.End();
gl.Begin(OpenGL.GL_TRIANGLES);//第三个⾯
gl.Color(1.0f, 1.0f, 1.0f);
gl.Vertex(0.0f, 0.0f, -2.0f);//第四个点
gl.Color(0.0f, 1.0f, 0.0f);
gl.Vertex(-1.0f, -1.0f, 0.0f);//左顶点
gl.Color(1.0f, 0.0f, 0.0f);
gl.Vertex(0.0f, 1f, 0.0f);//顶点
gl.End();
gl.Begin(OpenGL.GL_TRIANGLES);//第四个⾯
gl.Color(1.0f, 1.0f, 1.0f);
gl.Vertex(0.0f, 0.0f, -2.0f);//第四个点
gl.Color(0.0f, 0.0f, 1.0f);
gl.Vertex(1.0f, -1.0f, 0.0f);//右顶点
gl.Color(1.0f, 0.0f, 0.0f);
gl.Vertex(0.0f, 1f, 0.0f);//顶点
gl.End();
#endregion
}
gl.Flush(); //强制刷新
}
private void openGLControl1_OpenGLInitialized(object sender, EventArgs e)
{
OpenGL gl = openGLControl1.OpenGL;
gl.ClearColor(0, 0, 0, 0);
}
private void openGLControl1_Resize(object sender, EventArgs e)
{
OpenGL gl = openGLControl1.OpenGL;
// 设置当前矩阵模式,对投影矩阵应⽤随后的矩阵操作
gl.MatrixMode(OpenGL.GL_PROJECTION);
// 重置当前指定的矩阵为单位矩阵,将当前的⽤户坐标系的原点移到了屏幕中⼼ gl.LoadIdentity();
// 创建透视投影变换
gl.Perspective(30.0f, (double)Width / (double)Height, 5, 100.0);
// 视点变换
gl.LookAt(0, 5, 0, 0, 0, 0, 0, 1, 0);
// 设置当前矩阵为模型视图矩阵
gl.MatrixMode(OpenGL.GL_MODELVIEW);
}
private void checkBoxDrawLine_CheckedChanged(object sender, EventArgs e)
{
drawLine = this.checkBoxDrawLine.Checked;
}
private void checkBoxDrawArea_CheckedChanged(object sender, EventArgs e) {
drawArea = this.checkBoxDrawArea.Checked;
}
private void checkBoxDrawVolume_CheckedChanged(object sender, EventArgs e) {
drawVolume = this.checkBoxDrawVolume.Checked;
}
private void checkBoxRotateX_CheckedChanged(object sender, EventArgs e)
{
flagRotateX = this.checkBoxRotateX.Checked;
}
private void checkBoxRotateY_CheckedChanged(object sender, EventArgs e)
{
flagRotateY = this.checkBoxRotateY.Checked;
}
private void checkBoxRotateZ_CheckedChanged(object sender, EventArgs e)
{
flagRotateZ = this.checkBoxRotateZ.Checked;
}
}
}。

相关文档
最新文档