本文基础: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命令 */
}
}
}