小狼学习原创,欢迎批评指正
先上代码
#include "stdafx.h" #include <windows.h> #include "iostream" #include "GL/glut.h" #include "math.h" #define windowsWidth 500 #define windowsHeight 500 using namespace std; int preX,preY; bool leftState=false; bool rightState=false; float angleX=0.0; float angleY=0.0; float angleY1=0.0; float angleY2=0.0; float angleX1=0.0; float angleX2=0.0; void init() { GLfloat mat_diffuse[4] = {0.5,0.5,0.5,1}; GLfloat mat_specular[] = {1,1,1,1}; GLfloat mat_ambient[] = {1,1,1,1}; GLfloat light_position[] = {1,1,1,0}; glClearColor(0,0,0,0); glShadeModel(GL_SMOOTH); glEnable(GL_DEPTH_TEST); glMaterialfv(GL_FRONT,GL_AMBIENT,mat_ambient);//环境光(全局环境光) glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);//散射光(很微弱的光,感觉像是从各种的物体反射的光) glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);//反射光(像高光) glMaterialf(GL_FRONT,GL_SHININESS,25.0); glLightfv(GL_LIGHT0,GL_POSITION,light_position); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glColorMaterial(GL_FRONT,GL_DIFFUSE); glEnable(GL_COLOR_MATERIAL); glClear(GL_COLOR_BUFFER_BIT); glRotatef(angleX1,0.0,1.0,0.0); glRotatef(angleY1,-1.0,0.0,0.0); glBegin(GL_DIFFUSE); glColor3f(0.0f,0.0f,1.0f); glutSolidTeapot(0.6f); cout<<"init"<<endl; } void KeyPressFunc(int key, int x, int y) { if(key==GLUT_KEY_UP) { angleY1 = 1; angleX1 = 0; glutPostRedisplay();//重绘图像 } else if(key==GLUT_KEY_DOWN) { angleY1 = -1; angleX1 = 0; glutPostRedisplay(); } else if(key==GLUT_KEY_RIGHT) { angleX1 = 1; angleY1 = 0; glutPostRedisplay(); } else if(key==GLUT_KEY_LEFT) { angleX1 =- 1; angleY1 = 0; glutPostRedisplay(); } } void randerScene() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); init(); glFlush(); //ERROR cout<<"shuaxin"<<endl; } void reshape(int w, int h) { glViewport(0,0,(GLsizei)w,(GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) { glOrtho(-1.5,1.5,-1.5*(GLfloat)w/(GLfloat)h,1.5*(GLfloat)w/(GLfloat)h,-10,10); } else { glOrtho(-1.5*(GLfloat)w/(GLfloat)h,1.5*(GLfloat)w/(GLfloat)h,-1.5,1.5,-10,10); } glMatrixMode(GL_MODELVIEW); glLoadIdentity(); randerScene(); } void IdleFunc() { angleY1 = 0; angleX1 = 0.1; glutPostRedisplay();//重绘图像 } void setupRc() { glClearColor(0.5f,0.5f,0.5f,1.0f); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ); glShadeModel (GL_FLAT);//光滑着色 } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH | GLUT_STENCIL ); glutInitWindowPosition(100, 100); glutInitWindowSize(400, 400); glutCreateWindow("teapot"); init(); glutDisplayFunc(randerScene); setupRc(); glutSpecialFunc(KeyPressFunc); // glutIdleFunc(IdleFunc);//空闲状态执行函数(取消注释茶壶自行旋转) glutReshapeFunc(&reshape); glutMainLoop(); return 0; }
这是一个受很多光照着Front(前面)的蓝色小茶壶,
分析下代码,从init(初始化)开始,
glShadeModel();这个是选择着色方式的函数,
如果里面的参数是GL_SMOOTH,那就是光滑着色,有渐变的效果,
如果参数是GL_FLAT,那就是平面着色,没有渐变效果,都是一个颜色,
而这只有在定点颜色不同时才有区别,
作为光滑smooth模式,右图为flat平面模式
应用光滑处理模式时,多边形所有点的法向是由内插生成的,具有一定的连续性,因此每个点的颜色也相应内插,故呈现不同色。这种模式下,插值方法采用的是双线性插值法
通常算法为:先用多边形顶点的光强线性插值出当前扫描线与多边形边交点处的光强,然后再用交点的光强线插值处扫描线位于多边形内区段上每一象素处的光强值。
图中显示出一条扫描线与多边形相交,交线的端点是A点和B点,P点是扫描线上位于多边形内的任一点,多边形三个顶点的光强分别为I1、I2和I3.
取A点的光强Ia为I1和I2的线性插值,B点的光强Ib为I1和I3的线性插值,P点的光强Ip则为Ia和Ib的线性插值。
处理后可以使用多边形表示的曲面光强连续,而且计算量很小。这种算法还可以以增量的形式改进,且能用硬件直接实现算法,从而广泛用于计算机实时图形生成
接下来是光照部分的重点函数,glMaterial(),
他有glMaterialf, glMateriali, glMaterialfv, glMaterialiv。这四种形式,
如果是
void glMaterialf(GLenum face, GLenum pname, GLfloat para) void glMateriali(GLenum face, GLenum pname, GLint para)
void glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) void glMaterialiv(GLenum face, GLenum pname, const GLint *params)
这些设置的都是GL_LIGHTn的属性(GL_LIGHT0,GL_LIGHT1,GL_LIGHT2。。。。一个又一个的光源),
GL_LIGHT0属性的默认值与其他不同,需要注意
p.s.只有
【狼】openGL 光照的学习,布布扣,bubuko.com
原文:http://www.cnblogs.com/zhanlang96/p/3859439.html