全球彩票平台_全球彩票注册平台|官网下载地址

热门关键词: 全球彩票平台,全球彩票注册平台,全球彩官网下载地址

【全球彩票注册平台】sharpgl学习笔记,矩阵堆栈

SharpGL学习笔记(八) 矩阵仓库和转换的总结例子: 机器人,sharpgl学习笔记

 

咱俩先引加入关贸总协定组织于"矩阵货仓"的官方说法:

OpenGL的矩阵饭店指的正是内部存款和储蓄器中等专门的工作高校门用来寄放矩阵数据的某块特殊区域。
实在,在开创、装入、相乘模型调换和投影调换矩阵时,都已运用货仓操作。一般说来,矩阵客栈常用于组织具有承继性的模型,即由局地大约指标构成的纷纭模型。举例,一辆车子就是由五个轮子、三个三角架及其余一些零部件构成的。它的承继性展今后当车子往前走时,首先是前轮旋转,然后全体车身向前挪动,接着是后轮旋转,然后全数车身向前挪动,如此进行下去,那样自行车就往前走了。
矩阵酒馆对复杂模型运动进程中的八个转移操作之间的牵连与单身十一分利于。因为具备矩阵操作函数如LoadMatrix()、MultMatrix()、LoadIdentity()等只处理当下矩阵或仓库顶端矩阵,那样货仓中下边包车型地铁其余矩阵就不受影响。货仓操作函数有以下七个:
PushMatrix(void);
PopMatrix(void);
率先个函数表示将富有矩阵依次压入旅社中,最上端矩阵是第二个矩阵的备份;压入的矩阵数不能够太多,不然出错。

其次个函数表示弹出货仓顶端的矩阵,令原第三个矩阵成为最上端矩阵,接受当前操作,故原最上端矩阵被损坏;当饭店中仅存四个矩阵时,不可能拓宽弹出操作,不然出错。

通过看出,矩阵旅舍操作与压入矩阵的顺序刚好相反,编制程序时要特别注意矩阵操作的逐条。
为了更加好地领略这两个函数,大家能够形象地认为glPushMatrix()正是“记住本身在哪”,glPopMatrix()正是“重返自身原本所在地”。

本身特目的在于"机器人"的代码里步入这段演示矩阵仓库用法的例证, 让情人们能看得更明亮驾驭一些.

 

下边这段测量试验代码是想让第一个长方体缩放为2*1*1, 沿X轴转45, 第4个长方体缩放为1*1*1,相当于不改变形, 置于第二个长方体的侧边贴着.

 1 public void rtest(ref OpenGL gl, float xPos, float yPos, float zPos)
 2         {
 3             gl.PushMatrix();
 4             {
 5                 gl.Color(1f, 0f, 0f);
 6                 gl.Translate(xPos, yPos, zPos);
 7                 gl.Scale(2f, 1f, 1f);
 8                 gl.Rotate(45, 1f, 0f, 0f);
 9                 DrawCube(ref gl, 0, 0, 0, true);
10             }
11             gl.PopMatrix();
12 
13             gl.PushMatrix();
14             {
15                 gl.Color(0f, 1f, 0f);
16                 gl.Translate(xPos - 2f, yPos, zPos);
17                 DrawCube(ref gl, 0, 0, 0, true);
18             }
19             gl.PopMatrix();
20         }

看来的遵从便是自家想真正想要的.

全球彩票注册平台 1

 

我们修改下代码, 把PushMatrix()和popMatrix()都注释了, 就如上面这样:

 1   public void rtest(ref OpenGL gl, float xPos, float yPos, float zPos)
 2         {
 3             //gl.PushMatrix();
 4             //{
 5                 gl.Color(1f, 0f, 0f);
 6                 gl.Translate(xPos, yPos, zPos);
 7                 gl.Scale(2f, 1f, 1f);
 8                 gl.Rotate(45, 1f, 0f, 0f);
 9                 DrawCube(ref gl, 0, 0, 0, true);
10             //}
11             //gl.PopMatrix();
12 
13             //gl.PushMatrix();
14             //{
15                 gl.Color(0f, 1f, 0f);
16                 gl.Translate(xPos - 2f, yPos, zPos);
17                 DrawCube(ref gl, 0, 0, 0, true);
18             //}
19             //gl.PopMatrix();
20         }

然后结果是如此的:

来得, 第一个DrawCube()受到了上边这个转变操作的影响, 像是持续了地方的极短方体的团团转与缩放同样.

于是, 在那边假如三个DrawCube()操作在其首尾各参与栈出栈作用括起来, 那么那三回DrawCube()就相互独立了四起, 不会互相影响. 

全球彩票注册平台 2

 

最后大家提交多个接纳"转换"的综合性的例子, 它画了贰个小动作能动的机器人, 场景做360度旋转, 能够考查到机器人每一种面.

其一例子改编自 徐明亮的《OpenGL游戏编制程序》那本书里的贰个事例, 原书例子是C 的代码.

