hyde
路人甲
路人甲
  • 注册日期2003-09-24
  • 发帖数555
  • QQ
  • 铜币1457枚
  • 威望0点
  • 贡献值0点
  • 银元0个
阅读:1590回复:0

OpenGL系列讲座(13续)

楼主#
更多 发布于:2004-03-20 10:43
7.4.4 材质改变

 

在实际应用的许多情况下,不同的物体或同一物体的不同部分都有可能设置不同的材质,

OpenGL函数库提供了两种方式实现这种要求。下面一例chgmat1.c采用的是设置矩阵堆栈来

保存不同物体的材质信息:

 

 

例 2-13  矩阵堆栈改变材质例程 chgmat1.c

 

 #include "glos.h"

 

#include <GL/gl.h>

#include <GL/glu.h>

#include <GL/glaux.h>

 

void myinit(void);

void CALLBACK display(void);

void CALLBACK myReshape(GLsizei w, GLsizei h);

 

/*  初始化z-buffer、光源和光照模型,

    在此不具体定义材质。

 */

void myinit(void)

{

    GLfloat ambient[] = { 0.0, 0.0, 0.0, 1.0 };

    GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0 };

    GLfloat specular[] = { 1.0, 1.0, 1.0, 1.0 };

    GLfloat position[] = { 0.0, 3.0, 2.0, 0.0 };

    GLfloat lmodel_ambient[] = { 0.4, 0.4, 0.4, 1.0 };

 

    glEnable(GL_DEPTH_TEST);

    glDepthFunc(GL_LESS);

 

    glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);

    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);

    glLightfv(GL_LIGHT0, GL_POSITION, position);

 

    glEnable(GL_LIGHTING);

    glEnable(GL_LIGHT0);

 

    glClearColor(0.0, 0.1, 0.1, 0.0);

}

 

void CALLBACK display(void)

{

    GLfloat no_mat[] = { 0.0, 0.0, 0.0, 1.0 };

    GLfloat mat_ambient[] = { 0.7, 0.7, 0.7, 1.0 };

    GLfloat mat_ambient_color[] = { 0.8, 0.8, 0.2, 1.0 };

    GLfloat mat_diffuse[] = { 0.1, 0.5, 0.8, 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};

 

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

 

/*  第一行第一列绘制的球仅有漫反射光而无环境光和镜面光。

 */

    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);

    auxSolidSphere(1.0);

    glPopMatrix();

 

/*  第一行第二列绘制的球有漫反射光和镜面光,并有低高光,

    而无环境光 。

 */

    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);

    auxSolidSphere(1.0);

    glPopMatrix();

 

/*  第一行第三列绘制的球有漫反射光和镜面光,并有很亮的高光,

    而无环境光 。

 */

    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, high_shininess);

    glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);

    auxSolidSphere(1.0);

    glPopMatrix();

 

/*  第一行第四列绘制的球有漫反射光和辐射光,

    而无环境和镜面反射光。

 */

    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, mat_emission);

    auxSolidSphere(1.0);

    glPopMatrix();

 

/*  第二行第一列绘制的球有漫反射光和环境光,

    而镜面反射光。

 */

    glPushMatrix();

    glTranslatef (-3.75, 0.0, 0.0);

    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);

    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);

    auxSolidSphere(1.0);

    glPopMatrix();

 

/*  第二行第二列绘制的球有漫反射光、环境光和镜面光,

    且有低高光。

 */

    glPushMatrix();

    glTranslatef (-1.25, 0.0, 0.0);

    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_SHININESS, low_shininess);

    glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);

    auxSolidSphere(1.0);

    glPopMatrix();

 

/*  第二行第三列绘制的球有漫反射光、环境光和镜面光,

    且有很亮的高光。

 */

    glPushMatrix();

    glTranslatef (1.25, 0.0, 0.0);

    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_SHININESS, high_shininess);

    glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);

    auxSolidSphere(1.0);

    glPopMatrix();

 

/*  第二行第四列绘制的球有漫反射光、环境光和辐射光,

    而无镜面光。

 */

    glPushMatrix();

    glTranslatef (3.75, 0.0, 0.0);

    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);

    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, mat_emission);

    auxSolidSphere(1.0);

    glPopMatrix();

 

/*  第三行第一列绘制的球有漫反射光和有颜色的环境光,

    而无镜面光。

 */

    glPushMatrix();

    glTranslatef (-3.75, -3.0, 0.0);

    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_color);

    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);

    auxSolidSphere(1.0);

    glPopMatrix();

 

/*  第三行第二列绘制的球有漫反射光和有颜色的环境光以及

    镜面光,且有低高光。

 */

    glPushMatrix();

    glTranslatef (-1.25, -3.0, 0.0);

    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_color);

    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);

    auxSolidSphere(1.0);

    glPopMatrix();

 

/*  第三行第三列绘制的球有漫反射光和有颜色的环境光以及

    镜面光,且有很亮的高光。

 */

    glPushMatrix();

    glTranslatef (1.25, -3.0, 0.0);

    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_color);

    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);

    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);

    glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);

    glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);

    auxSolidSphere(1.0);

    glPopMatrix();

 

/*  第三行第四列绘制的球有漫反射光和有颜色的环境光以及

    辐射光,而无镜面光。

 */

    glPushMatrix();

    glTranslatef (3.75, -3.0, 0.0);

    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_color);

    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, mat_emission);

    auxSolidSphere(1.0);

    glPopMatrix();

 

    glFlush();

}

 

void CALLBACK myReshape(GLsizei w, GLsizei h)

