OpenGL学习4

来源:互联网 发布:linux 防御ddos 编辑:程序博客网 时间:2024/05/22 00:30

//三个球体 加入光照和材质
#include <windows.h>
#include <GL/glut.h>
GLfloat light_position[] = {0.0,3.0,6.0,0.0};//光源位置
GLfloat no_mat[] = {0.0,0.0,0.0,1.0};//材料的辐射光颜色
GLfloat mat_grey_ambient[] = {0.5,0.5,0.5,1.0};
GLfloat mat_red_ambient[] = {0.0,0.0,1.0,1.0};
GLfloat mat_diffuse[] = {0.8,0.2,0.5,1.0};
GLfloat mat_specular[] = {1.0,1.0,1.0,1.0};
GLfloat no_shininess[] = {0.0};
GLfloat low_shininess[] = {5.0};
GLfloat high_shininess[] = {100.0};
GLfloat mat_emission[] = {0.3,0.2,0.2,0.0};

void myInit(void)
{
//void glLightfv( GLenum light , GLenum pname , TYPE param )
//参数light指定所创建的光源号,如 GL_LIGHT0 ,GL_LIGHT1 ,GL_LIGHT2 ... ...
//参数pname指定光源特性
//参数param设置相应光源特性值
//pname 参数名 缺省值 说明   
//GL_AMBIENT ( 0.0 , 0.0 , 0.0 , 1.0 ) 环境光的颜色
//GL_DIFFUSE  ( 1.0 , 1.0 , 1.0 , 1.0 )  漫反射光的颜色
//GL_SPECULAR ( 1.0 , 1.0 , 1.0 , 1.0 )  镜面光的颜色
//GL_POSITION ( 0.0 , 0.0 , 1.0 , 0.0 )  光源位置坐标
//GL_SPOT_DIRECTION ( 0.0 , 0.0 , -1.0 ) 点光源聚光方向矢量
//GL_SPOT_EXPONENT 0.0  点光源聚光指数
//GL_SPOT_CUTOFF 180.0 点光源聚光截止角
//GL_CONSTANT_ATTENUATION 1.0 常数衰减因子
//GL_LINER_ATTENUATION 0.0 线性衰减因子
//GL_QUADRATIC_ATTENUATION 0.0 平方衰减因子
//注:只有 GL_LIGHT0 的 GL_DIFFUSE 和 GL_SPECULAR 的缺省值为 ( 1.0 ,1.0 ,1.0 ,1.0 )
//其他光源的 GL_DIFFUSE 和 GL_SPECULAR 缺省值均为 ( 0.0 ,0.0 ,0.0 ,1.0 )
glLightfv(GL_LIGHT2,GL_POSITION,light_position);//设置光源
glEnable(GL_DEPTH_TEST);//激活深度比较
glDepthFunc(GL_LESS);//指定深度比较中使用的数值
glEnable(GL_LIGHTING);// 启用光照
glEnable(GL_LIGHT0); // 启用指定光源
glShadeModel(GL_SMOOTH);
}

void display(void)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glPushMatrix();
/*为光照模型指定材质参数*/
//glMaterial为光照模型指定材质参数。
//第一个参数为改变材质的面,其值必为GL_FRONT, GL_BACK或GL_FRONT_AND_BACK中的一个。
//第二个参数为需要改变的材质参数。第三个参数为赋给参数二的值或指向值的指针
glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);//定义材质的漫反射光
glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);//定义材质的镜面反射光
glMaterialfv(GL_FRONT,GL_SHININESS,high_shininess);//定义反射光亮度
//过GL_EMISSION定义一个RGBA值,使物体看起来象发出这种颜色的光一样。
//而现实中,除光源外,其他物体都不发光;可以利用这一特性来模拟光源。
glMaterialfv(GL_FRONT,GL_EMISSION,no_mat);//材料的辐射光颜色

glColorMaterial(GL_FRONT,GL_AMBIENT);//使材质色跟踪当前颜色
glEnable(GL_COLOR_MATERIAL);

/*第一个球形*/
//一些移动或旋转等变换后,使用glPushMatrix();
//OpenGL 会把这个变换后的位置和角度保存起来。
//然后你再随便做第二次移动或旋转变换,再用glPopMatrix();
//OpenGL 就把刚刚保存的那个位置和角度恢复。
glPushMatrix();
glColor3fv(no_mat);//设置当前颜色
glTranslatef(-2.5,1.5,0.0);//模型相对照相机焦点平移
//该函数中第一个变量angle制定模型旋转的角度,
//单位为度,后三个变量表示以原点(0,0,0)到点(x,y,z)的连线为轴线逆时针旋转物体。
//例如,glRotatef(-30.0,0.0,0.0,1.0)的结果是绕z轴顺时针旋转90.0度。
glRotatef(15.0,1.0,0.0,0.0);
//绘制实心球体
//参数:
//radius:球体的半径
//slices:球体围绕z轴分割的数目
//stacks:球体沿着z轴分割的数目
//绘制中心在模型坐标原点,半径为radius的球体,球体围绕z轴分割slices次,球体沿着z轴分割stacks次
glutSolidSphere(1.2,20.0,20.0);//这是绘制几何体类函数中的一个。此函数绘制一个球体。
glPopMatrix();//堆栈操作,见glPushMatrix()

/*第二个球形*/
glPushMatrix();
glColor3fv(mat_grey_ambient);
glRotatef(15.0,1.0,0.0,0.0);
glutSolidSphere(1.4,20.0,20.0);
glPopMatrix();

/*第三个球形*/
glPushMatrix();
glColor3fv(mat_red_ambient);
glTranslatef(2.5,-1.5,0.0);
glRotatef(15.0,1.0,0.0,0.0);
glutSolidSphere(1.6,20.0,20.0);
glPopMatrix();