先贴出源代码:

 

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Linq;
  7 using System.Text;
  8 using System.Windows.Forms;
  9 using SharpGL;
 10 
 11 namespace SharpGLWinformsApplication1
 12 {
 13     public partial class SharpGLForm : Form
 14     {
 15         public float angle;                  // 机器人绕视点旋转的角度
 16         float[] legAngle = new float[2];     // 腿的当前旋转角度
 17         float[] armAngle = new float[2];     // 胳膊的当前旋转角度
 18 
 19         bool leg1 = true;                    // 机器人腿的状态,true向前,flase向后
 20         bool leg2 = false;
 21         bool arm1 = true;   
 22         bool arm2 = false;
 23 
 24         private float rotation = 0.0f;
 25         public SharpGLForm()
 26         {
 27             InitializeComponent();
 28             angle = 0.0f;                    // 设置初始角度为0
 29             legAngle[0] = legAngle[1] = 0.0f;
 30             armAngle[0] = armAngle[1] = 0.0f;
 31         }
 32 
 33         private void openGLControl_OpenGLDraw(object sender, PaintEventArgs e)
 34         {
 35             OpenGL gl = openGLControl.OpenGL;
 36             gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
 37 
 38             gl.LoadIdentity();
 39             gl.Rotate(rotation, 0.0f, 1.0f, 0.0f);
 40 
 41             drawGrid(gl);
 42             DrawRobot(ref gl, 0, 0, 0);
 43             //rtest(ref gl, 0, 0, 0);
 44             rotation  = 1.0f;
 45         }
 46 
 47 
 48 
 49 
 50         private void openGLControl_OpenGLInitialized(object sender, EventArgs e)
 51         {
 52             OpenGL gl = openGLControl.OpenGL;
 53             gl.ClearColor(0, 0, 0, 0);
 54         }
 55 
 56         private void openGLControl_Resized(object sender, EventArgs e)
 57         {
 58             OpenGL gl = openGLControl.OpenGL;
 59 
 60             gl.MatrixMode(OpenGL.GL_PROJECTION);
 61 
 62             gl.LoadIdentity();
 63             gl.Perspective(60.0f, (double)Width / (double)Height, 0.01, 100.0);
 64             gl.LookAt(-5, 5, 15, 0, 0, 0, 0, 1, 0);
 65             gl.MatrixMode(OpenGL.GL_MODELVIEW);
 66         }
 67 
 68         //测试例子
 69         public void rtest(ref OpenGL gl, float xPos, float yPos, float zPos)
 70         {
 71             gl.PushMatrix();
 72             {
 73                 gl.Color(1f, 0f, 0f);
 74                 gl.Translate(xPos, yPos, zPos);
 75                 gl.Scale(2f, 1f, 1f);
 76                 gl.Rotate(45, 1f, 0f, 0f);
 77                 DrawCube(ref gl, 0, 0, 0, true);
 78             }
 79             gl.PopMatrix();
 80 
 81             gl.PushMatrix();
 82             {
 83                 gl.Color(0f, 1f, 0f);
 84                 gl.Translate(xPos - 2f, yPos, zPos);
 85                 DrawCube(ref gl, 0, 0, 0, true);
 86             }
 87             gl.PopMatrix();
 88         }
 89 
 90 
 91         public void DrawRobot(ref OpenGL Gl, float xPos, float yPos, float zPos)
 92         {
 93             Gl.PushMatrix();
 94             {
 95                 Gl.Translate(xPos, yPos, zPos);
 96 
 97                 ///绘制各个部分
 98                 //Gl.LoadIdentity();
 99                 DrawHead(ref Gl, 1f, 2f, 0f);     // 绘制头部  2*2*2
100                 DrawTorso(ref Gl, 1.5f, 0.0f, 0.0f); //躯干,  3*5*2
101 
102                 Gl.PushMatrix();
103                 {
104                     //如果胳膊正在向前运动,则递增角度,否则递减角度 
105                     if (arm1)
106                         armAngle[0] = armAngle[0]   1f;
107                     else
108                         armAngle[0] = armAngle[0] - 1f;
109 
110                     ///如果胳膊达到其最大角度则改变其状态
111                     if (armAngle[0] >= 15.0f)
112                         arm1 = false;
113                     if (armAngle[0] <= -15.0f)
114                         arm1 = true;
115 
116                     //平移并旋转后绘制胳膊
117                     Gl.Translate(0.0f, -0.5f, 0.0f);
118                     Gl.Rotate(armAngle[0], 1.0f, 0.0f, 0.0f);
119                     DrawArm(ref Gl, 2.5f, 0.0f, -0.5f);  //胳膊1, 1*4*1  
120                 }
121                 Gl.PopMatrix();
122 
123                 Gl.PushMatrix();
124                 {
125                     if (arm2)
126                         armAngle[1] = armAngle[1]   1f;
127                     else
128                         armAngle[1] = armAngle[1] - 1f;
129 
130 
131                     if (armAngle[1] >= 15.0f)
132                         arm2 = false;
133                     if (armAngle[1] <= -15.0f)
134                         arm2 = true;
135 
136 
137                     Gl.Translate(0.0f, -0.5f, 0.0f);
138                     Gl.Rotate(armAngle[1], 1.0f, 0.0f, 0.0f);
139                     DrawArm(ref Gl, -1.5f, 0.0f, -0.5f); //胳膊2, 1*4*1
140                 }
141                 Gl.PopMatrix();
142 
143                 Gl.PushMatrix();
144                 {
145                     ///如果腿正在向前运动,则递增角度,否则递减角度 
146                     if (leg1)
147                         legAngle[0] = legAngle[0]   1f;
148                     else
149                         legAngle[0] = legAngle[0] - 1f;
150 
151                     ///如果腿达到其最大角度则改变其状态
152                     if (legAngle[0] >= 15.0f)
153                         leg1 = false;
154                     if (legAngle[0] <= -15.0f)
155                         leg1 = true;
156 
157                     ///平移并旋转后绘制胳膊
158                     Gl.Translate(0.0f, -0.5f, 0.0f);
159                     Gl.Rotate(legAngle[0], 1.0f, 0.0f, 0.0f);
160                     DrawLeg(ref Gl, -0.5f, -5.0f, -0.5f); //腿部1,1*5*1 
161                 }
162                 Gl.PopMatrix();
163 
164                 Gl.PushMatrix();
165                 {
166                     if (leg2)
167                         legAngle[1] = legAngle[1]   1f;
168                     else
169                         legAngle[1] = legAngle[1] - 1f;
170 
171                     if (legAngle[1] >= 15.0f)
172                         leg2 = false;
173                     if (legAngle[1] <= -15.0f)
174                         leg2 = true;
175 
176                     Gl.Translate(0.0f, -0.5f, 0.0f);
177                     Gl.Rotate(legAngle[1], 1.0f, 0.0f, 0.0f);
178                     DrawLeg(ref Gl, 1.5f, -5.0f, -0.5f); //腿部2, 1*5*1
179                 }
180                 Gl.PopMatrix();
181             }
182             Gl.PopMatrix();
183         }
184 
185         // 绘制一个手臂 
186         void DrawArm(ref OpenGL Gl, float xPos, float yPos, float zPos)
187         {
188             Gl.PushMatrix();
189             Gl.Color(1.0f, 0.0f, 0.0f);    // 红色 
190             Gl.Translate(xPos, yPos, zPos);
191             Gl.Scale(1.0f, 4.0f, 1.0f);        // 手臂是1x4x1的立方体 
192             DrawCube(ref Gl, 0.0f, 0.0f, 0.0f,false);
193             Gl.PopMatrix();
194         }
195 
196         // 绘制一条腿 
197         void DrawLeg(ref OpenGL Gl, float xPos, float yPos, float zPos)
198         {
199             Gl.PushMatrix();
200             Gl.Color(1.0f, 1.0f, 0.0f);    // 黄色 
201             Gl.Translate(xPos, yPos, zPos);
202             Gl.Scale(1.0f, 5.0f, 1.0f);        // 腿是1x5x1长方体 
203             DrawCube(ref Gl, 0.0f, 0.0f, 0.0f,false);
204             Gl.PopMatrix();
205         }
206 
207         // 绘制头部
208         void DrawHead(ref OpenGL Gl, float xPos, float yPos, float zPos)
209         {
210             Gl.PushMatrix();
211             Gl.Color(1.0f, 1.0f, 1.0f);    // 白色 
212             Gl.Translate(xPos, yPos, zPos);
213             Gl.Scale(2.0f, 2.0f, 2.0f);        //头部是 2x2x2长方体
214             DrawCube(ref Gl, 0.0f, 0.0f, 0.0f,false);
215             Gl.PopMatrix();
216         }
217 
218         // 绘制机器人的躯干 
219         void DrawTorso(ref OpenGL Gl, float xPos, float yPos, float zPos)
220         {
221             Gl.PushMatrix();
222             Gl.Color(0.0f, 0.0f, 1.0f);     // 蓝色
223             Gl.Translate(xPos, yPos, zPos);
224             Gl.Scale(3.0f, 5.0f, 2.0f);         // 躯干是3x5x2的长方体 
225             DrawCube(ref Gl, 0.0f, 0.0f, 0.0f,false);
226             Gl.PopMatrix();
227         }
228 
229         void drawGrid(OpenGL gl)
230         {
231             //绘制过程
232             gl.PushAttrib(OpenGL.GL_CURRENT_BIT);  //保存当前属性
233             gl.PushMatrix();                        //压入堆栈
234             gl.Translate(0f, -20f, 0f);
235             gl.Color(0f, 0f, 1f);
236 
237             //在X,Z平面上绘制网格
238             for (float i = -50; i <= 50; i  = 1)
239             {
240                 //绘制线
241                 gl.Begin(OpenGL.GL_LINES);
242                 {
243                     if (i == 0)
244                         gl.Color(0f, 1f, 0f);
245                     else
246                         gl.Color(0f, 0f, 1f);
247 
248                     //X轴方向
249                     gl.Vertex(-50f, 0f, i);
250                     gl.Vertex(50f, 0f, i);
251                     //Z轴方向 
252                     gl.Vertex(i, 0f, -50f);
253                     gl.Vertex(i, 0f, 50f);
254       
255                 }
256                 gl.End();
257             }
258             gl.PopMatrix();
259             gl.PopAttrib();
260         }
261 
262         internal void DrawCube(ref OpenGL Gl, float xPos, float yPos, float zPos,bool isLine)
263         {
264             Gl.PushMatrix();
265             Gl.Translate(xPos, yPos, zPos);
266             if (isLine)
267                 Gl.Begin(OpenGL.GL_LINE_STRIP);
268             else
269                 Gl.Begin(OpenGL.GL_POLYGON);
270 
271             // 顶面
272             Gl.Vertex(0.0f, 0.0f, 0.0f);
273             Gl.Vertex(0.0f, 0.0f, -1.0f);
274             Gl.Vertex(-1.0f, 0.0f, -1.0f);
275             Gl.Vertex(-1.0f, 0.0f, 0.0f);
276 
277             // 前面
278             Gl.Vertex(0.0f, 0.0f, 0.0f);
279             Gl.Vertex(-1.0f, 0.0f, 0.0f);
280             Gl.Vertex(-1.0f, -1.0f, 0.0f);
281             Gl.Vertex(0.0f, -1.0f, 0.0f);
282 
283             // 右面
284             Gl.Vertex(0.0f, 0.0f, 0.0f);
285             Gl.Vertex(0.0f, -1.0f, 0.0f);
286             Gl.Vertex(0.0f, -1.0f, -1.0f);
287             Gl.Vertex(0.0f, 0.0f, -1.0f);
288 
289             // 左面
290             Gl.Vertex(-1.0f, 0.0f, 0.0f);
291             Gl.Vertex(-1.0f, 0.0f, -1.0f);
292             Gl.Vertex(-1.0f, -1.0f, -1.0f);
293             Gl.Vertex(-1.0f, -1.0f, 0.0f);
294 
295             // 底面 
296             Gl.Vertex(0.0f, 0.0f, 0.0f);
297             Gl.Vertex(0.0f, -1.0f, -1.0f);
298             Gl.Vertex(-1.0f, -1.0f, -1.0f);
299             Gl.Vertex(-1.0f, -1.0f, 0.0f);
300 
301 
302             // 后面
303             Gl.Vertex(0.0f, 0.0f, 0.0f);
304             Gl.Vertex(-1.0f, 0.0f, -1.0f);
305             Gl.Vertex(-1.0f, -1.0f, -1.0f);
306             Gl.Vertex(0.0f, -1.0f, -1.0f);
307             Gl.End();
308             Gl.PopMatrix();
309         }
310 
311 
312 
313     }
314 }

