OpenGL中能渲染的基本元素是什么?(曲面)
OPENGL基本元素:
GL_POINTS GL_LINES GL_POLYGON GL_LINE_STRIP
GL_LINE_LOOP GL_TRANGLES GL_TRANGLE_STRIP GL_TRANGLE_FAN GL_QUADS GL_QUAD_STRIP
GLU基本元素:NUBRS曲线曲面,二次曲面等
2.用框图说明OpenGL的渲染流程,并简要说明每个坐标系。
顶点
投影变换
模型视图变换
裁剪空间
裁切测试
Alpha测试
模版测试
深度测试
帧缓存区
片元测试
提取纹理单元用于纹理应用;
纹理坐标计算,采样纹理应用;
法向量计算;
fog;
主颜色辅颜色混合
片元处理
光栅化
ViewPort
除法
标准坐标系
屏幕空间
光照计算
3.写出OpenGL中局部光照的方程,要包含的系数有光源参数、材料参数、聚光灯的参数、衰减参数等,方程要表示是多个光源的。
Norm(X):单位化X
N:顶点的单位化法向量
V:聚光灯指向顶点的向量
D:聚光灯的方向向量,它是单位向量
T:顶点到光源的向量,当光源是聚光灯时,即为-V
P:顶点到视点的向量
L:N*Norm(T)
S:Norm(T+P)
顶点颜色=材料自发光+
环境光颜色*材料的环境颜色属性+
对每个聚光灯加上(聚光灯衰减因子*聚光灯的效果)*
[光源的环境颜色*材料的环境颜色+
取Max{L,0}*漫反射光颜色*材料的漫反射属性+
取(Max{S*N,0})shininess * 灯的反射值*材料的反射属性
其中shininess为镜面反射指数
后半部分即:
每个光源的贡献=衰减因子*聚光灯效果*(环境光成分+漫反射成分+镜面反射成分)
聚光的衰减因子=
聚光灯效果:
光源不是聚光灯,取1
光源是聚光灯但是顶点位于光源外,取0
其它:(Max{V*D,0})exp (exp为镜面反射指数值)
4.分析程序并计算
5.在OpenGL中,使用纹理的步骤是什么?纹理坐标和纹理都可以通过程序计算出来,自动生成纹理的原理是什么?
步骤:1、创建纹理对象,并为它指定一个纹理。
2、确定这个纹理如何应用到每个象素上。
3、启用纹理贴图功能。
4、绘制场景,提供纹理坐标和几何图形坐标。
投影纹理:通过应用一系列的变换,可以把物体坐标中的坐标映射到一个2D空间(纹理空间)中,并找出每个顶点映射到纹理的哪个部分,然后把这个位置当作纹理坐标给顶点。变换的过程是将物体坐标进行MODEL变换统一到一个世界坐标系,再进过Projector的VIEW矩阵变换投影的视点(Projector View)空间下,然后通过透视矩阵,最后要进行一部缩放和偏移的变换,这样就生成了它的投影纹理。
多重纹理:多重纹理是指对一个多边形映射多个纹理。在纹理映射的过程中,对各个纹理单元中的纹理,通过纹理组合函数,逐个应用到多边形上。使用多重纹理时,有多个纹理单元和多个纹理坐标,OPENGL渲染时对每个纹理进行单独的纹理操作,并把结果传递到下一个纹理单元中,即每个纹理单元根据它的纹理状态,把原来的片元颜色与纹理单元中的图像以一定的方式进行组合,把把产生的片元颜色传递到下一个纹理单元,在纹理组合时,OPENGL通过指定的纹理组合函数,如GL_REPLACE,GL_ADD,GL_MODULATE等方式。
6.帧缓存有几种,什么叫片元。片元的测试和操作有哪些?
颜色缓存:包括左前,右前,左后,右后及任意数量的辅助颜色缓存。
深度缓存,模板缓存,累积缓存。
明白stencilbuffer(模板缓冲区)的使用。
模板测试常用的是屏蔽掉屏幕中一些不规则的区域,以免在这些区域中进行绘图。使用glStencilFunc()和glStencilOp()函数选择需要使用的特定比较函数,参考值以及对模板缓冲区所执行的修改操作。
模板测试的结果决定了像素的颜色值是否要被写入到渲染目标,像素的深度值是否要被写入深度缓冲。
例如,当参考模板值为0时将一些物体绘制到场景中,而此时模板缓冲已经清除为1,那么当绘制这些物体时模板缓冲就会为0。如果接着将参考值设置为1,而且StencilFunction设置为 CompareFunction.LessEqual,那么只有那些模板值不为0的对应区域的像素会被绘制。这是使用模板缓冲创建一个当前绘制区域的基本用法。
要使用模板缓冲,DepthFormat必须保留一些字节用于模板缓冲。
片元:光栅化时处理的基本单位(像素),包括了点的法线,坐标,贴图坐标等信息。
片元的测试按下列的顺序进行,如果在前面的测试中片元被删除,则不在进行后续的测试或操作。
1.剪取测试:利用glScissor()函数定义窗口中的一个矩形,并将图在其中。
2.alpha测试:利用alpha值来确定或是拒绝一个片元。利用glEnable()使用参数GL_ALPHA_TEST激活。哟哦那个glAlphaFunc()来比较。用来实现透明算法和纹理图制作贴花。
3.模板测试:对存储于模板缓存中的像素值与参考值进行比较,根据比较的结果来对模板缓存中的值进行修改。glStencilOp().
4.深度测试:用于消除隐藏表面的操作。glDepthFunc()来设置比较函数。
用stencilbuffer编程实现一个功能。
镜面功能:
实现此功能需要进行两次绘制,首先对所有非镜像物体进行绘制,这个时候不需要对模板缓冲进行任何修改;之后绘制镜面,不过是绘制在模板缓冲上,表示只有镜子之块区域在下一次绘制的时候可以通过模板测试,之后对所有的镜像物体(当然需要对所有物体进行镜像变换,即点减去表示此点到镜像平面最短距离的向量的两倍,镜像矩阵根据上面的所述推出)进行绘制,由于我们设置了模板缓冲,故这一次绘制只会绘制在镜子所覆盖的那块区域,于是,我们的镜像效果就出来了。
5.
6.不考
7.如何实现纹理的反走样?说明其原理。
Mip-map技术可以实现纹理反走样,通过设置不同级别(即不同程度的缩放纹理)的纹理贴图。我们在绘制的时候如果绘制的纹理需要被缩放,就对相邻两个级别所对应位置的纹理值进行插值计算以得到我们需要的颜色值。
对场景的反走样,通常采用多重采样的方法。多重采样的方法使用额外的颜色,深度和模版信息对图元进行反走样处理。每个片元是根椐子像素样本的数量和信息来计算,也就是根据一个多重采样缓冲区所保存的样本来计算。
一种是扰动视点的方法,也就是多次绘制这个场景,每次绘制时,对视点进行抖动,作一点轻微的偏移,当整个渲染过程完结后,再把所有图象叠加起来,由于每个图象的位置不同,可以减轻锯齿状。
8.不考
9.不考
10.请用OBJ格式表示一个长度为10的立方体,并把每个面分别贴上图片文件,。
三种常见格式:.obj .x .3ds .vrml
a.obj mtllib a.mtl
# 8 vertices
v 0.0 0.0 0.0
v 0.0 10.0 0.0
v 0.0 10.0 10.0
v 0.0 0.0 10.0
v 10.0 0.0 0.0
v 10.0 10.0 0.0
v 10.0 10.0 10.0
v 10.0 0.0 10.0
#normals
nv 0.0 0.0 1.0
nv 0.0 0.0 -1.0
nv 0.0 1.0 0.0
nv 0.0 -1.0 0.0
nv 1.0 0.0 0.0
nv -1.0 0.0 0.0
vt 0.0 0.0
vt 1.0 0.0
vt 1.0 1.0
vt 1.0 1.0
g posx_map
usemtl posx_map
f 4/1/6 2/2/6 1/3/6 3/4/6
g posy_map
usemtl posy_map
f 2/1/4 6/2/4 5/3/4 1/4/4
g negx_map
usemtl negx_map
f 6/1/5 8/2/5 7/3/5 5/4/5
g negy_map
usemtl negy_map
f 8/1/3 4/2/3 3/3/3 7/4/3
g posz_map
usemtl posz_map
f 7/1/2 3/2/2 1/3/2 5/4/2
g negz_map
usemtl negz_map
a.mtl
newmtl posx_map
Ka 0.968600 0.968600 0.968600
Kd 0.968600 0.968600 0.968600
Ks 0.900000 0.900000 0.900000
newmtl posy_map
Ka 0.968600 0.968600 0.968600
Kd 0.968600 0.968600 0.968600
Ks 0.900000 0.900000 0.900000
newmtl posz_map
Ka 0.968600 0.968600 0.968600
Kd 0.968600 0.968600 0.968600
Ks 0.900000 0.900000 0.900000
newmtl negx_map
Ka 0.968600 0.968600 0.968600
Kd 0.968600 0.968600 0.968600
Ks 0.900000 0.900000 0.900000
newmtl negy_map
Ka 0.968600 0.968600 0.968600
Kd 0.968600 0.968600 0.968600
Ks 0.900000 0.900000 0.900000
newmtl negz_map
Ka 0.968600 0.968600 0.968600
Kd 0.968600 0.968600 0.968600
Ks 0.900000 0.900000 0.900000
11.分析下面的程序并计算
在下面的例子中,计算对应四个顶点所对应的四边形上的一个点(-1.5, 0.5, 0.0)对应的纹理坐标是多少?按照最近邻域滤波方法,该点对应的颜色是什么?写出详细的计算过程,只有结果将不给分。
#define checkImageWidth
#define checkImageHeight
static GLubyte checkImage[checkImageHeight][checkImageWidth][4];
static GLuint texName;
void makeCheckImage(void)
{
int i, j, c;
for (i = 0; i < checkImageHeight; i++) {
for (j = 0; j < checkImageWidth; j++) {
c = ((((i&0x8)==0)^((j&0x8))==0))*255;
checkImage[i][j][0] = (GLubyte) c;
checkImage[i][j][1] = (GLubyte) c;
checkImage[i][j][2] = (GLubyte) c;
checkImage[i][j][3] = (GLubyte) 255;
}
}
}
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);
makeCheckImage();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &texName);
glBindTexture(GL_TEXTURE_2D, texName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth, checkImageHeight,
0, GL_RGBA, GL_UNSIGNED_BYTE, checkImage);
}
void display(void)
{ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glBindTexture(GL_TEXTURE_2D, texName);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, -1.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-2.0, 1.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(0.0, 1.0, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f(0.0, -1.0, 0.0);
glEnd();
glFlush();
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 30.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -3.6);
}
int main(int argc, char** argv)
{ glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(250, 250);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
}
四个顶点所对应的四边形形上的一个点(-1.0,0.5,0.0)对应的纹理坐标是(0.75,0.75)
颜色矩阵是*所以,【48】【48】,接着是与运算和异或运算得出,按照最近临域滤波方法,该店、点对应的黑颜色设双线性混合因子为:x水平方向,y竖直方向:
V点的x,y为
x=d1/v1v2;
y=d3/V2V3ss
2.V的纹理坐标=V2*x*y+V3*(1-x)*y+v1*x*(1-y)+V4(1-x)(1-y);
写成矩阵形式:
4.根据上面公司计算出的V点的纹理坐标去求取屏幕相应位置的像素值,函数如下:
Color4 GetTextureColor(float s, float t)
{
Int x = (int)( s * width );
Int y = (int)( t*height);
Return texture_buffer[ x*width + y];}下载本文