1.導(dǎo)入頭文件
#include "GLTools.h"
#include <GLUT/GLUT.h>
2.初始化要用到的全局變量
//初始化一個批次容器
GLBatch triangleBatch;
//初始化一個著色管理器
GLShaderManager shaderManager;
//所繪制的正方形的邊長宾濒。
GLfloat lengthOfSide = 0.2;
//正方形的頂點數(shù)組
GLfloat vVerts[] = {
-(lengthOfSide/2), -(lengthOfSide/2), 0.0f, //A點
(lengthOfSide/2), -(lengthOfSide/2), 0.0f, //B點
(lengthOfSide/2), (lengthOfSide/2), 0.0f, //C點
-(lengthOfSide/2), (lengthOfSide/2), 0.0f //D點
};
3.在Main函數(shù)進行初始化窗口以及注冊回調(diào)函數(shù)
int main(int argc,char* argv[]) {
//初始化GLUT庫抠刺,這個函數(shù)只是傳入命令參數(shù)并且初始化glut庫
glutInit(&argc, argv);
//初始化雙緩沖窗口
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
//GLUT窗口大小,窗口標(biāo)題
glutInitWindowSize(600, 600);
//創(chuàng)建一個標(biāo)題為Triangle的窗口
glutCreateWindow("Triangle");
//注冊重塑函數(shù)
glutReshapeFunc(changeSize);
//注冊顯示函數(shù)
glutDisplayFunc(renderScene);
//注冊特殊鍵位點擊回調(diào)函數(shù)
glutSpecialFunc(specialKeyClick);
//初始化一個GLEW庫,確保OpenGL API對程序完全可用扁瓢。
GLenum status = glewInit();
if (GLEW_OK != status) {
printf("GLEW Error:%s\n",glewGetErrorString(status));
return 1;
}
//設(shè)置我們的渲染環(huán)境
setupRC();
//這是?個?限執(zhí)?的循環(huán)伐债,它會負(fù)責(zé)?直處理窗?和操作系統(tǒng)的?戶輸?等操作
glutMainLoop();
return 0;
}
3.渲染之前需要進行清屏、初始化固定著色器以及設(shè)置頂點數(shù)據(jù)
void setupRC() {
//設(shè)置窗口背景顏色
glClearColor(0.98f, 0.5f, 0.3f, 1);
//初始化固定著色器
shaderManager.InitializeStockShaders();
//設(shè)置圖元鏈接類型以及頂點個數(shù),GL_TRIANGLE_FAN代表以三角形扇形的方式連接頂點
triangleBatch.Begin(GL_TRIANGLE_FAN, 4);
//拷貝頂點數(shù)據(jù)到批次類
triangleBatch.CopyVertexData3f(vVerts);
//配置完畢
triangleBatch.End();
}
4.窗口改變大小時的回調(diào)函數(shù)
//窗口大小改變時附鸽,接受新的寬度和高度
void changeSize(int w, int h) {
//設(shè)置GL視口位置以及大小
glViewport(0, 0, w, h);
}
5.當(dāng)需要重新渲染圖形時的回調(diào)函數(shù)
void renderScene() {
//清除一個或一組特定的緩存區(qū)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
//2.設(shè)置一組浮點數(shù)來表示紅色
GLfloat vRed[] = {1.0, 0.0, 0.0, 0.5f};
//傳遞到存儲著色器,即GLT_SHADER_IDENTITY著色器瞒瘸,這個著色器只是使用指定顏色以默認(rèn)笛卡爾坐標(biāo)系在屏幕上渲染幾何圖形
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vRed);
//提交著色器
triangleBatch.Draw();
//在開始的設(shè)置openGL 窗口的時候坷备,我們指定要一個雙緩沖區(qū)的渲染環(huán)境。這就意味著將在后臺緩沖區(qū)進行渲染情臭,渲染結(jié)束后交換給前臺省撑。這種方式可以防止觀察者看到可能伴隨著動畫幀與動畫幀之間的閃爍的渲染過程。緩沖區(qū)交換平臺將以平臺特定的方式進行俯在。
//將后臺緩沖區(qū)進行渲染竟秫,然后結(jié)束后交換給前臺
glutSwapBuffers();
}
運行程序就會看到如下的運行結(jié)果:
運行結(jié)果
5.在特殊鍵位點擊回調(diào)函數(shù)里面編寫如下代碼
void specialKeyClick(int key, int x, int y) {
//以D點為基準(zhǔn)坐標(biāo),來改變A朝巫、B鸿摇、C其他點坐標(biāo)的值
GLfloat d_x = vVerts[9];
GLfloat d_y = vVerts[10];
if (key == GLUT_KEY_UP) { //上移
d_y += 0.1;
//判斷上移之后是否超出邊界石景,超出就緊貼上邊界
if (d_y > 1) {
d_y = 1;
}
} else if (key == GLUT_KEY_LEFT) { //左移
d_x -= 0.1;
//判斷左移之后是否超出邊界劈猿,超出就緊貼左邊界
if (d_x < -1) {
d_x = -1;
}
} else if (key == GLUT_KEY_RIGHT) { //右移
d_x += 0.1;
//判斷右移之后是否超出邊界,超出就緊貼右邊界
if (d_x + lengthOfSide > 1) {
d_x = 1 - lengthOfSide;
}
} else if (key == GLUT_KEY_DOWN) { //下移
d_y -= 0.1;
//判斷下移之后是否超出下邊界潮孽,超出就緊貼下邊界
if (d_y - lengthOfSide < -1) {
d_y = -1 + lengthOfSide;
}
}
//重新設(shè)置移動后A點的坐標(biāo)
vVerts[0] = d_x;
vVerts[1] = d_y - lengthOfSide;
//重新設(shè)置移動后B點的坐標(biāo)
vVerts[3] = d_x + lengthOfSide;
vVerts[4] = d_y - lengthOfSide;
//重新設(shè)置移動后C點的坐標(biāo)
vVerts[6] = d_x + lengthOfSide;
vVerts[7] = d_y;
//重新設(shè)置移動后D點的坐標(biāo)
vVerts[9] = d_x;
vVerts[10] = d_y;
//重新拷貝新的頂點數(shù)據(jù)到批次類
triangleBatch.CopyVertexData3f(vVerts);
//發(fā)送通知揪荣,重新渲染圖形
glutPostRedisplay();
}
運行看看效果如何吧~~~