C#+OpenGL编程之OpenGL 变换(机器人)

本文深入探讨了使用C#和OpenGL进行三维图形编程,通过修改基础场景,实现了机器人各部分(如头部、躯干、手臂、腿)的动态变换,包括旋转角度的调整与状态变化,展示了一种将编程理论应用于实际图形创作的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  本文基础:C#+OpenGL编程之环境搭建


  原书第三章使用了一个机器人完成变换。

  正如基础教程所述,我们现在使用C# 继承来修改基础场景。

  

using System;
using System.Collections.Generic;
using System.Text;
using Tao.Glfw;
using Tao.OpenGl;

namespace OpenGL
{
    /// <summary>
    /// 第三章 OpenGL 变换 C# by 大师♂罗莊
    /// </summary>
    class Root : Examplefirst
    {
        float angle;            /**< 机器人绕视点旋转的角度 */
        float[] legAngle = new float[2];		/**< 腿的当前旋转角度 */
        float[] armAngle = new float[2];      /**< 胳膊的当前旋转角度 */

        bool leg1 = true;		/**< 机器人腿的状态,true向前,flase向后 */
        bool leg2 = false;

        bool arm1 = true;
        bool arm2 = false;

        public Root()
            : base()
        {
            
            base.title = "第三章 OpenGL 变换";
            angle = 0.0f;                    /**< 设置初始角度为0 */
            legAngle[0] = legAngle[1] = 0.0f;
            armAngle[0] = armAngle[1] = 0.0f;
        }


       internal void DrawCube(float xPos, float yPos, float zPos)
        {
            Gl.glPushMatrix();
            Gl.glTranslatef(xPos, yPos, zPos);
            Gl.glBegin(Gl.GL_POLYGON);

            /** 顶面 */
            Gl.glVertex3f(0.0f, 0.0f, 0.0f);
            Gl.glVertex3f(0.0f, 0.0f, -1.0f);
            Gl.glVertex3f(-1.0f, 0.0f, -1.0f);
            Gl.glVertex3f(-1.0f, 0.0f, 0.0f);

            /** 前面 */
            Gl.glVertex3f(0.0f, 0.0f, 0.0f);
            Gl.glVertex3f(-1.0f, 0.0f, 0.0f);
            Gl.glVertex3f(-1.0f, -1.0f, 0.0f);
            Gl.glVertex3f(0.0f, -1.0f, 0.0f);

            /** 右面 */
            Gl.glVertex3f(0.0f, 0.0f, 0.0f);
            Gl.glVertex3f(0.0f, -1.0f, 0.0f);
            Gl.glVertex3f(0.0f, -1.0f, -1.0f);
            Gl.glVertex3f(0.0f, 0.0f, -1.0f);

            /** 左面*/
            Gl.glVertex3f(-1.0f, 0.0f, 0.0f);
            Gl.glVertex3f(-1.0f, 0.0f, -1.0f);
            Gl.glVertex3f(-1.0f, -1.0f, -1.0f);
            Gl.glVertex3f(-1.0f, -1.0f, 0.0f);

            /** 底面 */
            Gl.glVertex3f(0.0f, 0.0f, 0.0f);
            Gl.glVertex3f(0.0f, -1.0f, -1.0f);
            Gl.glVertex3f(-1.0f, -1.0f, -1.0f);
            Gl.glVertex3f(-1.0f, -1.0f, 0.0f);


            /** 后面 */
            Gl.glVertex3f(0.0f, 0.0f, 0.0f);
            Gl.glVertex3f(-1.0f, 0.0f, -1.0f);
            Gl.glVertex3f(-1.0f, -1.0f, -1.0f);
            Gl.glVertex3f(0.0f, -1.0f, -1.0f);
            Gl.glEnd();
            Gl.glPopMatrix();
        }

        /** 绘制一个手臂 */
        void DrawArm(float xPos, float yPos, float zPos)
        {
            Gl.glPushMatrix();
            Gl.glColor3f(1.0f, 0.0f, 0.0f);    /**< 红色 */
            Gl.glTranslatef(xPos, yPos, zPos);
            Gl.glScalef(1.0f, 4.0f, 1.0f);	    /**< 手臂是1x4x1的立方体 */
            DrawCube(0.0f, 0.0f, 0.0f);
            Gl.glPopMatrix();
        }

        /** 绘制头部 */
        void DrawHead(float xPos, float yPos, float zPos)
        {
            Gl.glPushMatrix();
            Gl.glColor3f(1.0f, 1.0f, 1.0f);	/**< 白色 */
            Gl.glTranslatef(xPos, yPos, zPos);
            Gl.glScalef(2.0f, 2.0f, 2.0f);		/**<头部是 2x2x2长方体 */
            DrawCube(0.0f, 0.0f, 0.0f);
            Gl.glPopMatrix();
        }

        /** 绘制机器人的躯干 */
        void DrawTorso(float xPos, float yPos, float zPos)
        {
            Gl.glPushMatrix();
            Gl.glColor3f(0.0f, 0.0f, 1.0f);	 /**< 蓝色 */
            Gl.glTranslatef(xPos, yPos, zPos);
            Gl.glScalef(3.0f, 5.0f, 2.0f);	     /**< 躯干是3x5x2的长方体 */
            DrawCube(0.0f, 0.0f, 0.0f);
            Gl.glPopMatrix();
        }

