OpenGL game development: familiarization exercise ["OpenGL Super Collection" Chapter 2]

After studying the second chapter of "OpenGL Super Collection", we wrote our first OpenGL program, and really started the OpenGL journey.

Let us re-practice and familiarize ourselves with the 3 examples in Chapter 2 below!

 

1. "Triangle" The first triangle

Through this example, we are familiar with some processes of OpenGL, such as initialization, window creation, window title, graphics rendering, etc.

I will not copy and paste the specific example code. Below I will only post some learning extensions that I have made for this example:

// +++++++++++++++++++++++++++++++++++++++
// 《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;
}

First post a screenshot of the operation:

In other words, four triangles are used to form a square

The above procedure is explained below:

1. Define the other 3 new triangle GLBatch to store the vertex data of the triangle drawn.

2. Define the other 3 new triangle vertex arrays and put them into the corresponding GLBatch.

3. The other 3 new triangles are being rendered during rendering.

 

2. "Move" makes the graphics alive through key input

Also only post the expanded content part:

 +++++++++++++++++++++++++++++++++++++++
 《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;
}

First post a screenshot of the operation:

Corresponding to the change of the arrow after pressing the ↑←↓→ button

The above procedure is explained below:

1. The first is to define a triangular GLBatch.

2. Define a triangle vertex array to store the vertex data of the triangle.

3. fTriangleX and fTriangleY ​​are the coordinates of the center point of the bottom side of the triangle. When the button changes, the rotation is performed through this origin.

4. fPi and fRad are pi and radians, which are also parameters used for rotation.

5. fCurAngle represents the angle of rotation, which is the angle of rotation after the button is changed.

6. fScale is a scaling ratio of the triangle.

7. The Rotate function is used to rotate the vertex coordinates (the detailed rotation part has been explained in the previous section, if you need a detailed explanation, please leave a message for me, I will skip it here) .

8. The RotateTriangleArrow function is used to rotate the three vertices of a triangle.

9. In SetupRC, it's time to put our triangle vertex data into the GLBatch we defined, and then perform the same rendering in RenderScene.

10. In SpecialKeys, change our fCurAngle (the angle of triangle rotation).

 

3. "Bounce" simple animation, updated and rendered through continuous refreshing

Do some interesting things by referring to "Bounce" and "Triangle".

The extended part is posted below:

 +++++++++++++++++++++++++++++++++++++++
 《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;
}

First post a screenshot of the operation:

Draw a "simple robot" through triangles and squares and wave his hands to "greet us"

The above procedure is explained below:

1. The drawing part of the triangle figure is realized by drawing multiple triangles and quadrilaterals, and pictures will be posted later. (See the picture drawn by the robot for details)

2. The action of waving the arm is realized by rotating the triangle, for example, the direction arrow like "Move" is realized by rotating. (See the picture of waving arms for details)

PS: Because the angle of the triangle is roughly calculated, the rotated arm is not perfect, but it can be considered as achieving the goal.

 

The robot draws pictures:

 

Waving arms:

Imitate the action of our swinging arm and perform a rotation operation.

 

Okay, that's the end of the extended learning content of this chapter. If you don't understand, you can comment and leave a message, and I will add it later.

Finally, I wish you all a happy Chinese Valentine's Day~

 

The source code of this chapter: has been uploaded to Github-learn-extension-Chapter02 , interested readers can check it out~

 

 

 

 

 

 

Guess you like

Origin blog.csdn.net/qq_31243065/article/details/108206295