今天学习了材质,奉上源代码:
#pragma comment(lib, "glaux.lib")
#include "gl\glaux.h"
#include <gl\glut.h>
float yRot = 0;
unsigned int nPre = 0;
void display(void)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清楚颜色数据和深度数据(清屏)
glColor3f(1.0,1.0,1.0);
glLoadIdentity(); //初始变换矩阵为单位矩阵
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
GLfloat no_mat[] =
{0.0, 0.0, 0.0, 1.0};
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
GLfloat mat_ambient[] =
{1.0, 1.0, 1.0, 1.0};
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
GLfloat mat_diffuse[] =
{1.0, 1.0, 1.0, 1.0};
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
GLfloat mat_specular[] =
{1.0, 1.0, 1.0, 1.0};
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
GLfloat no_shininess[] =
{0.0};
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
GLfloat low_shininess[] =
{5.0};
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
GLfloat hig_shininess[] =
{100.0};
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
GLfloat mat_emission[] =
{0.3,0.8, 0.0, 1.0};
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
glPushMatrix(); //压入变换矩阵那
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//材质设置有效一直保持到改变为止。
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//第一行第一列的球,仅有慢反射光,而无环境光喝镜面光。
glPushMatrix();
glTranslatef(-3.75, 3.0, 0.0); //第一个球的位置
glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
glutSolidSphere(1, 30,30);//利用库函数绘制一个半径为1的球体。
glPopMatrix(); //弹出矩阵。
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//第一行第二列的球,有漫反射光喝镜面光,低高光,并无环境光
glPushMatrix();
glTranslatef(-1.25, 3.0, 0.0);
glMaterialfv(GL_FRONT,GL_AMBIENT, no_mat);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT,GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT,GL_SHININESS, low_shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
glutSolidSphere(1, 30,30);//利用库函数绘制一个半径为1的球体。
glPopMatrix();
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//第一行第三列绘制的球有漫反射光和镜面光,并有很亮的高光,而无环境光
glPushMatrix();
glTranslatef(1.25, 3.0, 0.0);
glMaterialfv(GL_FRONT,GL_AMBIENT, no_mat);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT,GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT,GL_SHININESS, hig_shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
glutSolidSphere(1, 30,30);//利用库函数绘制一个半径为1的球体。
glPopMatrix();
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//第一行第四列绘制的球有漫反射光和辐射光,而无环境和镜面反射光
glPushMatrix();
glTranslatef(3.75, 3.0, 0.0);
glMaterialfv(GL_FRONT,GL_AMBIENT, no_mat);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT,GL_SPECULAR, no_mat);
glMaterialfv(GL_FRONT,GL_SHININESS, hig_shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
glutSolidSphere(1, 30,30);//利用库函数绘制一个半径为1的球体。
glPopMatrix();
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
glPopMatrix(); //这里会沿用以前的设置的材质。
glTranslatef(3.75, 0.0, 0.0);
glutSolidSphere(1, 30,30);//利用库函数绘制一个半径为1的球体。
glPopMatrix();
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//其他的不写了。。
//第二行第一列绘制的球有漫反射光和环境光,而镜面反射光。
//第二行第二列绘制的球有漫反射光、环境光和镜面光,且有低高光
//第二行第三列绘制的球有漫反射光、环境光和镜面光,且有很亮的高光
//第二行第四列绘制的球有漫反射光、环境光和辐射光,而无镜面光
//第三行第一列绘制的球有漫反射光和有颜色的环境光,而无镜面光。
//第三行第二列绘制的球有漫反射光和有颜色的环境光以及镜面光,且有低高光
//第三行第三列绘制的球有漫反射光和有颜色的环境光以及镜面光,且有很亮的高光
//第三行第四列绘制的球有漫反射光和有颜色的环境光以及辐射光,而无镜面光
glutSwapBuffers(); //交换缓冲区。显示图形
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//初始化
void init (void)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
glClearColor (0.5, 0.5, 0.5, 0.0); //清理颜色,为黑色,(也可认为是背景颜色)
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
GLfloat light_diffuse[]=
{ 0.0, 0.0, 1.0, 1.0};//蓝色 //有灯光才能体现材质的效果,他的灯光的强度是与的关系。貌似是两个相乘什么的。(0-1)范围。
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
GLfloat light_position[] =
{ 0, 3, 2.0, 0.0 }; //设置点光源的矩阵,这个向量也忒奇怪了,1不跟着变,0跟着变,设置为透视之后又是1跟着变,0不跟着变。
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
GLfloat light_specular[] =
{ 1.0, 1.0, 0.0, 1.0 }; //反射光
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
GLfloat light_ambient[] =
{0.5, 0.5, 0.5, 1.0};
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); //,漫射光会产生漫射的效果和高光的效果
glLightfv(GL_LIGHT0, GL_POSITION, light_position); //点光源没有漫射光的效果,会一直是黑色的。但会有高光反射的效果。
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); //反射光基本没有效果。可能是我不知道吧
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0); //如果什么都不设置,GL_LIGHT有默认的值。
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//当窗口大小改变时,会调用这个函数
void reshape(GLsizei w,GLsizei h)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
//这里小说明一下:矩阵模式是不同的,他们各自有一个矩阵。投影相关
//只能用投影矩阵。(只是目前情况下哦,等我学多了可能就知道为什么了。)
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
glViewport(0,0,w,h); //设置视口
glMatrixMode(GL_PROJECTION); //设置矩阵模式为投影变换矩阵,
glLoadIdentity(); //变为单位矩阵
//gluPerspective(60, (GLfloat)w / h, 0, 1000); //设置投影矩阵
glOrtho(-6.0, 6.0, -6.0 * h / w, 6.0* h / w, -10, 10); //为了不变形,则要长和宽成比例
glMatrixMode(GL_MODELVIEW); //设置矩阵模式为视图矩阵(模型)
glLoadIdentity(); //变为单位矩阵
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
int main(int argc, char** argv)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
glutInit(&argc, argv); //Opnegl初始化
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA); //设置显示模式为双缓冲,RGEBA
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
glutInitWindowSize (800, 600); //窗口大小
glutInitWindowPosition (100, 100); //窗口位置
glutCreateWindow ("hello"); //创建一个标题为hello的窗口
init (); //初始化资源,这里一定要在创建窗口以后,不然会无效。
glutDisplayFunc(display); //窗口大小改变时的回调
glutReshapeFunc(reshape); //绘制图形时的回调
glutMainLoop(); //主循环。
return 0;
}
1.材质在光的照耀下才能发挥他的作用。没有光,材质是不能显示的。
2.他和光的设置基本一样。光设置的函数是glLightfv(XX,XXX,XX);材质的设置是void glMaterialf(
GLenum face, //设置材质的面片,是前面,后面,还是双面
GLenum pname, //材质的类型,是环境光材质,漫反射,反射,高光,辐射光等
GLfloat param //参数,跟光的参数一样,表示对应的值。
);
材质有环境光,漫反射,镜面反射,辐射,高光等几种设置。里面的颜色参数代表他对该颜色的反射强度,1,最强,0表示完全吸收。也就是说他会跟光做一个乘法。得出来的光就颜色就是反射的我们眼睛的颜色。例如:[1.0, 0.0, 1.0]的材质,本来呈现紫色,如果用[1.0,1.0,1.0]的光去照射就是紫色。如果是[0.0,1.0,1.0]的光照射就是蓝色。因为最后他们各分量相乘得到了[0,0,1]就呈现蓝色了。
4.心的:
补上上次的,点光源设置的是一个位置的向量,他会跟随变换矩阵变化。但是不清楚他的最后一个参数是什么,而且最后一个参数在透视投影和正交投影有相反的表现。哎。还需继续学习。
材质有有保存的,所以如果你设置过材质,一定要注意在新的物体重新设置它的材质,不然会用先前设置的材质。
gluperspective(XXXX)的函数是设置透视矩阵的,因为这次有多个球,想对比更强烈点,书上是用哦正交矩阵
glOrtho(XXX);//他的参数是世界坐标系的点哦。如果想不变形的话,一定要保证长和宽要和窗口的长宽协调。