学习了《OpenGL超级宝典》第二章后,编写了我们的第一个OpenGL程序,也真正开始了OpenGL之旅。
下面来让我们一起重新练习熟悉一下第二章的3个例子吧!
1. "Triangle" 第一个三角形
通过这个例子我们熟悉了OpenGL的一些流程,如初始化、窗口的创建、窗口的标题、图形的渲染等。
具体的例子代码我就不复制贴出了哈~,下面我只贴出我对此例子做的一些学习扩展:
// +++++++++++++++++++++++++++++++++++++++
// 《OpenGL 超级宝典》 Chapter02 Triangle
// ---------------------------------------
// 头文件引用
......
// GLTools 封装的顶点批次处理类
GLBatch triangleBatch;
// GLTools 封装的着色器管理器
GLShaderManager shaderManager;
// +++++++++++
// 自己扩展部分
GLBatch triangle2Batch;
GLBatch triangle3Batch;
GLBatch triangle4Batch;
// -----------
// 初始化
void SetupRC()
{
// 书本相同
// 蓝色背景
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
// 初始化 GLTools 的着色器管理器
shaderManager.InitializeStockShaders();
// 创建一个三角形顶点数组
GLfloat vVerts[] = {
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.0f, 0.0f, 0.0f,
};
// 拷贝三角形顶点数组到 GLTools 的顶点批次中
// GL_TRIANGLES 表示为三角形顶点
triangleBatch.Begin(GL_TRIANGLES, 3);
triangleBatch.CopyVertexData3f(vVerts);
triangleBatch.End();
// +++++++++++
// 自己扩展部分
// 绿色三角形顶点
GLfloat vVerts2[] = {
0.5f, -0.5f, 0.0f,
0.5f, 0.5f, 0.0f,
0.0f, 0.0f, 0.0f,
};
triangle2Batch.Begin(GL_TRIANGLES, 3);
triangle2Batch.CopyVertexData3f(vVerts2);
triangle2Batch.End();
// 黄色三角形顶点
GLfloat vVerts3[] = {
0.5f, 0.5f, 0.0f,
-0.5f, 0.5f, 0.0f,
0.0f, 0.0f, 0.0f,
};
triangle3Batch.Begin(GL_TRIANGLES, 3);
triangle3Batch.CopyVertexData3f(vVerts3);
triangle3Batch.End();
// 洋红色三角形顶点
GLfloat vVerts4[] = {
-0.5f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.0f, 0.0f, 0.0f,
};
triangle4Batch.Begin(GL_TRIANGLES, 3);
triangle4Batch.CopyVertexData3f(vVerts4);
triangle4Batch.End();
// -----------
}
// 渲染场景
void RenderScene(void)
{
// 书本相同
// 清除 颜色 和 深度 和 模板 的缓冲区数据
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
// 红色
GLfloat vRed[] = { 1.0f, 0.0f, 0.0f, 1.0f };
// 装载红色着色器
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vRed);
// 绘制三角形
triangleBatch.Draw();
// +++++++++++
// 自己扩展部分
// 绿色
GLfloat vGreen[] = { 0.0f, 1.0f, 0.0f, 1.0f };
// 装载红色着色器
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vGreen);
// 绘制三角形
triangle2Batch.Draw();
// 黄色
GLfloat vYellow[] = { 1.0f, 1.0f, 0.0f, 1.0f };
// 装载红色着色器
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vYellow);
// 绘制三角形
triangle3Batch.Draw();
// 洋红色
GLfloat vMagenta[] = { 1.0f, 0.0f, 1.0f, 1.0f };
// 装载红色着色器
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vMagenta);
// 绘制三角形
triangle4Batch.Draw();
// -----------
// 将后台缓冲区内容切换到前台缓冲区
glutSwapBuffers();
}
int main(int argc, char * argv[])
{
// 书本相同
.....
return 0;
}
首先贴出运行的截图:
也就是通过四个三角形进行拼出一个正方形
下面进行讲解上面的程序:
1. 定义其他3个新的三角形GLBatch用于存放绘制是三角形顶点数据。
2. 定义其他3个新的三角形顶点数组,然后放入对应GLBatch中。
3. 渲染中进行渲染其他3个新的三角形。
2. "Move" 通过按键输入让图形变得有活力
同样也只贴出扩展的内容部分:
+++++++++++++++++++++++++++++++++++++++
《OpenGL 超级宝典》 Chapter02 Move
---------------------------------------
.......
+++++++++++
自己扩展部分
GLBatch triangleBatch;
GLfloat fPi = 3.1415926f;
GLfloat fRad = fPi / 180.0f;
GLfloat fTriangleX = 0.0f, fTriangleY = 0.0f;
GLfloat fCurAngle = 0.0f;
// 创建一个三角形顶点数组
GLfloat fScale = 0.8f;
GLfloat vTriangleVerts[] = {
-blockSize * fScale, 0.0f, 0.0f,
blockSize * fScale, 0.0f, 0.0f,
0.0f, blockSize * fScale, 0.0f,
};
void Rotate(GLfloat angle, GLfloat *pX, GLfloat *pY)
{
*pX = fTriangleX + (blockSize * fScale) * cos(angle * fRad);
*pY = fTriangleY + (blockSize * fScale) * sin(angle * fRad);
}
void RotateTriangleArrow(GLfloat angle)
{
Rotate(angle, &vTriangleVerts[0], &vTriangleVerts[1]);
Rotate(angle + 90.0f, &vTriangleVerts[3], &vTriangleVerts[4]);
Rotate(angle + 180.0f, &vTriangleVerts[6], &vTriangleVerts[7]);
}
// -----------
void SetupRC()
{
.......
triangleBatch.Begin(GL_TRIANGLES, 3);
triangleBatch.CopyVertexData3f(vTriangleVerts);
triangleBatch.End();
}
void SpecialKeys(int key, int x, int y)
{
.......
if (key == GLUT_KEY_UP) {
fCurAngle = 0.0f;
blockY += stepSize;
}
if (key == GLUT_KEY_DOWN) {
fCurAngle = 180.0f;
blockY -= stepSize;
}
if (key == GLUT_KEY_LEFT) {
fCurAngle = 90.0f;
blockX -= stepSize;
}
if (key == GLUT_KEY_RIGHT) {
fCurAngle = 270.0f;
blockX += stepSize;
}
.......
RotateTriangleArrow(fCurAngle);
triangleBatch.CopyVertexData3f(vTriangleVerts);
glutPostRedisplay();
}
void RenderScene(void)
{
......
// 南瓜橙色
GLfloat vPumpkinOrange[] = { 0.98f, 0.625f, 0.12f, 1.0f };
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vPumpkinOrange);
triangleBatch.Draw();
glutSwapBuffers();
}
int main(int argc, char * argv[])
{
......
return 0;
}
首先贴出运行的截图:
分别对应按下了 ↑←↓→按键后箭头的变化
下面进行讲解上面的程序:
1. 首先是定义一个三角形的GLBatch。
2. 定义一个三角形的顶点数组,用于存放三角形的顶点数据。
3. fTriangleX 和 fTriangleY 表示为 三角形底边的中心点的坐标,当按键发生变化后,通过这个原点进行旋转。
4. fPi 和 fRad 为圆周率和弧度,同样为旋转用到的参数。
5. fCurAngle 表示为旋转的角度,分别对于按键改变后进行旋转的角度。
6. fScale 为对三角形的一个缩放比例。
7. Rotate 函数用于对顶点坐标进行旋转(详细旋转的部分,在以前的有讲过,如需单独详细讲解请给我留言吧,此处就略过了)。
8. RotateTriangleArrow函数用于旋转三角形的三个顶点。
9. 在SetupRC是时候将我们的三角形顶点数据进行放入我们定义的GLBatch中,然后在RenderScene的时候同样进行渲染。
10. 在SpecialKeys的时候,进行改变我们的fCurAngle(三角形旋转的角度)。
3. "Bounce" 简单的动画片,通过不断刷新进行更新渲染
通过参照 "Bounce" 和 "Triangle" 来进行做一些有意思的事情吧。
下面贴出扩展部分:
+++++++++++++++++++++++++++++++++++++++
《OpenGL 超级宝典》 Chapter02 Bounce
---------------------------------------
.......
GLShaderManager shaderManager;
GLBatch leftFootTriangleBatch;
GLBatch leftShankTriangleBatch;
GLBatch leftThighTriangleBatch;
GLBatch leftUpperArmTriangleBatch;
GLBatch leftForeArmTriangleBatch;
GLBatch leftFinger1TriangleBatch;
GLBatch leftFinger2TriangleBatch;
GLBatch rightFootTriangleBatch;
GLBatch rightShankTriangleBatch;
GLBatch rightThighTriangleBatch;
GLBatch rightUpperArmTriangleBatch;
GLBatch rightForeArmTriangleBatch;
GLBatch rightFinger1TriangleBatch;
GLBatch rightFinger2TriangleBatch;
GLBatch neckTriangleBatch;
GLBatch bodySquareBatch;
GLBatch headSquareBatch;
GLfloat fStartX = 0.0f, fStartY = 0.0f;
// Left-Foot
GLfloat vLeftFootVerts[] = {
fStartX - 0.02f - 0.1f, fStartY, 0.0f,
fStartX - 0.02f, fStartY, 0.0f,
fStartX - 0.07f, fStartY + 0.05f, 0.0f
};
// Left-Shank
GLfloat vLeftShankVerts[] = {
fStartX - 0.07f, fStartY + 0.05f, 0.0f,
fStartX - 0.02f - 0.02f, fStartY + 0.05f + 0.1f, 0.0f,
fStartX - 0.02f - 0.08f, fStartY + 0.05f + 0.1f, 0.0f,
};
// Left-Thigh
GLfloat vLeftThightVerts[] = {
fStartX - 0.02f - 0.08f, fStartY + 0.05f + 0.1f, 0.0f,
fStartX - 0.02f - 0.02f, fStartY + 0.05f + 0.1f, 0.0f,
fStartX - 0.07f, fStartY + 0.05f + 0.1f + 0.08f, 0.0f,
};
// Right-Foot
GLfloat vRightFootVerts[] = {
fStartX + 0.02f + 0.1f, fStartY, 0.0f,
fStartX + 0.02f, fStartY, 0.0f,
fStartX + 0.07f, fStartY + 0.05f, 0.0f
};
// Right-Shank
GLfloat vRightShankVerts[] = {
fStartX + 0.07f, fStartY + 0.05f, 0.0f,
fStartX + 0.02f + 0.02f, fStartY + 0.05f + 0.1f, 0.0f,
fStartX + 0.02f + 0.08f, fStartY + 0.05f + 0.1f, 0.0f,
};
// Right-Thigh
GLfloat vRightThightVerts[] = {
fStartX + 0.02f + 0.08f, fStartY + 0.05f + 0.1f, 0.0f,
fStartX + 0.02f + 0.02f, fStartY + 0.05f + 0.1f, 0.0f,
fStartX + 0.07f, fStartY + 0.05f + 0.1f + 0.08f, 0.0f,
};
// Body
GLfloat vBodyVerts[] = {
fStartX - 0.1f, fStartY + 0.05f + 0.1f + 0.08f, 0.0f,
fStartX + 0.1f, fStartY + 0.05f + 0.1f + 0.08f, 0.0f,
fStartX + 0.1f, fStartY + 0.05f + 0.1f + 0.08f + 0.15f, 0.0f,
fStartX - 0.1f, fStartY + 0.05f + 0.1f + 0.08f + 0.15f, 0.0f,
};
// Neck
GLfloat vNeckVerts[] = {
fStartX - 0.07f, fStartY + 0.05f + 0.1f + 0.08f + 0.15f, 0.0f,
fStartX + 0.07f, fStartY + 0.05f + 0.1f + 0.08f + 0.15f, 0.0f,
fStartX, fStartY + 0.05f + 0.1f + 0.08f + 0.15f + 0.05f, 0.0f,
};
// Head
GLfloat vHeadVerts[] = {
fStartX, fStartY + 0.05f + 0.1f + 0.08f + 0.15f + 0.05f, 0.0f,
fStartX + 0.05f, fStartY + 0.05f + 0.1f + 0.08f + 0.15f + 0.05f + 0.05f, 0.0f,
fStartX, fStartY + 0.05f + 0.1f + 0.08f + 0.15f + 0.05f + 0.05f + 0.1f, 0.0f,
fStartX - 0.05f, fStartY + 0.05f + 0.1f + 0.08f + 0.15f + 0.05f + 0.05f, 0.0f,
};
// Left-UpperArm
GLfloat vLeftUpperArmVerts[] = {
fStartX - 0.1f, fStartY + 0.05f + 0.1f + 0.08f + 0.075f - 0.03f, 0.0f,
fStartX - 0.1f, fStartY + 0.05f + 0.1f + 0.08f + 0.075f + 0.03f, 0.0f,
fStartX - 0.1f - 0.05f, fStartY + 0.05f + 0.1f + 0.08f + 0.075f, 0.0f,
};
// Right-UpperArm
GLfloat vRightUpperArmVerts[] = {
fStartX + 0.1f, fStartY + 0.05f + 0.1f + 0.08f + 0.075f - 0.03f, 0.0f,
fStartX + 0.1f, fStartY + 0.05f + 0.1f + 0.08f + 0.075f + 0.03f, 0.0f,
fStartX + 0.1f + 0.05f, fStartY + 0.05f + 0.1f + 0.08f + 0.075f, 0.0f,
};
// Left-ForeArm
GLfloat vLeftForeArmVerts[] = {
fStartX - 0.1f - 0.05f, fStartY + 0.05f + 0.1f + 0.08f + 0.075f, 0.0f,
fStartX - 0.1f - 0.05f - 0.07f, fStartY + 0.05f + 0.1f + 0.08f + 0.075f + 0.03f, 0.0f,
fStartX - 0.1f - 0.05f - 0.07f, fStartY + 0.05f + 0.1f + 0.08f + 0.075f - 0.03f, 0.0f,
};
// Right-ForeArm
GLfloat vRightForeArmVerts[] = {
fStartX + 0.1f + 0.05f, fStartY + 0.05f + 0.1f + 0.08f + 0.075f, 0.0f,
fStartX + 0.1f + 0.05f + 0.07f, fStartY + 0.05f + 0.1f + 0.08f + 0.075f + 0.03f, 0.0f,
fStartX + 0.1f + 0.05f + 0.07f, fStartY + 0.05f + 0.1f + 0.08f + 0.075f - 0.03f, 0.0f,
};
// Left-Finger-1
GLfloat vLeftFinger1Verts[] = {
fStartX - 0.1f - 0.05f - 0.07f, fStartY + 0.05f + 0.1f + 0.08f + 0.075f + 0.03f, 0.0f,
fStartX - 0.1f - 0.05f - 0.07f - 0.02f, fStartY + 0.05f + 0.1f + 0.08f + 0.075f + 0.03f - 0.015f, 0.0f,
fStartX - 0.1f - 0.05f - 0.07f, fStartY + 0.05f + 0.1f + 0.08f + 0.075f + 0.03f - 0.03f, 0.0f,
};
// Left-Finger-2
GLfloat vLeftFinger2Verts[] = {
fStartX - 0.1f - 0.05f - 0.07f, fStartY + 0.05f + 0.1f + 0.08f + 0.075f + 0.03f - 0.03f, 0.0f,
fStartX - 0.1f - 0.05f - 0.07f - 0.02f, fStartY + 0.05f + 0.1f + 0.08f + 0.075f + 0.03f - 0.015f - 0.03f, 0.0f,
fStartX - 0.1f - 0.05f - 0.07f, fStartY + 0.05f + 0.1f + 0.08f + 0.075f + 0.03f - 0.03f - 0.03f, 0.0f,
};
// Right-Finger-1
GLfloat vRightFinger1Verts[] = {
fStartX + 0.1f + 0.05f + 0.07f, fStartY + 0.05f + 0.1f + 0.08f + 0.075f + 0.03f, 0.0f,
fStartX + 0.1f + 0.05f + 0.07f + 0.02f, fStartY + 0.05f + 0.1f + 0.08f + 0.075f + 0.03f - 0.015f, 0.0f,
fStartX + 0.1f + 0.05f + 0.07f, fStartY + 0.05f + 0.1f + 0.08f + 0.075f + 0.03f - 0.03f, 0.0f,
};
// Right-Finger-2
GLfloat vRightFinger2Verts[] = {
fStartX + 0.1f + 0.05f + 0.07f, fStartY + 0.05f + 0.1f + 0.08f + 0.075f + 0.03f - 0.03f, 0.0f,
fStartX + 0.1f + 0.05f + 0.07f + 0.02f, fStartY + 0.05f + 0.1f + 0.08f + 0.075f + 0.03f - 0.015f - 0.03f, 0.0f,
fStartX + 0.1f + 0.05f + 0.07f, fStartY + 0.05f + 0.1f + 0.08f + 0.075f + 0.03f - 0.03f - 0.03f, 0.0f,
};
void Rotate(GLfloat fOriginX, GLfloat fOriginY, GLfloat fRadius, GLfloat angle, GLfloat *pX, GLfloat *pY)
{
static GLfloat fPi = 3.1415926f, fRad = fPi / 180.0f;
*pX = fOriginX + fRadius * cos(angle * fRad);
*pY = fOriginY + fRadius * sin(angle * fRad);
}
// 获取两点之间的距离
GLfloat GetDistanceBetweenTwoPoint(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
{
// 根据勾股定理计算两点距离
GLfloat a = x1 - x2;
GLfloat b = y1 - y2;
return sqrt(a * a + b * b);
}
// 挥舞手臂
void WaringArm()
{
static GLint counter = 1;
static GLfloat fMinAngle = 180.0f - 30.0f, fMaxAngle = 180.0f + 30.0f, fAngle = fMinAngle, fAngleInc = 1.0f;
if (++counter > 30)
counter = 0;
else
return;
fAngle += fAngleInc;
if (fAngle <= fMinAngle) {
fAngle = fMinAngle;
fAngleInc = 1;
}
else if (fAngle >= fMaxAngle) {
fAngle = fMaxAngle;
fAngleInc = -1;
}
// 肘关节的坐标点(x, y)
GLfloat fLeftElbowX = vLeftForeArmVerts[0], fLeftElbowY = vLeftForeArmVerts[1];
// 旋转点1
Rotate(
fLeftElbowX, fLeftElbowY,
GetDistanceBetweenTwoPoint(fLeftElbowX, fLeftElbowY, vLeftForeArmVerts[3], vLeftForeArmVerts[4]),
fAngle - 20, &vLeftForeArmVerts[3], &vLeftForeArmVerts[4]
);
// 旋转点2
Rotate(
fLeftElbowX, fLeftElbowY,
GetDistanceBetweenTwoPoint(fLeftElbowX, fLeftElbowY, vLeftForeArmVerts[6], vLeftForeArmVerts[7]),
fAngle + 20, &vLeftForeArmVerts[6], &vLeftForeArmVerts[7]
);
leftForeArmTriangleBatch.CopyVertexData3f(vLeftForeArmVerts);
vRightForeArmVerts[3] = -vLeftForeArmVerts[3];
vRightForeArmVerts[4] = vLeftForeArmVerts[4];
vRightForeArmVerts[6] = -vLeftForeArmVerts[6];
vRightForeArmVerts[7] = vLeftForeArmVerts[7];
rightForeArmTriangleBatch.CopyVertexData3f(vRightForeArmVerts);
// 旋转 Finger1 点1
Rotate(
fLeftElbowX, fLeftElbowY,
GetDistanceBetweenTwoPoint(fLeftElbowX, fLeftElbowY, vLeftFinger1Verts[0], vLeftFinger1Verts[1]),
fAngle - 6 - 11, &vLeftFinger1Verts[0], &vLeftFinger1Verts[1]
);
// 旋转 Finger1 点2
Rotate(
fLeftElbowX, fLeftElbowY,
GetDistanceBetweenTwoPoint(fLeftElbowX, fLeftElbowY, vLeftFinger1Verts[3], vLeftFinger1Verts[4]),
fAngle - 6, &vLeftFinger1Verts[3], &vLeftFinger1Verts[4]
);
// 旋转 Finger1 点3
Rotate(
fLeftElbowX, fLeftElbowY,
GetDistanceBetweenTwoPoint(fLeftElbowX, fLeftElbowY, vLeftFinger1Verts[6], vLeftFinger1Verts[7]),
fAngle - 6 + 11, &vLeftFinger1Verts[6], &vLeftFinger1Verts[7]
);
leftFinger1TriangleBatch.CopyVertexData3f(vLeftFinger1Verts);
vRightFinger1Verts[0] = -vLeftFinger1Verts[0];
vRightFinger1Verts[1] = vLeftFinger1Verts[1];
vRightFinger1Verts[3] = -vLeftFinger1Verts[3];
vRightFinger1Verts[4] = vLeftFinger1Verts[4];
vRightFinger1Verts[6] = -vLeftFinger1Verts[6];
vRightFinger1Verts[7] = vLeftFinger1Verts[7];
rightFinger1TriangleBatch.CopyVertexData3f(vRightFinger1Verts);
// 旋转 Finger2 点1
Rotate(
fLeftElbowX, fLeftElbowY,
GetDistanceBetweenTwoPoint(fLeftElbowX, fLeftElbowY, vLeftFinger2Verts[0], vLeftFinger2Verts[1]),
fAngle + 6 - 11, &vLeftFinger2Verts[0], &vLeftFinger2Verts[1]
);
// 旋转 Finger2 点2
Rotate(
fLeftElbowX, fLeftElbowY,
GetDistanceBetweenTwoPoint(fLeftElbowX, fLeftElbowY, vLeftFinger2Verts[3], vLeftFinger2Verts[4]),
fAngle + 6, &vLeftFinger2Verts[3], &vLeftFinger2Verts[4]
);
// 旋转 Finger2 点3
Rotate(
fLeftElbowX, fLeftElbowY,
GetDistanceBetweenTwoPoint(fLeftElbowX, fLeftElbowY, vLeftFinger2Verts[6], vLeftFinger2Verts[7]),
fAngle + 6 + 11, &vLeftFinger2Verts[6], &vLeftFinger2Verts[7]
);
leftFinger2TriangleBatch.CopyVertexData3f(vLeftFinger2Verts);
vRightFinger2Verts[0] = -vLeftFinger2Verts[0];
vRightFinger2Verts[1] = vLeftFinger2Verts[1];
vRightFinger2Verts[3] = -vLeftFinger2Verts[3];
vRightFinger2Verts[4] = vLeftFinger2Verts[4];
vRightFinger2Verts[6] = -vLeftFinger2Verts[6];
vRightFinger2Verts[7] = vLeftFinger2Verts[7];
rightFinger2TriangleBatch.CopyVertexData3f(vRightFinger2Verts);
}
void AutoTriangleCopyVertexData3f(GLBatch *pTriangleBatch, GLfloat *vVerts)
{
pTriangleBatch->Begin(GL_TRIANGLES, 3);
pTriangleBatch->CopyVertexData3f(vVerts);
pTriangleBatch->End();
}
void SetupRC()
{
......
AutoTriangleCopyVertexData3f(&leftFootTriangleBatch, vLeftFootVerts);
AutoTriangleCopyVertexData3f(&leftShankTriangleBatch, vLeftShankVerts);
AutoTriangleCopyVertexData3f(&leftThighTriangleBatch, vLeftThightVerts);
AutoTriangleCopyVertexData3f(&rightFootTriangleBatch, vRightFootVerts);
AutoTriangleCopyVertexData3f(&rightShankTriangleBatch, vRightShankVerts);
AutoTriangleCopyVertexData3f(&rightThighTriangleBatch, vRightThightVerts);
bodySquareBatch.Begin(GL_TRIANGLE_FAN, 4);
bodySquareBatch.CopyVertexData3f(vBodyVerts);
bodySquareBatch.End();
AutoTriangleCopyVertexData3f(&neckTriangleBatch, vNeckVerts);
headSquareBatch.Begin(GL_TRIANGLE_FAN, 4);
headSquareBatch.CopyVertexData3f(vHeadVerts);
headSquareBatch.End();
AutoTriangleCopyVertexData3f(&leftUpperArmTriangleBatch, vLeftUpperArmVerts);
AutoTriangleCopyVertexData3f(&leftForeArmTriangleBatch, vLeftForeArmVerts);
AutoTriangleCopyVertexData3f(&leftFinger1TriangleBatch, vLeftFinger1Verts);
AutoTriangleCopyVertexData3f(&leftFinger2TriangleBatch, vLeftFinger2Verts);
AutoTriangleCopyVertexData3f(&rightUpperArmTriangleBatch, vRightUpperArmVerts);
AutoTriangleCopyVertexData3f(&rightForeArmTriangleBatch, vRightForeArmVerts);
AutoTriangleCopyVertexData3f(&rightFinger1TriangleBatch, vRightFinger1Verts);
AutoTriangleCopyVertexData3f(&rightFinger2TriangleBatch, vRightFinger2Verts);
}
void RenderScene(void)
{
......
GLfloat vRed[] = { 1.0f, 0.0f, 0.0f, 1.0f };
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vRed);
leftFootTriangleBatch.Draw();
rightFootTriangleBatch.Draw();
GLfloat vGreen[] = { 0.0f, 1.0f, 0.0f, 1.0f };
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vGreen);
leftShankTriangleBatch.Draw();
rightShankTriangleBatch.Draw();
GLfloat vYellow[] = { 1.0f, 1.0f, 0.0f, 1.0f };
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vYellow);
leftThighTriangleBatch.Draw();
rightThighTriangleBatch.Draw();
GLfloat vMagenta[] = { 1.0f, 0.0f, 1.0f, 1.0f };
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vMagenta);
bodySquareBatch.Draw();
GLfloat vCyan[] = { 1.0f, 1.0f, 1.0f, 1.0f };
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vCyan);
neckTriangleBatch.Draw();
GLfloat vPumpkinOrange[] = { 0.98f, 0.625f, 0.12f, 1.0f };
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vPumpkinOrange);
headSquareBatch.Draw();
GLfloat vPastelPink[] = { 0.98f, 0.04f, 0.70f, 1.0f };
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vPastelPink);
leftUpperArmTriangleBatch.Draw();
rightUpperArmTriangleBatch.Draw();
GLfloat vPlum1[] = { 0.67f, 0.50f, 1.0f, 1.0f };
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vPlum1);
leftForeArmTriangleBatch.Draw();
rightForeArmTriangleBatch.Draw();
GLfloat vOrchid1[] = { 1.0f, 0.51f, 0.98f, 1.0f };
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vOrchid1);
leftFinger1TriangleBatch.Draw();
leftFinger2TriangleBatch.Draw();
rightFinger1TriangleBatch.Draw();
rightFinger2TriangleBatch.Draw();
WaringArm();
glutSwapBuffers();
glutPostRedisplay();
}
int main(int argc, char* argv[])
{
.......
return 0;
}
首先贴出运行的截图:
通过三角形和正方形进行绘制一个"简单的机器人"并且挥舞着双手向我们 "打招呼"
下面进行讲解上面的程序:
1. 三角形图形的绘制部分,是通过绘制多个三角形和四边形进行实现的,后面会贴出图片。(详细见机器人绘制图片)
2. 挥舞手臂的动作实现,通过旋转三角形,例如像 "Move" 的方向箭头通过旋转实现。(详细见挥舞手臂图片)
PS: 因为三角形的角度部分为大概计算的,所以旋转后的手臂并不完美,不过也算达到目的了。
机器人绘制图片:
挥舞手臂:
模仿我们摆动手臂的动作,进行做旋转操作。
好的,本章扩展学习内容部分就到此结束了,如有不懂的可评论留言,后续在进行补充。
最后祝大家七夕快乐~
本章源码:已上传到Github-learn-extension-Chapter02了哦,有兴趣的读者可以看下~