GPGPU編程技術--opengl程序

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


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章