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


 

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