1、Opengl是一個有限狀態機
輸入:各種三維模型、外部事件
輸出:屏幕的像素值
狀態:顏色、觀察位置、材質、透視方法
2、回調函數
交互程序能夠隨時響應事件,依靠無限的事件處理循環
回調函數定義程序對具體事件的響應方式。
事件放入事件隊列,並由系統窗口系統用相應的回調函數處理。
a、顯示回調函數
void glutDisplayFunc(void (*func)(void))
頂點變換依靠矩陣運算完成,包含平移旋轉投影
不同操作使用使用不同的矩陣,投影矩陣(projection matrix)、模型視圖矩陣(model-view-matrix)
模型視圖矩陣負責定義攝像機的位姿即攝像機的位置和觀察方向。
b、變形回調函數
void glutReshapeFunc(void(*func)(GLint width, GLint height))
c 、空閒回調函數
void glutIdlefunc(void (*f)(void))
當沒有窗口事件到達時,GLUT程序功能可以執行後臺處理任務或連續動畫。
3、圖形流水線
a、應用程序
應用程序生成由一些列頂點座標描述的三維模型,將其送至圖形流水線的入口
如glutWireTeapot
b、頂點着色器
負責逐頂點計算,位移、旋轉、投影變換
例子中旋轉矩陣、透視投影矩陣交給頂點着色器對整個模型進行逐頂點操作
將三維頂點變爲二維投影平面的一個點
c、光柵化器
將投影在二維平面上的點轉化爲離散的像素點,決定幀緩衝裏每個像素取值
d、片段着色器
負責逐像素計算,在繪製二維圖形時給每個幀緩衝像素賦值,如設置目標和背景的顏色
e、幀緩存
最終圖像繪製完成並輸出到顯示的地方
glutSwapBuffers交換後臺幀緩存和前臺幀緩存,刷新到屏幕
#define GLEW_STATIC
#include <GL/glew.h>
#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>
GLuint v, f, p;
float lpos[4] = { 1,0.5,1,0 };
#pragma comment( lib, "glew32s.lib" )
void changeSize(int w, int h)
{
printf("changesize w = %d, h = %d\n", w, h);
if (h == 0) h = 1;
float ratio = 1.0*w / h;
//在更改之前重設座標系
glMatrixMode(GL_PROJECTION);//設置爲投影矩陣
glLoadIdentity();//設置爲單位矩陣
//設置視口爲整個窗口
glViewport(0, 0, w, h);
//設置正確的透視投影方法
gluPerspective(45, ratio, 1, 1000);
/*
void gluPerspective(
GLdouble fovy, //角度
GLdouble aspect,//視景體的寬高比
GLdouble zNear,//沿z軸方向的兩裁面之間的距離的近處
GLdouble zFar //沿z軸方向的兩裁面之間的距離的遠處
)
*/
glMatrixMode(GL_MODELVIEW);
}
float a = 0;
void renderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//組合不同的緩衝標誌位,表明需要清除的緩衝
//GL_COLOR_BUFFER_BIT顏色緩衝 GL_DEPTH_BUFFER_BIT深度緩衝
glLoadIdentity();// 當前矩陣初始化爲單位矩陣,爲默認的模型視圖矩陣
gluLookAt(0.0, 0.0, 5.0,// 攝影機的位置
0.0, 0.0, -1.0,//攝影機指向的點
0.0f, 1.0f, 0.0f);//定義的正上方
//此時初始化的當前矩陣被gluLookAt確定的模型視圖修改
glLightfv(GL_LIGHT0, GL_POSITION, lpos);//光源函數
glRotatef(a, 0, 1, 1);// 旋轉變換,a角度,以[0,1,1]爲轉軸
//glutSolidTeapot(2);//太大看不到茶壺
glutWireTeapot(1); //網格茶壺,上一個爲連續表面茶壺
a += 0.1;
glutSwapBuffers();//雙緩衝,交換緩衝
//glutPostRedisplay();//glutIdleFunc如果不調用,需要加這個,不然沒法旋轉,標記當前窗口需要重新繪製
}
int main(int argc, char**argv)
{
glutInit(&argc, argv);
//設置初始顯示模式。深度緩衝、雙緩衝、顏色緩衝
//GLUT_STENCIL.模板緩衝區。
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100, 100);
glutInitWindowSize(320, 320);
glutCreateWindow("GPGPU GLSL");
glutDisplayFunc(renderScene); //註冊顯示回調函數
glutIdleFunc(renderScene);
glutReshapeFunc(changeSize);//註冊變形回調函數
glEnable(GL_DEPTH_TEST);
glClearColor(1.0, 0.0, 0.0, 0.5);
glColor3f(0.0, 0.0, 1.0);//定義繪製目標的顏色
glewInit();
glutMainLoop();
return 0;
}