1.在使用GL_POSITION指定光源位置时,我们指定的是光源在眼睛坐标系中的位置。
光源 的位置是 以 GL_POSITION参数 和一个4值的矢量 ( x , Y , z , w) 来定 义的。如果 w的值等于 0 . 0, 那 么( x ,y,z ) 的值就定义了一个矢量, 其指定光线照过来的方向。这样的光源称为定向光源, 其所有光线都是平行的,就好像其光源的位置在无穷远。定向光的最普通的实例为太阳,太阳所发出的光到达地球时, 其所有光线都几乎是彼 此平行 的 。
当指定的 w值非0时,所定 义的就是一个定点光源对,于定 点光源,( x ,y ,z ) 的值定义了此光源在物体齐次坐标系中的坐标位置 。
/*注:齐次坐标(Homogeneous
Coordinate)
在空间直角坐标系中,任意一点可用一个三维坐标矩阵[x y z]表示。如果将该点用一个四维坐标的矩阵[Hx
Hy Hz H]表示时,则称为齐次坐标表示方法。在齐次坐标中,最后一维坐标H称为比例因子。
在OpenGL中,二维坐标点全看作三维坐标点,所有的点都用齐次坐标来描述,统一作为三维齐次点来处理。每个齐次点用一个向量(x, y, z, w)表示,其中四个元素全不为零。齐次点具有下列几个性质:
1)如果实数a非零,则(x, y, x, w)和(ax, ay, az, aw)表示同一个点,类似于x/y = (ax)/( ay)。
2)三维空间点(x, y, z)的齐次点坐标为(x, y, z, 1.0),二维平面点(x,y)的齐次坐标为(x, y, 0.0, 1.0)。
3)当w不为零时,齐次点坐标(x, y, z, w)即三维空间点坐标(x/w, y/w, z/w);当w为零时,齐次点(x, y, z, 0.0)表示此点位于某方向的无穷远处。
注意:OpenGL中指定w大于或等于0.0。*/
利用下面的代码来说明:
一、光源位置为(1.0,1.0,1.0,1.0)时,到达远点距离是根号3约等于1.73,当我们把球的半径设为小于1.73的数时,球上始终有光照,并且半径越小,光照的范围越大。此时光源的位置在物体的齐次坐标系中,也就是说,光照与物体的相对关系可以直接由坐标位置来描述。当球半径大于1.73时,我们将看到一片漆黑,因为球已经把光源包在内部了。
二、光源位置为(1.0,1.0,1.0,0.0)时,此时的坐标代表一个向量,相当于太阳光照射过来的方向,此时球半径多大都有光照。
#include <glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
static int spin=0;
#define xsx 500
#define xsy 500
GLfloat *data_z;
GLbyte *data_d;
void printbypepixels(GLbyte*data)
{
FILE *fp;
fp=fopen("C:\\pixels.txt","wt");
for(int i=0;i<xsx*xsy;i++)
fprintf(fp,"%d\n",data[i]);
fclose(fp);
}
void printfloatpixels(GLfloat*data)
{
FILE *fp;
fp=fopen("C:\\pixels.txt","wt");
for(int i=0;i<xsx*xsy;i++)
fprintf(fp,"%f\n",data[i]);
fclose(fp);
}
void init(void)
{
GLfloat mat_spec[]={1.0,1.0,1.0,1.0};
GLfloat mat_shin[]={50.0};
GLfloat lightpos[]={1.0,1.0,1.0,1.0};
GLfloat white_light[]={1.0,1.0,1.0,.0};
GLfloat lmodel_ambient[]={0.1,0.1,0.1,1.0};
glClearColor(0,0,0,0);
glShadeModel(GL_SMOOTH);
glMaterialfv(GL_FRONT,GL_SPECULAR,mat_spec);
glMaterialfv(GL_FRONT,GL_SHININESS,mat_shin);
glLightfv(GL_LIGHT0,GL_POSITION,lightpos);
glLightfv(GL_LIGHT0,GL_DIFFUSE,white_light);
glLightfv(GL_LIGHT0,GL_SPECULAR,white_light);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,lmodel_ambient);;
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
}
void display(void)
{ GLfloat pos[]={0.0,0.0,1.0,1.0};
GLfloat norm3[3];
data_z=(GLfloat*)malloc(sizeof(GLfloat)*xsx*xsy);
data_d=(GLbyte*)malloc(sizeof(GLbyte)*xsx*xsy);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef((GLfloat)spin,1,0,0);
glutSolidSphere(2.0,16,20);
glPopMatrix();
glFlush();
}
void processNormalKeys(unsigned char key, int x, int y) {
if (key == 27)
exit(0);
}
void ChangeSize(int w, int h)
{
GLfloat nRange = 5.0f;
if(h == 0)
h = 1;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange);
else
glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange);
//gluPerspective(60.0,h/w,1,400);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void mouse(int button,int state,int x,int y)
{
switch(button)
{
case GLUT_LEFT_BUTTON:if (state==GLUT_DOWN)
{spin=(spin+30)%360;
glutPostRedisplay();
}
break;
default:break;
}
}
int main(int argc,char**argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);
glutInitWindowSize(xsx,xsy);
glutInitWindowPosition(300,100);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(display);
glutReshapeFunc(ChangeSize);
glutKeyboardFunc(processNormalKeys);
glutMouseFunc(mouse);
glutMainLoop();
return 0;
}

1398

被折叠的 条评论
为什么被折叠?



