发信人: rhine (有雨无风), 信区: BorlandDev
标  题: OpenGL在C++Builder中的应用(9)
发信站: 哈工大紫丁香 (Sun Aug 27 06:47:13 2000), 转信

发信人: jinchao (Sonic), 信区: BCB
发信站: BBS 水木清华站 (Fri Jul 30 09:19:07 1999) WWW-POST

               (九)综合应用
    这是一个较为复杂的例子,显示一个白色球体和四个不同颜色的光源,用键盘控制
,r,g,b,w键分别控制红,绿,蓝,白四个光源的开闭,空格控制动画的开关,首先建立一
个NewApplication,修改Unit1.h,在Form类中加入Pravite成员"HGLRC hRC;",然后修改其
中Unit1.cpp如下:
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------

#pragma package(smart_init)
#pragma resource "*.dfm"
BOOL AnimationMode = TRUE;
BOOL Flag0,Flag1,Flag2,Flag3;//四个光源的开关标志
GLfloat Red[3]={1.0f,0.0f,0.0f},
             Green[3]={0.0f,1.0f,0.0f},
             Blue[3]={0.0f,0.0f,1.0f},
             White[3]={1.0f,1.0f,1.0f};
GLfloat Position0[4]={0.0f,2.0f,0.0f,1.0f};
GLfloat Position1[4]={-2.0f,0.0f,0.0f,1.0f};
GLfloat Position2[4]={0.0f,-2.0f,0.0f,1.0f};
GLfloat Position3[4]={2.0f,0.0f,0.0f,1.0f};
GLUquadricObj * sphere;//指向球体的指针
//-----------------加入用于定义四个光源的函数
void InitLight()
{   
    Flag0=Flag1=Flag2=Flag3=1;
    glShadeModel(GL_SMOOTH);
    glDepthFunc(GL_LESS);
    glEnable(GL_DEPTH_TEST);
    //定义光照模式
    GLfloat GlobalAmbient[4]={0.2f,0.2f,0.2f,1.0f};
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT,GlobalAmbient);
    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_FALSE);
    glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER,GL_FALSE);
//-------定义红色光源
    GLfloat Ambient0[4]={0.2f,0.2f,0.2f,1.0f};
    GLfloat Diffuse0[4]={1.0f,0.0f,0.0f,1.0f};
    GLfloat Specular0[4]={1.0f,0.0f,0.0f,1.0f};

    glLightfv(GL_LIGHT0,GL_AMBIENT,Ambient0);
    glLightfv(GL_LIGHT0,GL_DIFFUSE,Diffuse0);
    glLightfv(GL_LIGHT0,GL_SPECULAR,Specular0);
    glLightfv(GL_LIGHT0,GL_POSITION,Position0);
//--------- 定义绿色光源
    GLfloat Ambient1[4]={0.4f,0.4f,0.4f,1.0f};
    GLfloat Diffuse1[4]={0.0f,1.0f,0.0f,1.0f};
    GLfloat Specular1[4]={0.0f,1.0f,0.0f,1.0f};

    glLightfv(GL_LIGHT1,GL_AMBIENT,Ambient1);
    glLightfv(GL_LIGHT1,GL_DIFFUSE,Diffuse1);
    glLightfv(GL_LIGHT1,GL_SPECULAR,Specular1);
    glLightfv(GL_LIGHT1,GL_POSITION,Position1);
//--------- 定义蓝色光源
    GLfloat Ambient2[4]={0.4f,0.4f,0.4f,1.0f};
    GLfloat Diffuse2[4]={0.0f,0.0f,1.0f,1.0f};
    GLfloat Specular2[4]={0.0f,0.0f,1.0f,1.0f};

    glLightfv(GL_LIGHT2,GL_AMBIENT,Ambient2);
    glLightfv(GL_LIGHT2,GL_DIFFUSE,Diffuse2);
    glLightfv(GL_LIGHT2,GL_SPECULAR,Specular2);
    glLightfv(GL_LIGHT2,GL_POSITION,Position2);
//--------- 定义白色光源
    GLfloat Ambient3[4]={0.4f,0.4f,0.4f,1.0f};
    GLfloat Diffuse3[4]={1.0f,1.0f,1.0f,1.0f};
    GLfloat Specular3[4]={1.0f,1.0f,1.0f,1.0f};

    glLightfv(GL_LIGHT3,GL_AMBIENT,Ambient3);
    glLightfv(GL_LIGHT3,GL_DIFFUSE,Diffuse3);
    glLightfv(GL_LIGHT3,GL_SPECULAR,Specular3);
    glLightfv(GL_LIGHT3,GL_POSITION,Position3);