glDisable(GL_COLOR_MATERIAL);//关闭材质模式
glPopMatrix();

glFlush();
}

void myReshape(int w,int h)
{
glViewport(0,0,(GLsizei)w,(GLsizei)h);//设置视口 左下角的坐标(0,0)
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

if(w <= h)
glOrtho(-5.5,5.5,-5.5*(GLfloat)h/(GLfloat)w,5.5*(GLfloat)h/(GLfloat)w,-5.5,5.5);
else
glOrtho(-5.5*(GLfloat)w/(GLfloat)h,5.5*(GLfloat)w/(GLfloat)h,-5.5,5.5,-5.5,5.5);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

int main(int argc,char ** argv)
{
/*初始化*/
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(400,400);
glutInitWindowPosition(100,100);

/*创建窗口*/
glutCreateWindow(" Light&Material ");

/*绘制与显示*/
myInit();
glutReshapeFunc(myReshape);
glutDisplayFunc(display);

glutMainLoop();
return 0;
}

//四个控制点 Bezier曲线
#include "windows.h"
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <GL/glaux.h>
#include <GL/glaux.h>
void myinit(void);
void CALLBACK myReshape(GLsizei w, GLsizei h);
void CALLBACK display(void);
//控制Bezier曲线的四个点
GLfloat ctrlpoints[4][3]={{-4.0,-4.0,0.0},{-2.0,4.0,0.0},{2.0,-4.0,0.0},{4.0,4.0,0.0}};
void myinit(void)
{
glClearColor(0.0, 0.0, 0.0, 1.0);//设置背景颜色 黑色
//OpenGL通过一种求值器的机制来产生曲线和曲面
//OpenGL中使用glMap1*()函数来创建一维求值器
//函数的第一个参数target指出控制顶点的意义以及在参数points中需要提供多少值,
//GL_MAP1_VERTEX_3  x,y,z顶点坐标
//GL_MAP1_VERTEX_4 x,y,z,w 顶点坐标
//GL_MAP1_INDEX 颜色表
//GL_MAP1_COLOR_4 R,G,B,A
//GL_MAP1_NORMAL  法向量
//GL_MAP1_TEXTURE_COORD_1 s 纹理坐标
//GL_MAP1_TEXTURE_COORD_2 s,t 纹理坐标
//GL_MAP1_TEXTURE_COORD_3 s,t,r 纹理坐标
//GL_MAP1_TEXTURE_COORD_4 s,t,r,q 纹理坐标
//参数points指针可以指向控制点集、RGBA颜色值或纹理坐标串等
//参数u1和u2,指明变量U的范围,U一般从0变化到1。
//参数stride是跨度,表示在每块存储区内浮点数或双精度数的个数,即两个控制点间的偏移量,
//函数参数order是次数加 1,叫阶数,与控制点数一致
glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4,&ctrlpoints[0][0]);
glEnable(GL_MAP1_VERTEX_3);//启动函数 其中参数与glMap1f()的第一个参数一致
glShadeModel(GL_FLAT);
}
void CALLBACK display(void)
{
int i;
glClear(GL_COLOR_BUFFER_BIT);// 刷新背景
glColor3f(1.0, 1.0, 1.0);//设置像素颜色  曲线颜色
//void glEvalCoord1{fd}[v](TYPE u);
//参数u是定义域内的值,这个函数调用一次只产生一个坐标。
//glEvalcoord1*()将u值传给所有已启动的求值器,
//然后由这些已启动的求值器生成坐标、法向量、颜色或纹理坐标
glBegin(GL_LINE_STRIP);
for (i = 0; i <= 30; i++)
glEvalCoord1f((GLfloat) i/30.0);
glEnd();

/* 显示控制点 */
glPointSize(5.0);
glColor3f(1.0, 1.0, 0.0);

glBegin(GL_POINTS);
for (i = 0; i < 4; i++)
glVertex3fv(&ctrlpoints[i][0]);//四个控制点
glEnd();

glFlush();
}
void CALLBACK myReshape(GLsizei w, GLsizei h)//注释如上讲
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-5.0, 5.0, -5.0*(GLfloat)h/(GLfloat)w,5.0*(GLfloat)h/(GLfloat)w, -5.0, 5.0);
else
glOrtho(-5.0*(GLfloat)w/(GLfloat)h, 5.0*(GLfloat)w/(GLfloat)h, -5.0, 5.0, -5.0, 5.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void main(void)
{
//glutInitDisplayMode用来确定所创建窗口的显示模式。
//本例中的参数GLUT_SINGLE 指定单缓存窗口,这也是缺省模式,
//对应的模式为GLUT_DOUBLE 双缓存窗口。
//参数GLUT_RGB指定颜色RGBA模式,这也是缺省模式,对应的模式为GLUT_INDEX 颜色索引模式窗口。
auxInitDisplayMode (AUX_SINGLE | AUX_RGB);
auxInitPosition (0, 0, 500, 500);//大小x=500 y=500 (0,0)是屏幕左上点
auxInitWindow ("Arbitrary Clipping Planes");//创建顶层窗口,窗口的名字为扩号中的参数
myinit ();
//注册当前窗口的形状变化回调函数。
//当改变窗口大小时,该窗口的形状改变回调函数将被调用。
//在此例中就是myReshape指定形状变化函数。
auxReshapeFunc (myReshape);
//进入GLUT事件处理循环。
//glutMainLoop函数在GLUT程序中最多只能调用一次,它一旦被调用就不再返回,
//并且调用注册过的回调函数。所以这个函数必须放在注册回调函数的后面,
//此例中为glutReshapeFunc, glutDisplayFunc。
auxMainLoop(display);
}

原创粉丝点击