本条代码朋友们首要需注意上面七个非常重要:

(1) 机器人的6个部分的坐标为何要取上边这样的值?

因为画每种部分都用了入栈出栈, 因而各类部分都以单身相对于原点来计量的, 总括的时候你还得参照他事他说加以考察  长*高*宽 的音信, 作者已经把它标记到注释里了.

DrawHead(ref Gl, 1f, 2f, 0f);     // 绘制头部  2*2*2
DrawTorso(ref Gl, 1.5f, 0.0f, 0.0f); //躯干,  3*5*2
DrawArm(ref Gl, 2.5f, 0.0f, -0.5f);  //胳膊1, 1*4*1  
DrawArm(ref Gl, -1.5f, 0.0f, -0.5f); //胳膊2, 1*4*1
DrawLeg(ref Gl, -0.5f, -5.0f, -0.5f); //腿部1,1*5*1 
DrawLeg(ref Gl, 1.5f, -5.0f, -0.5f); //腿部2, 1*5*1

(2) 好好体会饭店的操作, 主要在画机器人的函数Draw罗布ot()里.

 

程序运营时截取了一帧,效果如下:

全球彩票注册平台 3

 

 

OpenGL的"转变" 宗旨终于通透到底讲完了! 最先作者接触这个剧情时, 认为术语太多, 枯燥无趣. 但是它是OpenGL真正最基本的入门功夫. 就如 徐明亮在《OpenGL游戏编制程序》那本书里说的: 说完OpenGL转变的知识后, 读者已经有丰裕的底蕴能够起来编写制定游戏了! 

笔者即刻还不快,  就学那一点知识就足以起来写游戏? 那材料灯的亮光呢? 开什么样玩笑?

未来自己就允许这一说法了, 因为"转变"的学识是重视, 请引起朋友们丰裕的偏重, 踏实把它学好! 不要像笔者同样浮澡走弯路!

 

本节源代码下载

 

 原创文章 : 

 

) 矩阵仓库和转换的总结例子: 机器人,sharpgl学习笔记 大家先引加入关贸总协定组织于"矩阵仓库"的法定说法: OpenGL的矩阵商旅指的就是内...

全球彩票注册平台 4

 

2 举例

例1. OpenGL光源岗位的活动

挪动格局: 先pushMatrix()一下,然后在张开活动操作,然后旋转操作,然后钦点光源的职分,然后PopMatrix()一下,就完毕了。

全球彩票注册平台 5全球彩票注册平台 6

#include "windows.h"
#include <gl/glut.h>
static int spin = 0;
void init()
{
glShadeModel( GL_SMOOTH );
glEnable( GL_LIGHTING );
glEnable( GL_LIGHT0 );
glEnable( GL_DEPTH_TEST );
}
void display()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
GLfloat position[] = { 0.0, 0.0, 1.5, 1.0 };
//第一点也是最重要的一点:OpenGL中的模型视图变换矩阵全是右乘当前变换矩阵
glPushMatrix(); //将当前变换矩阵(单位阵)压入堆栈
glTranslatef( 0.0, 0.0, -5.0 ); // transformation 1
glPushMatrix(); //将平移变换后的的矩阵作为当前变换矩阵压入堆栈,
glRotated( (GLdouble)spin, 1.0, 0.0, 0.0 );
glLightfv( GL_LIGHT0, GL_POSITION, position );
glTranslated( 0.0, 0.0, 1.5 );
glDisable( GL_LIGHTING );
glColor3f( 0.0, 1.0, 0.0 );
glutWireCube( 0.1 );//绿色的下框,代表光源位置
glEnable( GL_LIGHTING );
glPopMatrix(); //消除绘制绿色WireCube时对当前变换矩阵的影响
glutSolidSphere( 0.5, 40, 40 );//以被光照的物体
glPopMatrix(); // Pop the old matrix without the transformations. //返回到单位矩阵
glFlush();
}
void reshape( int w, int h )
{
glViewport( 0, 0, (GLsizei)w, (GLsizei)h );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 40.0, (GLfloat)w/(GLfloat)h, 1.0, 20.0 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
}
void mouse( int button, int state, int x, int y )
{
switch ( button )
{
case GLUT_LEFT_BUTTON:
if ( state == GLUT_DOWN )
{
spin = ( spin   30 ) % 360;
glutPostRedisplay();
}
break;
default:
break;
}
}
int main( int argc, char ** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH );
glutInitWindowPosition( 100, 100 );
glutInitWindowSize( 500, 500 );
glutCreateWindow( argv[0] );
init();
glutDisplayFunc( display );
glutReshapeFunc( reshape );
glutMouseFunc( mouse );
glutMainLoop();
return 0;
}

View Code

 

例2 机械手臂的转动

上边例子中的机械手臂是由四个大致的长方体依靠一定的继续关系结合的。glPushMatrix和glPopMatrix之间的转移绝对前三回是独自的

全球彩票注册平台 7全球彩票注册平台 8