{

    glViewport(0, 0, w, h);

    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();

    if (w <= (h * 2))

    glOrtho (-6.0, 6.0, -3.0*((GLfloat)h*2)/(GLfloat)w,

        3.0*((GLfloat)h*2)/(GLfloat)w, -10.0, 10.0);

    else

    glOrtho (-6.0*(GLfloat)w/((GLfloat)h*2),

        6.0*(GLfloat)w/((GLfloat)h*2), -3.0, 3.0, -10.0, 10.0);

    glMatrixMode(GL_MODELVIEW);

}

 

void main(void)

{

    auxInitDisplayMode (AUX_SINGLE | AUX_RGBA);

    auxInitPosition (0, 0, 600, 450);

    auxInitWindow ("Material");

    myinit();

    auxReshapeFunc (myReshape);

    auxMainLoop(display);

}

 

  

 

图 2-7-5 多种光和材质的变化效果

 

    以上程序运行结果是绘制12个球(3行4列)。第一行的球材质都没有环境反射光,

第二行的都有一定的环境反射光,第三行的都有某种颜色的环境光。而第一列的球材质

仅有蓝色的漫反射光;第二列的不仅有蓝漫反射光,而且还有镜面反射光,较低的高光

;第三列的不仅有蓝漫反射光,而且还有镜面反射光,很亮的高光;第四列的还包括辐

射光,但无镜面光。

 

    这个程序运用矩阵堆栈多次调用glMaterialfv()来设置每个球的材质,也就是改变

同一场景中的不同物体的颜色。但由于这个函数的应用有个性能开销,因此建议最好尽

可能少的改变材质,以减少改变材质时所带来的性能开销,可采用另一种方式即改变材

质颜色,相应函数为glColorMaterial(),说明如下:

 

       void glColorMaterial(GLenum face,GLenum mode);

 

函数参数face指定面,值有GL_FRONT、GL_BACK或GL_FRONT_AND_BACK(缺省值)。mode

指定材质成分,值有GL_AMBIENT、GL_DIFFUSE、GL_AMBIENT_AND_DIFFUSE(缺省值)、

GL_SPECULAR或GLEMISSION。

   注意,这个函数说明了两个独立的值,第一个参数说明哪一个面和哪些面被修改,而

第二个参数说明这些面的哪一个或哪些材质成分要被修改。OpenGL并不为每一种face保

持独立的mode变量。在调用glColorMterial()以后,首先需要用GL_COLOR_MATERIAL作为

参数调用glEnable()来启动颜色材质,然后在绘图时调用glColor*()来改变当前颜色,

或用glMaterial()来改变材质成分。当不用这种方式来改变材质时,可调用

glDisable(GL_COLOR_MATERIAL)来关闭取消。如下面一段代码:

 

     glColorMaterial(GL_FRONT,GL_DIFFUSE);

     glEnable(GL_COLOR_MATERIAL);

     glColor3f(0.3,0.5,0.7);

     /* draw some objects here. */

     glcolor3f(0.0,1.0,0.0);

     /* draw other objects here.*/

     glDisable(GL_COLOR_MATERIAL);

 

    当需要改变场景中大部分方面的单个材质时,最好调用glColorMaterial();当需要

修改不止一个材质参数时,最好调用glMaterial*()。注意,当不需要颜色材质时一定要

关闭它,以避免相应的开销。下面来看一个颜色材质的具体应用例子chgmat2.c:

 

 

例 2-14  颜色定义改变材质例程 chgmat2.c

 

#include "glos.h"

 

#include <GL/gl.h>

#include <GL/glu.h>

#include <GL/glaux.h>

 

void myinit(void);

void CALLBACK myReshape(GLsizei w, GLsizei h);

void CALLBACK display(void);

 

void myinit(void)

{

   GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };

 

    glLightfv(GL_LIGHT0, GL_POSITION, light_position);

 

    glEnable(GL_LIGHTING);

    glEnable(GL_LIGHT0);

    glDepthFunc(GL_LESS);

    glEnable(GL_DEPTH_TEST);

 

    glColorMaterial(GL_FRONT, GL_DIFFUSE);

    glEnable(GL_COLOR_MATERIAL);

}

 

void CALLBACK display(void)

{

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

 

   /* draw one yellow ball */

    glLoadIdentity();

    glTranslatef(-0.7,0.0,0.0);

    glColor3f(1.0,1.0,0.0);

    auxSolidSphere(0.5);

 

   /* draw one red cone */

    glLoadIdentity();

    glRotatef(-65.0,1.0,0.0,0.0);

    glTranslatef(0.7,0.0,0.0);

    glColor3f(1.0,0.0,0.0);

    auxSolidCone(0.4,0.6);

 

    glFlush();

}

 

void CALLBACK myReshape(GLsizei w, GLsizei h)

{

    glViewport(0, 0, w, h);

     glMatrixMode(GL_PROJECTION);

    glLoadIdentity();

    if (w <= h)

    glOrtho (-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w,

        1.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);

    else

    glOrtho (-1.5*(GLfloat)w/(GLfloat)h,

        1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0);

    glMatrixMode(GL_MODELVIEW);

    glLoadIdentity();

}

 

void main(void)

{

    auxInitDisplayMode (AUX_SINGLE | AUX_RGB | AUX_DEPTH16);

    auxInitPosition (0, 0, 500, 500);

    auxInitWindow ("ColorMaterial Mode");

    myinit();

    auxReshapeFunc (myReshape);

    auxMainLoop(display);

}

 

 

以上程序改变的是漫反射颜色。场景中显示了一个黄色的球和一个红色的锥体。

 

  

 

                        图 2-7-6 漫反射材质改变

喜欢0 评分0
夜落了,风静了,我喜欢一本书,一杯茶,一粒摇曳的烛光...
游客

返回顶部