01
一个简单的OpenGL程序(内部一些常见的参数)
#include <GL/glut.h>
void mydisplay(){
glClear(GL_COLOR_BUFFER_BIT);
//glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_POLYGON);
glVertex2f(-0.5, -0.5);
glVertex2f(-0.5, 0.5);
glVertex2f(0.5, 0.5);
glVertex2f(0.5, -0.5);
glEnd();
glFlush();
}
int main(int argc, char** argv){
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(500,500);
glutInitWindowPosition(0,0);
glutCreateWindow("simple");
glutDisplayFunc(mydisplay);
init();
glutMainLoop();
}
02
glutMainLoop()是一个在我们所有图形语言中驱动主要操作的函数. 这个函数被无限期迭代. 在每次迭代中, 它检查事件队列是否为空.
03
04
marching cube算法是一种用来计算等值线isocurve(或等值面isosurface)的常用算法,其基本思想是线性插值逼近等值线(或等值面),下面以二维为例介绍其计算过程。
1、在平面上构建m*n的网格,利用已知的函数v=f(x,y)求出网格节点的值;
2、根据所要求的值(iso-value)在相邻节点之间插值标出相应点;
3、根据第二步所得到的点,在同一网格内连接成线,即求得相应的等值线。
注意:使用marching cube算法一定要有快速计算网格节点值的方法,要么用函数v=f(x,y),要么直接硬件测量得到
05
绘制滑动五彩小正方形
#include <GL/gl.h>
#include <GL/glut.h>
/* globals */
GLsizei wh = 500, ww = 500; /* initial window size */
GLfloat size = 3.0; /* half side length of square */
void drawSquare(int x, int y)
{
y = wh-y;
glColor3f( (char) random()%256, (char) random()%256,
(char) random()%256);
glBegin(GL_POLYGON);
glVertex2f(x+size, y+size);
glVertex2f(x-size, y+size);
glVertex2f(x-size, y-size);
glVertex2f(x+size, y-size);
glEnd();
glFlush();
}
void myReshape(GLsizei w, GLsizei h)
{
/* adjust clipping box */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, (GLdouble)w, 0.0, (GLdouble)h, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
/* adjust viewport and clear */
glViewport(0,0,w,h);
glClearColor (0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
/* set global size for use by drawing routine */
ww = w;
wh = h;
}
void myinit(void)
{
glViewport(0,0,ww,wh);
/* Pick 2D clipping window to match size of screen window
This choice avoids having to scale object coordinates
each time window is resized */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, (GLdouble) ww , 0.0, (GLdouble) wh , -1.0, 1.0);
/* set clear color to black and clear window */
glClearColor (0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
}
void mouse(int btn, int state, int x, int y)
{
if(btn==GLUT_RIGHT_BUTTON&state==GLUT_DOWN) exit();
}
int main(int argc, char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutCreateWindow("square");
myinit ();
glutReshapeFunc (myReshape);
glutMouseFunc (mouse);
glutMotionFunc(drawSquare);
glutMainLoop();
}
06
橡皮筋技术
基于异或操作的橡皮筋技术利用了异或逻辑操作的重要性质:值A与值B两次异或,其值仍然为A;异或逻辑运算如下图所示:也就是:
A | B | A异或B | A异或B异或B |
---|---|---|---|
1 | 1 | 0 | 1 |
1 | 0 | 1 | 1 |
0 | 1 | 1 | 0 |
0 | 0 | 0 | 0 |
将这个性质应用到像素的颜色上,则可以利用两次异或操作恢复本来的像素颜色。即:将图形显示方式设置为异或模式(如Visual C++中的函数SetROP2),画出图形(此时图形是可见的),在异或模式下,将相同的图形再画一遍,这个图形将会从屏幕上消失,而原来被它覆盖的部分将恢复如初。
07
OpenGL绘制流水线及各个模块的功能
- 顶点处理
该模块的两个主要功能是执行坐标变化和计算每一个顶点的颜色值 - 裁剪和图元组装
由于成像系统不可能一次对整个场景成像,我们必须进行裁剪;图元组装是把顶点组装成像线段和多边形这样的图元 - 光栅化
光栅化模块必须确定在帧缓存中那些像素位于图元的内部,该模块对于每个图元输出一组片元 - 片元处理
片元可以看做是携带相关信息的潜在像素,该模块利用光栅化模块生成的片元来更新帧缓存中的像素
08
双缓存原理及调用设置参数
图形硬件具有两个帧缓存,其中一个帧缓存用于显示图像,我们称之为前端缓存,另一个称之为后端缓存,用于存储用户需要显示的内容。一段完成了场景的绘制,就可以交换前端缓存和后端缓存的内容,然后清除后端缓存并写入新的数据
glSwapBuffer();
gluInitDisplayModel(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
09
OpenGL的坐标系:
- 对象坐标系
- 世界坐标系
- 照相机坐标系
- 裁剪坐标系
- 规范化的设备坐标系
- 屏幕坐标系
10
正交投影规范化
使用平移和旋转变换将照相机坐标系下的顶点变换到默认的视见体内部成为投影规范化,使得变形后的对象的正交投影与原来想得到的对象的投影图相同
投影变换矩阵:
10
phong模型以及改进的phong模型
(1)phong反射模型有4个向量:n,v,l,r。对于表面上任意一点p,向量n是p点处的法向量,向量v是从p指向观察者的向量。向量l是从点p指向点光源的向量。向量r的方向是从沿着向量l方向入射的光线按照反射定律的出射方向。phong反射模型考虑了光线和材质之间的相互作用:环境光反射,漫反射,镜面反射
(2)改进的phong模型
引入一个新的向量——半角向量,半角向量位于观察向量v和光源向量l这两者正中间,在改进的phong模型中(又称blinn-phong模型),利用半角向量计算镜面反射分量r
11
phong着色和gouraud着色的特点
(1)gouraud着色:在这种明暗绘制方法中,我们对公用一个顶点的多边形的法向量取平均值,把归一化后的平均值定义为该顶点的法向量,这种方法可以获得更平滑的插值效果,降低March带的效果
(2)phong着色:在多边形内部对方向量进行插值(gouraud是对顶点的明暗值进行插值),为了求出某个顶点的法向量,我们对公用该顶点的多边形的法向量进行插值。
12
梁友栋算法(liang-barsky算法)
13
bresenham算法