#include "windows.h"
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glaux.h>
void myinit(void);
void drawPlane(void);
void CALLBACK elbowAdd (void);
void CALLBACK elbowSubtract (void);
void CALLBACK shoulderAdd (void);
void CALLBACK shoulderSubtract (void);
void CALLBACK display(void);
void CALLBACK myReshape(GLsizei w, GLsizei h);
static int shoulder = 0, elbow = 0;
void CALLBACK elbowAdd (void)
{
elbow = (elbow   5) % 360;
}
void CALLBACK elbowSubtract (void)
{
elbow = (elbow - 5) % 360;
}
void CALLBACK shoulderAdd (void)
{
shoulder = (shoulder   5) % 360;
}
void CALLBACK shoulderSubtract (void)
{
shoulder = (shoulder - 5) % 360;
}
void CALLBACK display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 1.0, 1.0);
glPushMatrix(); // 将此句注释掉后可以发现上一次的变换结果对当前变换有影响,加上了glPushMatrix的目的是让各次变换相互独立。
glTranslatef (-0.5, 0.0, 0.0); // 将旋转后的Wirebox向左移动0.5个单位
glRotatef ((GLfloat) shoulder, 0.0, 0.0, 1.0); //看到shoulder是相对于0的绝对角度,不是基于上一次位置的相对角度。
glTranslatef (1.0, 0.0, 0.0); //Step 1将WireBox向右移动一个单位
// void auxWireBox(GLdouble width,GLdouble height,GLdouble depth)
auxWireBox(2.0, 0.2, 0.5); //这个WireBox以x=1为中心,width=2从该中心开始向两边各延伸1个单位。
glTranslatef (1.0, 0.0, 0.0);
glRotatef ((GLfloat) elbow, 0.0, 0.0, 1.0);
glTranslatef (0.8, 0.0, 0.0);
auxWireBox(1.6, 0.2, 0.5);
glPopMatrix(); // 可以看出glPushMatrix和glPopMatrix之间的变换效果被消除。清除上一次对modelview矩阵的修改。
glFlush();
}
void myinit (void)
{
glShadeModel (GL_FLAT);
}
void CALLBACK myReshape(GLsizei w, GLsizei h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(65.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef (0.0, 0.0, -5.0); /* 认为是viewing transform 不好理解,因此时是物体不动,世界坐标系向z轴正方向移动5个单位,眼睛位于世界坐标系的原点; 此处理解为对模型的变换更加直观既将物体向负z轴移动5个单位。*/
}
void main(void)
{
auxInitDisplayMode (AUX_SINGLE | AUX_RGBA);
auxInitPosition (0, 0, 400, 400);
auxInitWindow ("Composite Modeling Transformations");
myinit ();
auxKeyFunc (AUX_LEFT, shoulderSubtract);
auxKeyFunc (AUX_RIGHT, shoulderAdd);
auxKeyFunc (AUX_UP, elbowAdd);
auxKeyFunc (AUX_DOWN, elbowSubtract);
auxReshapeFunc (myReshape);
auxMainLoop(display);
}

View Code

 

 

 

 

OpenGL坐标转变专项论题(转)

 

 

OpenGL通过相机模拟、可以兑现计算机图形学中最基本的三个维度转变,即几何转变、投影调换、裁剪转换、视口调换等,同期,OpenGL还落实了矩阵货仓等。明白驾驭了有关坐标调换的源委,就算真的走进了白璧无瑕地三维世界。 
一、OpenGL中的三个维度物体的显得 
(一)坐标体系 
在切切实实世界中,全数的实体都具备三Witt征,但Computer本人只可以管理数字,显示二维的图样,将三个维度物体及二维数据联系在一同的并世无双纽带正是坐标。 
为了使被出示的三个维度物体数字化,要在被呈现的实体所在的上空中定义多个坐标系。这么些坐标系的尺寸单位和坐标轴的势头要适合对被出示物体的描述,那些坐标系称为世界坐标系。世界坐标系是一味一直不改变的。 
OpenGL还定义了部分坐标系的概念,所谓局地坐标系,也正是坐标系以物体的着力为坐标原点,物体的团团转或位移等操作都以环绕局地坐标系举行的,这时,当物人体模型型举办旋转或挪动等操作时,局地坐标系也推行相应的团团转或移动操作。供给留心的是,假使对实人体模型型进行缩放操作,则有个别坐标系也要进行对应的 缩放,假诺缩放比例在案各坐标轴上差别,那么再经过旋转操作后,局地坐标轴之间大概不再互相垂直。无论是在世界坐标系中开展转变照旧在有的坐标系中张开转换,程序代码是千篇一律的,只是不一样的坐标系思虑的转移形式各异而已。 
处理器对数字化的展现物体作了加工管理后,要在图片显示屏上海展览中心示,那就要在图纸显示器显示屏上定义一个二维直角坐标系,这几个坐标系称为显示器坐标系。这几个坐标系坐标轴的主旋律普通取成平行于显示器的边缘,坐标原点取在左下角,长度单位常取成一个象素。 
(二)三维物体的照相机模拟 
为了求证在三个维度物体到二维图象之间,须求经过什么样的调换,大家引进了相机(Camera)模拟的点子,假定用相机来拍照这一个世界,那么在照相机的取景器中,就存在人眼和现实世界中间的二个调换进度。

全球彩票注册平台 9 
图一、相机模拟OpenGL中的各样坐标转换

从三维物体到二维图象,就好似用相机拍录一样,经常都要经历以下多少个步骤: 
1、将相机置于三角架上,让它对准三个维度景物,它一定于OpenGL中调治视点的职责,即视点调换(Viewing Transformation)。 
2、将三个维度物体放在场景中的适当位置,它也等于OpenGL中的模型转换(Modeling Transformation),即对模型进行旋转、平移和缩放。 
3、选取相机镜头并调整焦距,使三维物体投影在二维胶片上,它一定于OpenGL中把三维模型投影到二维显示器上的经过,即OpenGL的投影调换(Projection Transformation),OpenGL中投影的法子有二种,即正射投影和透视投影。为了使显示的实体能以适当的岗位、大小和偏侧展现出来,必定要通过投影。有的时候为了出色图形的一有个别,只把图片的某一有的显得出来,那时能够定义一个三个维度视景体(Viewing Volume)。正射投影时一般是一个长方体的视景体,透视投影时一般是八个台式似的视景体。唯有视景体内的实体能被投影在体现平面上,别的部分则不能够。 
4、洗濯底片,决定二维相片的分寸,它一定与OpenGL中的视口转换(Viewport Transformation)(在显示器窗口内足以定义三个矩形,称为视口(Viewport),视景体投影后的图样就在视口内显示)规定荧屏上海展览中心示场景的限制和尺寸。 
由此地方的多少个步骤,七个三个维度空间里的实体就能够用相应的二维平面物体表示了,也就能够在二维的计算机显示器上科学呈现了。总的来讲,三维物体的来得进程如下:

全球彩票注册平台 10 
图二、三个维度物体的显得进程

二、OpenGL中的两种转换  OpenGL中的各类转变是因而矩阵运算实现的,具体的说,正是当发出四个转换命令时,该命令会扭转三个4X4阶的改换矩阵(OpenGL中的物体坐标 一律选用齐次坐标,即(x, y, z, w),故全数调换矩阵都利用4X4矩阵),当前矩阵与那个转变矩阵相乘,从而生成新的此时此刻矩阵。举个例子,对于极端坐标v ,转变命令平时在顶点坐标命令在此以前发生,若当前矩阵为C,调换命令构成的矩阵为M,则发出转变命令后,生成的新的近年来矩阵为CM,那一个矩阵再乘以顶点坐标 v,进而组合新的终点坐标CMv。上述进度表达,程序中绘制顶点前的末段一个改动命令最早成效于极端之上。那同期也验证,OpenGL编制程序中,实际的变换顺序与钦定的逐条是相反的。 
(一)视点转变 
视点转换鲜明了情景中物体的视点地方和可行性,就向上边提到的,它象是 在气象中放置了一架照相机,让相机对准要拍照的物体。确省时,相机(即视点)定位在坐标系的原点(相机开首方向都指向Z负轴),它同物人体模型型的缺省地点是 一致的,显著,假设不进行视点调换,相机和实体是重叠在联合的。 
举行视点转变的下令和实施模型调换的指令是同样的,想一想,在用相机 拍片物体时,咱们得以保证物体的岗位不动,而将相机移离物体,这就一定于视点转换;另外,我们也能够维持相机的定位地点,将物体移离相机,那就相当于模型 转变。那样,在OpenGL中,以逆时针旋转物体就一定于以顺时针旋转相机。由此,咱们必需把视点转变和模型转变结合在联合思索,而对那二种转移单独开展 思量是毫无意义的。 
除去用模子转变命令实行视点调换之外,OpenGL实用库还提供了gluLookAt()函数,该函数有八个变量,分别定义了视点的任务、相机瞄准方向的参谋试的地方以及相机的迈入方向。该函数的原型为:

void gluLookAt(GLdouble eyex,GLdouble eyey,GLdouble eyez,GLdouble centerx,GLdouble centery,GLdouble upx,GLdouble upy,GLdouble upz);

该函数定义了视点矩阵,并用该矩阵乘以当前矩阵。eyex,eyey,eyez定义了视点的岗位;centerx、centery和centerz变量内定了参谋试的地方的任务,该点常常为相机所瞄准的气象大旨轴线上的点;upx、upy、upz变量内定了发展向量的取向。 
常备,视点调换操作在模型转变操作以前发生,以便模型调换先对实体发生功能。场景中物体的终极经过模型转变之后移动到所企盼的岗位,然后再对气象进行视点定位等操作。模型转换和视点转变共同组成模型视景矩阵。 
(二)模型转换 
模型转变是在世界坐标系中开展的。缺省时,物人体模型型的大旨定位在坐标系的主导处。OpenGL在这一个坐标系中,有多少个指令,能够模型转变。 
1、模型平移

glTranslate{fd}(TYPE x,TYPE y,TYPE z);

该函数用内定的x,y,z值沿着x轴、y轴、z轴平移物体(或根据同样的量值移动部分坐标系)。 
2、模型旋转

glRotate{fd}(TYPE angle,TYPE x,TYPE,y,TYPE z);

该函数中首先个变量angle制定模型旋转的角度,单位为度,后四个变量表示以原点(0,0,0)到点(x,y,z)的连线为轴线逆时针转动物体。举例,glRotatef(45.0,0.0,0.0,1.0)的结果是绕z轴旋转45度。 
3、模型缩放

glScale{fd}(TYPE x,TYPE y,TYPE z);

该函数能够对实体沿着x,y,z轴分别进行放大降低。函数中的八个参数分别是x、y、z轴方向的比例转变因子。缺省时都为1.0,即物体没变化。程序中物体Y轴比例为2.0,其他都为1.0,就是说将立方体产生长方体。 
(三)投影调换 
透过模型视景的转移后,场景中的物体放在了所企望的地点上,但鉴于显示器只好用二维图象展现三维物体,因而将要靠投影来裁减维数(投影调换类似于选取相机的镜头)。 
实则,投影转换的指标正是概念八个视景体,使得视景体外剩下的片段裁剪掉,最后踏入图像的只是视景体内的关于部分。投影包罗透视投影(Perspective Projection)和珍重投影(Orthographic Projection)三种。 
透视投影,符合大家心情习贯,即离视点近的实体大,离视点远的物体小,远到极点即为消失,成为灭点。它的视景体类似于三个最上部和尾部都被开展切割过的棱椎,也正是棱台。那一个影子平时用于动画、视觉仿真以及别的众多存有真正面与反面映的下边。 
OpenGL透视投影函数有三个,在那之中等高校函授数glFrustum()的原型为:

void glFrustum(GLdouble left,GLdouble Right,GLdouble bottom,GLdouble top,GLdouble near,GLdouble far);

它制造三个看透视景体。其操作是成立一个看透投影矩阵,并且用这些矩阵乘以当前矩阵。这几个函数的参数只定义近裁剪平面包车型大巴左下角点和右上角点的三维空间坐 标,即(left,bottom,-near)和(right,top,-near);最终三个参数far是远裁剪平面包车型地铁Z负值,其左下角点和右上角点空 间坐标由函数依照透视投影原理自动生成。near和far表示离视点的远近,它们总为正值。该函数产生的视景体如图三所示。

全球彩票注册平台 11 
图三、透视投影视景体

另二个看透函数是:

void gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear, GLdouble zFar);