//---------定义当前材质
    GLfloat MatSpecular[4]={1.0f,1.0f,1.0f,1.0f};
    GLfloat MatShininess[1]={50.0f};
    glMaterialfv(GL_FRONT,GL_SPECULAR,MatSpecular);
    glMaterialfv(GL_FRONT,GL_SHININESS,MatShininess);

    glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
    glEnable(GL_COLOR_MATERIAL);
   
    glEnable(GL_LIGHTING);//允许光照模式
    glEnable(GL_LIGHT0);  //打开这四盏光源
    glEnable(GL_LIGHT1);
    glEnable(GL_LIGHT2);
    glEnable(GL_LIGHT3);
}
TForm1 *Form1;
//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//-------用于绘制球体以及光源"实体"的函数
void SolidSphere(GLdouble radius,GLint subdivisions)
{
    sphere = gluNewQuadric();
    gluSphere(sphere,radius,subdivisions,subdivisions);
    gluDeleteQuadric(sphere);
}
//----DrawLight()函数绘制四个小球代表四个光源
void DrawLight(GLfloat color[3],GLfloat position[])
{
    glColor3fv(color);
    glPushMatrix();
    glTranslatef(position[0],position[1],position[2]);
    SolidSphere(0.05,8);
    glPopMatrix();
}

//这次我们取消DrawWithOpenGL()函数,在FormPaint()中直接完成绘制
void __fastcall TForm1::FormPaint(TObject *Sender)
{
    HDC hDC;
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glDisable(GL_LIGHTING);
    //下面是光源旋转的计算
    static GLfloat angle=0.0f,da=4.0f;
    angle+=da;
    if(angle>360.0f)angle-=360.0f;
    glPushMatrix();
    glRotatef(angle,1.0f,0.0f,0.0f);
    if(Flag0)
      {
         glLightfv(GL_LIGHT0,GL_POSITION,Position0);
         DrawLight(Red,Position0);
      }
    if(Flag2)
      {
         glLightfv(GL_LIGHT2,GL_POSITION,Position2);
         DrawLight(Blue,Position2);
      }
    glPopMatrix();

    glPushMatrix();
    glRotatef(angle,0.0f,1.0f,0.0f);
    if(Flag1)
      {
         glLightfv(GL_LIGHT1,GL_POSITION,Position1);
         DrawLight(Green,Position1);
      }
    if(Flag3)
      {
         glLightfv(GL_LIGHT3,GL_POSITION,Position3);
         DrawLight(White,Position3);
      }
    glPopMatrix();


    glEnable(GL_LIGHTING);
    glColor3f(0.6f,0.6f,0.6f);//定义大球材质的DIFFUSE颜色即球的颜色
    SolidSphere(0.6,18);//绘制中间的大球

    glFlush();
    hDC=wglGetCurrentDC();
    SwapBuffers(hDC);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)
{
    HDC hDC;
    hDC= GetDC(this->Handle);
    static PIXELFORMATDESCRIPTOR pfd =
      {
            sizeof(PIXELFORMATDESCRIPTOR),
            1,
            PFD_DRAW_TO_WINDOW|
            PFD_SUPPORT_OPENGL|
            PFD_DOUBLEBUFFER,
            PFD_TYPE_RGBA,
            24,
            0,0,0,0,0,0,
            0,0,0,0,0,0,0,
            32,
            0,0,
            PFD_MAIN_PLANE,
            0,
            0,0,0
     };
    int pixelformat;
    if((pixelformat = ChoosePixelFormat(hDC,&pfd)) == 0)
      {
        MessageBox(NULL,"ChoosePixelFormat failed","Error",MB_OK);
        return ;
      }
    if(SetPixelFormat(hDC,pixelformat,&pfd) == FALSE)
      {
        MessageBox(NULL,"SetupPixelFormat failed","Error",MB_OK);
        return ;
      }
    hRC=wglCreateContext(hDC);
    wglMakeCurrent(hDC,hRC);
    glClearColor(0.0f,0.0f,0.0f,0.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    InitLight();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormDestroy(TObject *Sender)
{
    wglDeleteContext(hRC);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormResize(TObject *Sender)
{
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glViewport(0,0,this->ClientWidth,this->ClientHeight);
    glOrtho(-2.5,2.5,-2.5,2.5,-2.5,2.5);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}
//----------加入Timer控件,修改Intervar为100,主函数如下
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
    MSG msg;
    if(AnimationMode&&!PeekMessage(&msg,this->Handle,0,0,PM_NOREMOVE))
       FormPaint(NULL);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
    switch(Key)
     {
       case 'r':case 'R':
         if(Flag0){glDisable(GL_LIGHT0);Flag0=0;}
         else {glEnable(GL_LIGHT0);Flag0=1;}
         break;
       case 'g':case 'G':
         if(Flag1){glDisable(GL_LIGHT1);Flag1=0;}
         else {glEnable(GL_LIGHT1);Flag1=1;}
         break;
       case 'b':case 'B':
        if(Flag2){glDisable(GL_LIGHT2);Flag2=0;}
        else {glEnable(GL_LIGHT2);Flag2=1;}
        break;
       case 'w':case 'W':
        if(Flag3){glDisable(GL_LIGHT3);Flag3=0;}
        else {glEnable(GL_LIGHT3);Flag3=1;}
        break;
       case ' ':
         AnimationMode=!AnimationMode;break;
     }
}

--
        念天地之悠悠,
        独沧然而泪下,
        知我者谓我心忧,
        不知我者谓我何求......

--
☆ 来源:.哈工大紫丁香 bbs.hit.edu.cn.[FROM: rhine.bbs@smth.org]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:7.202毫秒