CS184.1X 计算机图形学导论 第6讲 学习笔记
L6V1:OPENGL 1:概述
1.OpenGL简介
1)图形编程接口(Graphics API),介于编程者和实际的图形硬件;
2)执行的统一指令集具有可移植性。
2.为什么需要OpenGL?
面向三维计算机图形的高级语言,具备许多2D/3D图形的基本处理功能。
3.OpenGL渲染管线
OpenGL具备对图形和图像的初始处理功能,其实际上是一个使用扫描转换器的光栅化程序。主流程第一步,针对图形,首先利用顶点着色器进行几何初始运算处理,而图像,则是进行像素操作;第二步则是进行扫描转换(光栅化),确定屏幕上图形顶点所具体对应的像素;主流程第三步,片元操作,确定每个形状的可见像素的输出颜色,最后输出到帧缓存。
L6V2:OPENGL 1:缓存和矩阵
1.缓存分类:颜色缓存(GLUT_RGB)、深度缓存(GLUT_DEPTH)、累积缓存(GLUT_ACCUM)、模板缓存(GLUT_STENCIL)、单缓存(GLUT_SINGLE)、双缓存(GLUT_DOUBLE);
2.为了移植性,OpenGL没有包含任何窗口系统交互的特性;但可以使用替代品:GLUT和一些其它的工具包(Motif、GLX、Tcl/Tk),均实现了回调,可以相应鼠标和键盘消息。
3.基本模式设置:
1 int main(int argc, char** argv) 2 { 3 ... 4 5 glutInit(&argc, argv); 6 7 // Requests the type of buffers (Single, RGB). 8 // Think about what buffers you would need... 9 10 glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); 11 12 glutInitWindowSize (500, 500); 13 glutInitWindowPosition (100, 100); 14 glutCreateWindow ("Simple Demo with Shaders"); 15 16 GLenum err = glewInit() ; 17 if (GLEW_OK != err) { 18 std::cerr << "Error: " << glewGetString(err) << std::endl; 19 } 20 21 init(); 22 23 ... 24 }
4.消息回调:
1 // Now, we define callbacks and functions for various tasks. 2 glutDisplayFunc(display); 3 glutReshapeFunc(reshape) ; 4 glutKeyboardFunc(keyboard); 5 glutMouseFunc(mouse) ; 6 glutMotionFunc(mousedrag) ;
5.视图(取决于物体位置和摄像机的属性)
1)两种矩阵栈(旧式风格):GL_MODELVIEW_MATRIX、GL_PROJECTION_MATRIX,用于物体和摄像机的矩阵变换;
2)一般情况下,摄像机位于坐标系原点上,朝向-Z方向;
3)在OpenGL中,矩阵元素存储是列优先的;在新的GLM中,矩阵元素存储为行优先,在编码中需要重点注意;
6.Base initialization code for viewing
1 void init (void) 2 { 3 ... 4 5 /* select clearing color */ 6 glClearColor (0.0, 0.0, 0.0, 0.0); 7 8 /* initialize viewing values */ 9 glMatrixMode(GL_PROJECTION); 10 glLoadIdentity();//读入单位矩阵 11 12 // Think about this. Why is the up vector not normalized? 13 glMatrixMode(GL_MODELVIEW) ; 14 glLoadIdentity() ;//读入单位矩阵 15 16 gluLookAt(0,-eyeloc,eyeloc,0,0,0,0,1,1) ;//OpenGL会自动进行单位化 17 18 ... 19 }
L6V3:OPENGL 1:窗口系统交互和回调函数
1.窗口系统交互 -> GLUT(Not part of OpenGL)
2.reshape()和mousedrag()
1)reshape( )始终保持投影区域的宽高比与窗口一致
1 void reshape(int w, int h) 2 { 3 windowWidth = w; 4 windowHeight = h; 5 glViewport (0, 0, (GLsizei) w, (GLsizei) h); 6 glMatrixMode(GL_PROJECTION); 7 glLoadIdentity(); 8 gluPerspective(30.0, (GLdouble)w/(GLdouble)h, 1.0, 10.0) ; 9 }
2)mousedrag( ):通过按住鼠标键拖动,来修改摄像机坐标来实现缩放功能
1 void mousedrag(int x, int y) { 2 int yloc = y - mouseoldy ; // We will use the y coord to zoom in/out 3 eyeloc += 0.005*yloc ; // Where do we look from 4 if (eyeloc < 0) eyeloc = 0.0 ; 5 mouseoldy = y ; 6 7 /* Set the eye location */ 8 glMatrixMode(GL_MODELVIEW) ; 9 glLoadIdentity() ; 10 gluLookAt(0,-eyeloc,eyeloc,0,0,0,0,1,1) ; 11 12 glutPostRedisplay() ; 13 }
其中,glutPostRedisplay()告诉GLUT尽可能快地排队等候显示函数,然后重绘场景进行显示。
L6V4:OPENGL 1:绘制
1.Geometry:
1)Point(GL_POINTS);
2)Line segments(GL_LINES);
3)Polygons(复杂图形采用GLU进行三角化);
4)其他特殊图形(GLUT引入),如Sphere、teapot、cube。
2.旧式绘制方法(采用客户服务器模型形式) ->易上手
1)将顶点添加在 glBegin()...glEnd()中间;
2)在定义顶点前,必须先定义颜色;
1 void display(void){ 2 glClear(GL_COLOR_BUFFER_BIT); 3 4 glBegin(GL_POLYGON); 5 6 glColor3f(1.0, 0.0, 0.0); 7 glVertex3f(0.5, 0.5, 0.0); 8 glColor3f(0.0, 1.0, 0.0); 9 glVertex3f(-0.5, 0.5, 0.0); 10 glColor3f(0.0, 0.0, 1.0); 11 glVertex3f(-0.5, -0.5, 0.0); 12 glColor3f(1.0, 1.0, 1.0); 13 glVertex3f(0.5, -0.5, 0.0);
14 15 glEnd(); 16 glFlush(); 17 }
其中,glFlush( )为同步指令,清理队列。
3.新式绘制方法(Vertex Buffer Objects)
1)定义多种类型的信息,分为顶点数组、颜色数组、索引数组;
2)建立顶点缓存对象、图元类型、缓存偏移量;
3)绑定缓存;
备注:此处详细看作业代码部分。
L6V5:OPENGL 1:初始化着色器
1.步骤:
1)Create shader(Vertex and Fragment);
2)Compile shader;
3)Attach shader to program;
4)Link program;
5)Use program。