它也开创一个对称透视视景体,但它的参数定义于前方的两样,参数fovy定义视界在X-Z平面包车型客车角度,范围是[0.0, 180.0];参数aspect是影子平面宽度与中度的比值;参数zNear和Far分别是远近裁剪面沿Z负轴到视点的偏离,它们总为正值。

全球彩票注册平台 12 
图四、透视投影视景体

如上五个函数缺省时,视点都在原点,视界沿Z轴指向负方向。 
正射投影,又叫平行投影。这种投影的视景体是一个矩形的平行管道,也正是一个长方体,如图五所示。正射投影的最大学一年级本本性是无论物体距离相机多少路程,投视后的物体大小尺寸不变。这种投影常常用在建造蓝图绘制和计算机帮助设计等地点,这么些行当须求投歌后的实体尺寸及相互间的角度不改变,以便施工或创设时物体比 例大小精确。

全球彩票注册平台 13 
图五、正射投影视景体

OpenGL正射投影函数也许有三个,四个函数是:

void glOrtho(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top, GLdouble near,GLdouble far)

它创立二个平行视景体。实际上这些函数的操作是创办多个正射投影矩阵,并且用这么些矩阵乘以当前矩阵。其中近裁剪平面是一个矩形,矩形左下角点三个维度空间坐 标是(left,bottom,-near),右上角点是(right,top,-near);远裁剪平面也是一个矩形,左下角点空间坐标是 (left,bottom,-far),右上角点是(right,top,-far)。全部的near和far值相同的时候为正或同期为负。如果未有别的转变, 正射投影的样子平行于Z轴,且视点朝向Z负轴。那意味着实体在视点后边时far和near都为负值,物体在视点后边时far和near都为正在。 
另一个函数是:

void gluOrtho2D(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top)

它是多个新鲜的正射投影函数,首要用来二维图像到二维显示器上的影子。它的near和far缺省值分别为-1.0和1.0,全体二维物体的Z坐标都为0.0。由此它的裁剪面是叁个左下角点为(left,bottom)、右上角点为(right,top)的矩形。

(四)视口调换。 
视口调换就是将视景体内投影的实体展现在二维的视口平面上。运用相机模拟格局,我们很轻松精通视口转换正是类 似于照片的放大与缩短。在微型Computer图形学中,它的概念是将通过几何转变、投影转换和剪裁转换后的实体展现于显示屏窗口内钦命的区域内,那几个区域经常为矩形,称 为视口。OpenGL中相关函数是:

glViewport(GLint x,GLint y,GLsizei width, GLsizei height);

本条函数定义三个视口。函数参数(x, y)是视口在荧屏窗口坐标系中的左下角点坐标,参数width和height分别是视口的宽窄和中度。缺省时,参数值即(0, 0, winWidth, winHeight) 指的是显示屏窗口的莫过于尺寸大小。全部这一个值都以以象素为单位,全为整型数。 
(5)裁剪转换 
在OpenGL中,除了视景体定义的多个裁剪平面(上、下、左、右、前、后)外,客户还可和谐再定义三个或多少个叠合裁剪平面,以去掉场景中非亲非故的对象,如图六所示。

