在真实世界中,每种物体对灯光的反应都不同,我们在OpenGL中定义不同的材质来模拟不同种类的物体。在OpenGL中,我们可以定义一个材质结构体管理对光照的影响信息(比如Phong模型),例如:
这里提供一个 网站 ,总结了一些不同物体的材质.
下面是上面创建的结构体在片元着色器的main方法中的应用(针对Phong模型):
可以看到,我们通过 来访问结构体的属性,这和C语言类似。虽然我们全局声明了材质结构体,但若是要为材质结构体的属性赋值,我们还是必须逐一赋值:
运行程序我们会发现场景太亮:
为解决场景过亮问题,我们可以定义一个灯光结构体:
灯光结构体中的ambient,diffuse,specular分别代表对各个类型光的强度影响。我们可以这样计算各个光照的效果:
设置灯光结构体的属性:
运行结果如下:
可以看到结果好了很多。通过这种方式,我们就可以通过改变属性来模拟不同的材质在不同灯光下的效果。
这个的话先用glEnable(GL_LIGHT0)开启0号光源,之后设置光源位置,position={x,y,z,w},x,y,z是一个向量,代表方向。x/w,t/w,z/w是位置坐标。w为零时,前面三者趋近无穷大,代表平行光。
之后输入glLightfv(GL_LIGHT0, GL_POSITION, position),这样0号光源位置确定。接下来设置环境光线强度,漫反射光线强度,镜面反射光线强度,都是r,g,b,alpha参数,这个知道怎么设吧。
设定好参数后,输入
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse)
glMaterialfv(GL_FRONT, GL_SPECULAR, specular)
glMaterialfv(GL_FRONT, GL_EMISSION, emission)
光源设定完成。
材质设定是glMaterialfv(GL_FRONT, XXXXX,XXXXX)和光线类似,第一个XXXX写GL_DIFFUSE,GL_SPECULAR, GL_EMISSION这类的。多出一个shininess,这个是代表镜面指数,越大耗费资源越多,越精细。
呼~打得好累,最后给你编了一个例子。打了这么多字,别忘了采纳。
#include<gl/glut.h>
#include<stdio.h>
void myDisplay()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(75, 1, 9, 60)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
gluLookAt(0, -20, 20, 0, 0, 0, 0, 0, 1)
{
GLfloat light_position[]={0.0f,0.0f,0.0f,1.0f}
GLfloat light_ambient[]={0.0f,0.0f,0.0f,1.0f}
GLfloat light_diffuse[]={1.0f,1.0f,1.0f,1.0f}
GLfloat light_specular[]={1.0f,1.0f,1.0f,1.0f}
glLightfv(GL_LIGHT0,GL_POSITION,light_position)
glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient)
glLightfv(GL_LIGHT0,GL_DIFFUSE,light_diffuse)
glLightfv(GL_LIGHT0,GL_SPECULAR,light_specular)
glEnable(GL_LIGHT0)
glEnable(GL_LIGHTING)
glEnable(GL_DEPTH_TEST)
}
{
GLfloat mat_ambient[]={0.4f,0.4f,0.4f,1.0f}
GLfloat mat_diffuse[]={0.4f,0.4f,0.4f,1.0f}
GLfloat mat_specular[]={0.7f,0.7f,0.7f,1.0f}
GLfloat mat_emission[]={0.0f,0.0f,0.0f,1.f}
GLfloat mat_shininess=60.0f
glMaterialfv(GL_FRONT,GL_AMBIENT,mat_ambient)
glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse)
glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular)
glMaterialfv(GL_FRONT,GL_EMISSION,mat_emission)
glMaterialf(GL_FRONT,GL_SHININESS, mat_shininess)
glTranslatef(15, 5, 5)
glutSolidSphere(10, 100, 20)
}
glFlush()
glutSwapBuffers()
}
int main(int argc,char *argv[])
{
glutInit(&argc,argv)
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE)
glutInitWindowPosition(100,100)
glutInitWindowSize(800,800)
glutCreateWindow("一个灰球")
glutDisplayFunc(&myDisplay)
glutMainLoop()
return 0
}
OpenGL可以读取模型的顶点,材质需要在OpenGL中进行设置,一般使用.bmp格式的图片作为模型的纹理贴图。我是用3DExploration将.3ds的文件转化成.cpp文件(存放顶点数组)载入OpenGL程序中,纹理贴图另外指定。欢迎分享,转载请注明来源:内存溢出
评论列表(0条)