        /** 绘制一条腿 */
        void DrawLeg(float xPos, float yPos, float zPos)
        {
            Gl.glPushMatrix();
            Gl.glColor3f(1.0f, 1.0f, 0.0f);	/**< 黄色 */
            Gl.glTranslatef(xPos, yPos, zPos);
            Gl.glScalef(1.0f, 5.0f, 1.0f);		/**< 腿是1x5x1长方体 */
            DrawCube(0.0f, 0.0f, 0.0f);
            Gl.glPopMatrix();
        }

        /** 在指定位置绘制机器人 */
        void DrawRobot(float xPos, float yPos, float zPos)
        {
        

            Gl.glPushMatrix();

            Gl.glTranslatef(xPos, yPos, zPos);	/**< 定位 */

            ///绘制各个部分
            DrawHead(1.0f, 2.0f, 0.0f);     /**< 绘制头部 */
            DrawTorso(1.5f, 0.0f, 0.0f);   /**< 绘制躯干 */

            ///绘制胳膊
            Gl.glPushMatrix();
            ///如果胳膊正在向前运动,则递增角度,否则递减角度 
            if (arm1)
                armAngle[0] = armAngle[0] + 0.1f;
            else
                armAngle[0] = armAngle[0] - 0.1f;

            ///如果胳膊达到其最大角度则改变其状态
            if (armAngle[0] >= 15.0f)
                arm1 = false;
            if (armAngle[0] <= -15.0f)
                arm1 = true;

            ///平移并旋转后绘制胳膊
            Gl.glTranslatef(0.0f, -0.5f, 0.0f);
            Gl.glRotatef(armAngle[0], 1.0f, 0.0f, 0.0f);
            DrawArm(2.5f, 0.0f, -0.5f);
            Gl.glPopMatrix();

            ///同上arm0
            Gl.glPushMatrix();

            if (arm2)
                armAngle[1] = armAngle[1] + 0.1f;
            else
                armAngle[1] = armAngle[1] - 0.1f;


            if (armAngle[1] >= 15.0f)
                arm2 = false;
            if (armAngle[1] <= -15.0f)
                arm2 = true;


            Gl.glTranslatef(0.0f, -0.5f, 0.0f);
            Gl.glRotatef(armAngle[1], 1.0f, 0.0f, 0.0f);
            DrawArm(-1.5f, 0.0f, -0.5f);
            Gl.glPopMatrix();

            ///绘制腿部
            Gl.glPushMatrix();

            ///如果腿正在向前运动,则递增角度,否则递减角度 
            if (leg1)
                legAngle[0] = legAngle[0] + 0.1f;
            else
                legAngle[0] = legAngle[0] - 0.1f;

            ///如果腿达到其最大角度则改变其状态
            if (legAngle[0] >= 15.0f)
                leg1 = false;
            if (legAngle[0] <= -15.0f)
                leg1 = true;

            ///平移并旋转后绘制胳膊
            Gl.glTranslatef(0.0f, -0.5f, 0.0f);
            Gl.glRotatef(legAngle[0], 1.0f, 0.0f, 0.0f);
            DrawLeg(-0.5f, -5.0f, -0.5f);

            Gl.glPopMatrix();

            ///同上leg1
            Gl.glPushMatrix();

            if (leg2)
                legAngle[1] = legAngle[1] + 0.1f;
            else
                legAngle[1] = legAngle[1] - 0.1f;

            if (legAngle[1] >= 15.0f)
                leg2 = false;
            if (legAngle[1] <= -15.0f)
                leg2 = true;

            Gl.glTranslatef(0.0f, -0.5f, 0.0f);
            Gl.glRotatef(legAngle[1], 1.0f, 0.0f, 0.0f);
            DrawLeg(1.5f, -5.0f, -0.5f);

            Gl.glPopMatrix();
            Gl.glPopMatrix();
        }


        /// <summary>
        /// 初始化视口投影,恢复原书的视口
        /// </summary>
        public override void iniView(int windowWidth, int windowHeight)
        {

            Gl.glViewport(0, 0, windowWidth, windowHeight);									/**< 重新设置视口 */
            Glu.gluPerspective(45.0f, windowWidth / windowHeight, 1.0f, 100.0f);
            Gl.glMatrixMode(Gl.GL_MODELVIEW);
            Gl.glLoadIdentity();
          
        }

        /// <summary>
        /// 重载,使用Draw方法绘图
        /// </summary>
        /// <param name="mouseX"></param>
        /// <param name="currentTime"></param>
        public override void DrawGLScene(int mouseX, double currentTime)
        {
            Draw();
        }

        /// <summary>
        /// 重载,加入书上角度变换代码
        /// </summary>
        /// <param name="mouseX"></param>
        /// <param name="currentTime"></param>
        public override void Update(float milliseconds)
        {
            //按下ESC结束
            isRunning = ((Glfw.glfwGetKey(Glfw.GLFW_KEY_ESC) == Glfw.GLFW_RELEASE) &&
                Glfw.glfwGetWindowParam(Glfw.GLFW_OPENED) == Gl.GL_TRUE);

            angle = angle + 0.05f;
            if (angle >= 360.0f)
                angle = 0.0f;
        }

        /** 绘制函数 */
        void Draw()
        {
            /** 用户自定义的绘制过程 */
            Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
            Gl.glLoadIdentity();

            ///进行模型变换并绘制机器人
            Gl.glPushMatrix();
            Gl.glTranslatef(0.0f, 0.0f, -30.0f);
            Gl.glRotatef(angle, 0.0f, 1.0f, 0.0f);
            DrawRobot(0.0f, 0.0f, 0.0f);
            Gl.glPopMatrix();


            Gl.glFlush();													/**< 强制执行所有的OpenGl.gl命令 */
        }
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值