全球彩票注册平台 14 
图六、附加裁剪平面

叠合平面裁剪函数为: 
1、void glClipPlane(GLenum plane,Const GLdouble *equation); 
函数参数equation指向二个独具八个全面值的数组,那八个周密分别是裁剪平面Ax By Cz D=0的A、B、C、D值。因而,由那多个周密就能够鲜明一个裁剪平面。参数plane是GL_CLIP_PLANEi(i=0,1,...),钦点裁剪面号。 
在调用附加裁剪函数在此之前,必须先运营glEnable(GL_CLIP_PLANEi),使妥帖前所定义的剪裁平面有效;当不再调用有个别附加裁剪平面时,可用glDisable(GL_CLIP_PLANEi)关闭相应的增大裁剪功效。 
下面那些例子不仅仅表明了附加裁剪函数的用法,并且调用了gluPerspective()透视投影函数,读者能够细细咀嚼其中的用法。例程如下:

#include "glos.h" 
#include <GL/gl.h> 
#include <GL/glu.h> 
#include <GL/glaux.h> 
void myinit(void); 
void CALLBACK myReshape(GLsizei w, GLsizei h); 
void CALLBACK display(void); 
void CALLBACK display(void) 

GLdouble eqn[4] = {1.0, 0.0, 0.0, 0.0}; 
glClear(GL_COLOR_BUFFER_BIT); 
glColor3f (1.0, 0.0, 1.0); 
glPushMatrix(); 
glTranslatef (0.0, 0.0, -5.0); 
/* clip the left part of wire_sphere : x<0 */ 
glClipPlane (GL_CLIP_PLANE0, eqn); 
glEnable (GL_CLIP_PLANE0); 
glRotatef (-90.0, 1.0, 0.0, 0.0); 
auxWireSphere(1.0); 
glPopMatrix(); 
glFlush(); 

void myinit (void) 

glShadeModel (GL_FLAT); 

void CALLBACK myReshape(GLsizei w, GLsizei h) 

glViewport(0, 0, w, h); 
glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 
   gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0); 
glMatrixMode(GL_MODELVIEW); 

void main(void) 

auxInitDisplayMode (AUX_SINGLE | AUX_RGB); 
auxInitPosition (0, 0, 500, 500); 
auxInitWindow ("Arbitrary Clipping Planes"); 
myinit (); 
auxReshapeFunc (myReshape); 
auxMainLoop(display); 
}

(六)矩阵栈的操作 
在陈诉矩阵栈从前,首先介绍七个基本OpenGL矩阵操作函数: 
1、void glLoadMatrix{fd}(const TYPE *m) 
设置当前矩阵中的成分值。函数参数*m是一个针对性16个因素(m0, m1, ..., m15)的指针,这十四个成分就是前段时间矩阵M中的成分,其排列情势如下: 
M = | m0 m4 m8 m12 | 
| m1 m5 m9 m13 | 
| m2 m6 m10 m14 | 
| m3 m7 m11 M15 | 
2、void glMultMatrix{fd}(const TYPE *m) 
用当下矩阵去乘*m所内定的矩阵,并将结果贮存于*m中。当前矩阵可以是用glLoadMatrix() 钦点的矩阵,也得以是别的矩阵转换函数的汇计算果。 
OpenGL的矩阵货仓指的正是内部存款和储蓄器中等专门的学问学校门用来寄存在矩阵数据的某块特殊区域。一般说来,矩阵货仓常用于组织具备承继性的模子,即由一些回顾目的结合的复 杂模型。矩阵旅舍对复杂模型运动进程中的多少个转移操作之间的调换与独立十一分造福。因为全部矩阵操作函数如glLoadMatrix()、 glMultMatrix()、glLoadIdentity()等只管理当下矩阵或客栈顶上部分矩阵,那样仓库中上边包车型大巴其余矩阵就不受影响。货仓操作函数有 以下七个: 
·void glPushMatrix(void); 
该函数表示将富有矩阵依次压入货仓中,最上部矩阵是第三个矩阵的备份;压入的矩阵数无法太多,不然出错。 
·void glPopMatrix(void); 
该函数表示弹出仓库顶上部分的矩阵,令原第一个矩阵成为最上部矩阵,接受当前操作,故原最上部矩阵被弄坏;当仓库中仅存一个矩阵时,不可能开展弹出操作,不然出错。

因为画每一种部分都用了入栈出栈, 由此各类部分都以独立相对于原点来计量的, 总结的时候你还得参谋  长*高*宽 的音讯, 笔者已经把它标明到注释里了.

本条代码朋友们紧要需注意下边八个关键:

 

原创作品,出自"天涯论坛, 猪悟能'S博客" : 

(1) 机器人的6个部分的坐标为何要取上面那样的值?

glPushMatrix 函数将近年来矩阵货仓推送,通过三个,复制当前矩阵。 那正是后 glPushMatrix 的调用饭馆的顶上部分矩阵是它上边包车型地铁等同的。

以后本人就同意这一说法了, 因为"调换"的文化是关键, 请引起朋友们充分的尊敬, 踏实把它学好! 不要像作者同样浮澡走弯路!

我立马还异常慢,  就学那点知识就足以开首写游戏? 这材料电灯的光呢? 开什么样玩笑?

1. 原理教学

  终于精晓为啥使用glPushMatrix()和glPopMatrix()的缘由了。将本次要求实践的缩放、平移等操作放在glPushMatrix和glPopMatrix之间。glPushMatrix()和glPopMatrix()的杂交使用能够清除上一回的转移对这一次转变的熏陶。使此番调换是以世界坐标系的原点为参谋试的位置举办。下面对上述结论做进一步的表达:

  1)OpenGL中的modelview矩阵转换是三个Marco夫进度:上叁遍的改动结果对此番调换有震慑,上次modelview转变后物体在世界坐标系下的职责是本次modelview转换的起源。暗许时此次调换和上次调换不独立。

  2)OpenGL物体建模实际上是分两步走的。第一步,在世界坐标系的原点地点绘制出该物体;第二步,通过modelview调换矩阵对世界坐标系原点处的实体进行仿射调换,将该物体移动到世界坐标系的靶子地方处。

  3)将modelview转换放在glPushMatrix和glPopMatrix之间能够使此番转换和上次改变独立。

  4)凡是利用glPushMatrix()和glPopMatrix()的前后相继一般可以看清是利用世界坐标系建立模型。既世界坐标系固定,modelview矩阵移动物体。

 

  一般说来,矩阵仓库常用于组织具备继承性的模子,即由一些轻易目的结合的目迷五色模型。比方,一辆自行车正是由多少个车轱辘、壹个三角架及其他一些零件构成的。它的承接性表现在当车子往前走时,首先是前轮旋转,然后全体车身向前移动,接着是后轮旋转,然后全部车身向前移动,如此进行下去,那样自行车就往前走了。将上述模型的构造进程放在glPushMatrix和glPopMatrix之间,则此次小车在世界坐标系中的地方不是根据上贰回小车的地点而付出的(以前三次的岗位为仿照效法),而是直接交给的以世界下的坐标(以世界坐标系的原点为参照)。整个经过是顺应人的思维进度的,由于每一次建立模型都是以单位阵为转变源点,故便于选用统一的兑现格局开展管理。

  矩阵仓库对复杂模型运动进度中的多少个转移操作之间的联系与独立十分福利。因为具有矩阵操作函数如glLoadMatrix()、glMultMatrix()、glLoadIdentity()等只处理当下矩阵或旅馆顶上部分矩阵,那样旅社中下边的别的矩阵就不受影响。饭馆操作函数有以下三个:

  void glPushMatrix(void);

  void glPopMatrix(void);

  第1个函数表示将富有矩阵依次压入货仓中,最上端矩阵是第一个矩阵的备份;压入的矩阵数不能够太多,不然出错。第三个函数表示弹出仓库最上端的矩阵,令原第三个矩阵成为最上端矩阵,接受当前操作,故原最上部矩阵被毁坏;当宾馆中仅存三个矩阵时,无法进行弹出操作,不然出错。因此看出,矩阵旅馆操作与压入矩阵的相继刚好相反,编制程序时要特别注意矩阵操作的一一。为了更加好地领略那多个函数,大家得以形象地以为glPushMatrix()正是“记住自个儿在哪”,glPopMatrix()正是“重临自个儿本来所在地”。

 

 1   public void rtest(ref OpenGL gl, float xPos, float yPos, float zPos)
 2         {
 3             //gl.PushMatrix();
 4             //{
 5                 gl.Color(1f, 0f, 0f);
 6                 gl.Translate(xPos, yPos, zPos);
 7                 gl.Scale(2f, 1f, 1f);
 8                 gl.Rotate(45, 1f, 0f, 0f);
 9                 DrawCube(ref gl, 0, 0, 0, true);
10             //}
11             //gl.PopMatrix();
12 
13             //gl.PushMatrix();
14             //{
15                 gl.Color(0f, 1f, 0f);
16                 gl.Translate(xPos - 2f, yPos, zPos);
17                 DrawCube(ref gl, 0, 0, 0, true);
18             //}
19             //gl.PopMatrix();
20         }

来得, 第四个DrawCube()受到了上面那贰个转变操作的影响, 疑似持续了上边的那多少个长方体的团团转与缩放一样.

转自 百度全面

 

 

 

见到的效果正是自己想真正想要的.

本节源代码下载

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Linq;
  7 using System.Text;
  8 using System.Windows.Forms;
  9 using SharpGL;
 10 
 11 namespace SharpGLWinformsApplication1
 12 {
 13     public partial class SharpGLForm : Form
 14     {
 15         public float angle;                  // 机器人绕视点旋转的角度
 16         float[] legAngle = new float[2];     // 腿的当前旋转角度
 17         float[] armAngle = new float[2];     // 胳膊的当前旋转角度
 18 
 19         bool leg1 = true;                    // 机器人腿的状态,true向前,flase向后
 20         bool leg2 = false;
 21         bool arm1 = true;   
 22         bool arm2 = false;
 23 
 24         private float rotation = 0.0f;
 25         public SharpGLForm()
 26         {
 27             InitializeComponent();
 28             angle = 0.0f;                    // 设置初始角度为0
 29             legAngle[0] = legAngle[1] = 0.0f;
 30             armAngle[0] = armAngle[1] = 0.0f;
 31         }
 32 
 33         private void openGLControl_OpenGLDraw(object sender, PaintEventArgs e)
 34         {
 35             OpenGL gl = openGLControl.OpenGL;
 36             gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
 37 
 38             gl.LoadIdentity();
 39             gl.Rotate(rotation, 0.0f, 1.0f, 0.0f);
 40 
 41             drawGrid(gl);
 42             DrawRobot(ref gl, 0, 0, 0);
 43             //rtest(ref gl, 0, 0, 0);
 44             rotation  = 1.0f;
 45         }
 46 
 47 
 48 
 49 
 50         private void openGLControl_OpenGLInitialized(object sender, EventArgs e)
 51         {
 52             OpenGL gl = openGLControl.OpenGL;
 53             gl.ClearColor(0, 0, 0, 0);
 54         }
 55 
 56         private void openGLControl_Resized(object sender, EventArgs e)
 57         {
 58             OpenGL gl = openGLControl.OpenGL;
 59 
 60             gl.MatrixMode(OpenGL.GL_PROJECTION);
 61 
 62             gl.LoadIdentity();
 63             gl.Perspective(60.0f, (double)Width / (double)Height, 0.01, 100.0);
 64             gl.LookAt(-5, 5, 15, 0, 0, 0, 0, 1, 0);
 65             gl.MatrixMode(OpenGL.GL_MODELVIEW);
 66         }
 67 
 68         //测试例子
 69         public void rtest(ref OpenGL gl, float xPos, float yPos, float zPos)
 70         {
 71             gl.PushMatrix();
 72             {
 73                 gl.Color(1f, 0f, 0f);
 74                 gl.Translate(xPos, yPos, zPos);
 75                 gl.Scale(2f, 1f, 1f);
 76                 gl.Rotate(45, 1f, 0f, 0f);
 77                 DrawCube(ref gl, 0, 0, 0, true);
 78             }
 79             gl.PopMatrix();
 80 
 81             gl.PushMatrix();
 82             {
 83                 gl.Color(0f, 1f, 0f);
 84                 gl.Translate(xPos - 2f, yPos, zPos);
 85                 DrawCube(ref gl, 0, 0, 0, true);
 86             }
 87             gl.PopMatrix();
 88         }
 89 
 90 
 91         public void DrawRobot(ref OpenGL Gl, float xPos, float yPos, float zPos)
 92         {
 93             Gl.PushMatrix();
 94             {
 95                 Gl.Translate(xPos, yPos, zPos);
 96 
 97                 ///绘制各个部分
 98                 //Gl.LoadIdentity();
 99                 DrawHead(ref Gl, 1f, 2f, 0f);     // 绘制头部  2*2*2
100                 DrawTorso(ref Gl, 1.5f, 0.0f, 0.0f); //躯干,  3*5*2
101 
102                 Gl.PushMatrix();
103                 {
104                     //如果胳膊正在向前运动,则递增角度,否则递减角度 
105                     if (arm1)
106                         armAngle[0] = armAngle[0]   1f;
107                     else
108                         armAngle[0] = armAngle[0] - 1f;
109 
110                     ///如果胳膊达到其最大角度则改变其状态
111                     if (armAngle[0] >= 15.0f)
112                         arm1 = false;
113                     if (armAngle[0] <= -15.0f)
114                         arm1 = true;
115 
116                     //平移并旋转后绘制胳膊
117                     Gl.Translate(0.0f, -0.5f, 0.0f);
118                     Gl.Rotate(armAngle[0], 1.0f, 0.0f, 0.0f);
119                     DrawArm(ref Gl, 2.5f, 0.0f, -0.5f);  //胳膊1, 1*4*1  
120                 }
121                 Gl.PopMatrix();
122 
123                 Gl.PushMatrix();
124                 {
125                     if (arm2)
126                         armAngle[1] = armAngle[1]   1f;
127                     else
128                         armAngle[1] = armAngle[1] - 1f;
129 
130 
131                     if (armAngle[1] >= 15.0f)
132                         arm2 = false;
133                     if (armAngle[1] <= -15.0f)
134                         arm2 = true;
135 
136 
137                     Gl.Translate(0.0f, -0.5f, 0.0f);
138                     Gl.Rotate(armAngle[1], 1.0f, 0.0f, 0.0f);
139                     DrawArm(ref Gl, -1.5f, 0.0f, -0.5f); //胳膊2, 1*4*1
140                 }
141                 Gl.PopMatrix();
142 
143                 Gl.PushMatrix();
144                 {
145                     ///如果腿正在向前运动,则递增角度,否则递减角度 
146                     if (leg1)
147                         legAngle[0] = legAngle[0]   1f;
148                     else
149                         legAngle[0] = legAngle[0] - 1f;
150 
151                     ///如果腿达到其最大角度则改变其状态
152                     if (legAngle[0] >= 15.0f)
153                         leg1 = false;
154                     if (legAngle[0] <= -15.0f)
155                         leg1 = true;
156 
157                     ///平移并旋转后绘制胳膊
158                     Gl.Translate(0.0f, -0.5f, 0.0f);
159                     Gl.Rotate(legAngle[0], 1.0f, 0.0f, 0.0f);
160                     DrawLeg(ref Gl, -0.5f, -5.0f, -0.5f); //腿部1,1*5*1 
161                 }
162                 Gl.PopMatrix();
163 
164                 Gl.PushMatrix();
165                 {
166                     if (leg2)
167                         legAngle[1] = legAngle[1]   1f;
168                     else
169                         legAngle[1] = legAngle[1] - 1f;
170 
171                     if (legAngle[1] >= 15.0f)
172                         leg2 = false;
173                     if (legAngle[1] <= -15.0f)
174                         leg2 = true;
175 
176                     Gl.Translate(0.0f, -0.5f, 0.0f);
177                     Gl.Rotate(legAngle[1], 1.0f, 0.0f, 0.0f);
178                     DrawLeg(ref Gl, 1.5f, -5.0f, -0.5f); //腿部2, 1*5*1
179                 }
180                 Gl.PopMatrix();
181             }
182             Gl.PopMatrix();
183         }
184 
185         // 绘制一个手臂 
186         void DrawArm(ref OpenGL Gl, float xPos, float yPos, float zPos)
187         {
188             Gl.PushMatrix();
189             Gl.Color(1.0f, 0.0f, 0.0f);    // 红色 
190             Gl.Translate(xPos, yPos, zPos);
191             Gl.Scale(1.0f, 4.0f, 1.0f);        // 手臂是1x4x1的立方体 
192             DrawCube(ref Gl, 0.0f, 0.0f, 0.0f,false);
193             Gl.PopMatrix();
194         }
195 
196         // 绘制一条腿 
197         void DrawLeg(ref OpenGL Gl, float xPos, float yPos, float zPos)
198         {
199             Gl.PushMatrix();
200             Gl.Color(1.0f, 1.0f, 0.0f);    // 黄色 
201             Gl.Translate(xPos, yPos, zPos);
202             Gl.Scale(1.0f, 5.0f, 1.0f);        // 腿是1x5x1长方体 
203             DrawCube(ref Gl, 0.0f, 0.0f, 0.0f,false);
204             Gl.PopMatrix();
205         }
206 
207         // 绘制头部
208         void DrawHead(ref OpenGL Gl, float xPos, float yPos, float zPos)
209         {
210             Gl.PushMatrix();
211             Gl.Color(1.0f, 1.0f, 1.0f);    // 白色 
212             Gl.Translate(xPos, yPos, zPos);
213             Gl.Scale(2.0f, 2.0f, 2.0f);        //头部是 2x2x2长方体
214             DrawCube(ref Gl, 0.0f, 0.0f, 0.0f,false);
215             Gl.PopMatrix();
216         }
217 
218         // 绘制机器人的躯干 
219         void DrawTorso(ref OpenGL Gl, float xPos, float yPos, float zPos)
220         {
221             Gl.PushMatrix();
222             Gl.Color(0.0f, 0.0f, 1.0f);     // 蓝色
223             Gl.Translate(xPos, yPos, zPos);
224             Gl.Scale(3.0f, 5.0f, 2.0f);         // 躯干是3x5x2的长方体 
225             DrawCube(ref Gl, 0.0f, 0.0f, 0.0f,false);
226             Gl.PopMatrix();
227         }
228 
229         void drawGrid(OpenGL gl)
230         {
231             //绘制过程
232             gl.PushAttrib(OpenGL.GL_CURRENT_BIT);  //保存当前属性
233             gl.PushMatrix();                        //压入堆栈
234             gl.Translate(0f, -20f, 0f);
235             gl.Color(0f, 0f, 1f);
236 
237             //在X,Z平面上绘制网格
238             for (float i = -50; i <= 50; i  = 1)
239             {
240                 //绘制线
241                 gl.Begin(OpenGL.GL_LINES);
242                 {
243                     if (i == 0)
244                         gl.Color(0f, 1f, 0f);
245                     else
246                         gl.Color(0f, 0f, 1f);
247 
248                     //X轴方向
249                     gl.Vertex(-50f, 0f, i);
250                     gl.Vertex(50f, 0f, i);
251                     //Z轴方向 
252                     gl.Vertex(i, 0f, -50f);
253                     gl.Vertex(i, 0f, 50f);
254       
255                 }
256                 gl.End();
257             }
258             gl.PopMatrix();
259             gl.PopAttrib();
260         }
261 
262         internal void DrawCube(ref OpenGL Gl, float xPos, float yPos, float zPos,bool isLine)
263         {
264             Gl.PushMatrix();
265             Gl.Translate(xPos, yPos, zPos);
266             if (isLine)
267                 Gl.Begin(OpenGL.GL_LINE_STRIP);
268             else
269                 Gl.Begin(OpenGL.GL_POLYGON);
270 
271             // 顶面
272             Gl.Vertex(0.0f, 0.0f, 0.0f);
273             Gl.Vertex(0.0f, 0.0f, -1.0f);
274             Gl.Vertex(-1.0f, 0.0f, -1.0f);
275             Gl.Vertex(-1.0f, 0.0f, 0.0f);
276 
277             // 前面
278             Gl.Vertex(0.0f, 0.0f, 0.0f);
279             Gl.Vertex(-1.0f, 0.0f, 0.0f);
280             Gl.Vertex(-1.0f, -1.0f, 0.0f);
281             Gl.Vertex(0.0f, -1.0f, 0.0f);
282 
283             // 右面
284             Gl.Vertex(0.0f, 0.0f, 0.0f);
285             Gl.Vertex(0.0f, -1.0f, 0.0f);
286             Gl.Vertex(0.0f, -1.0f, -1.0f);
287             Gl.Vertex(0.0f, 0.0f, -1.0f);
288 
289             // 左面
290             Gl.Vertex(-1.0f, 0.0f, 0.0f);
291             Gl.Vertex(-1.0f, 0.0f, -1.0f);
292             Gl.Vertex(-1.0f, -1.0f, -1.0f);
293             Gl.Vertex(-1.0f, -1.0f, 0.0f);
294 
295             // 底面 
296             Gl.Vertex(0.0f, 0.0f, 0.0f);
297             Gl.Vertex(0.0f, -1.0f, -1.0f);
298             Gl.Vertex(-1.0f, -1.0f, -1.0f);
299             Gl.Vertex(-1.0f, -1.0f, 0.0f);
300 
301 
302             // 后面
303             Gl.Vertex(0.0f, 0.0f, 0.0f);
304             Gl.Vertex(-1.0f, 0.0f, -1.0f);
305             Gl.Vertex(-1.0f, -1.0f, -1.0f);
306             Gl.Vertex(0.0f, -1.0f, -1.0f);
307             Gl.End();
308             Gl.PopMatrix();
309         }
310 
311 
312 
313     }
314 }

 

OpenGL的"转换" 核心终于深透讲完了! 最早笔者接触这几个剧情时, 感觉术语太多, 枯燥无趣. 不过它是OpenGL真正最中央的入门武功. 如同 徐明亮在《OpenGL游戏编制程序》那本书里说的: 说完OpenGL调换的知识后, 读者已经有丰盛的基础能够最初编制游戏了! 

未来本身就允许这一说法了, 因为"转换"的知识是至关心注重要, 请引起朋友们丰富的强调, 踏实把它学好! 不要像小编同样浮澡走弯路!

本文由全球彩票平台发布于全球彩票注册平台编程,转载请注明出处:【全球彩票注册平台】sharpgl学习笔记,矩阵堆栈

TAG标签: 全球彩票平台
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。