[��һ�Σ�����ӳ��] [Qt OpenGL�̳���ҳ] [��һ�Σ��ں�]

�����˲�����Դ�ͼ��̿���

��һ���һ���������ʹ�����ֲ�ͬ�������˲���ʽ����������ʹ�ü������ƶ������еĶ��󣬻���������OpenGL������Ӧ�ü򵥵Ĺ��ա���һ�ΰ����˺ܶ����ݣ���������ǰ���Ŀγ������ʵĻ����Ȼ�ͷ��ϰһ�¡����������Ĵ���֮ǰ���ܺõ���������֪ʶʮ����Ҫ��

����Ҫ�ڵ�һ�εĴ����Ͻ��иĶ��Ϳ����ˡ�

���ǽ�Ҫ����һ��loadGLTextures()�����������й����������ġ����ǽ�����һЩ�������Ժ����Ƕ���Щ�������н��͡�

NeHeWidget��

����nehewidget.hչ������

protected:

  void loadGLTextures();

���������������ǻ�����ָ����ͼƬ��������Ӧ��������

protected:

  bool fullscreen;
  GLfloat xRot, yRot, zRot;
  GLfloat zoom;
  GLfloat xSpeed, ySpeed;
  GLuint texture[3];
  GLuint filter;
  
  bool light;
  
};

�����������ӵ���������xRot��yRot��zRot�����������������������ϵ���ת��zoom�dz���������Ļ�ľ��롣xSpeed��ySpeed����������X����Y������ת���ٶȡ�texture[3]�����洢����������filter��������ʹ���ĸ�������light��˵�������Ƿ�ʹ�ù�Դ��

����nehewidget.cppչ������

GLfloat lightAmbient[4] = { 0.5, 0.5, 0.5, 1.0 };
GLfloat lightDiffuse[4] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat lightPosition[4] = { 0.0, 0.0, 2.0, 1.0 };

���ﶨ�����������飬�����������Ǻ͹�Դ�йص���Ϣ��

���ǽ�ʹ�����ֲ�ͬ�Ĺ⡣��һ�ֳ�Ϊ�����⡣�����������������˷������г����еĶ��󶼴��ڻ������������С��ڶ������͵Ĺ�Դ���������⡣���������ض��Ĺ�Դ�������������ij����еĶ��������ϲ������䡣����������ֱ�������µ��κζ������涼���ú�����������δ�����䵽���������Ե�Ҫ��һЩ��������������������ľ�����������Ͼͻ������ĺܲ�������ӰЧ����

������Դ�Ĺ��̺���ɫ�Ĵ�����ȫһ�¡�ǰ���������ֱ���RGB��ɫ����������һ����alphaͨ��������

���ˣ���һ���й�lightAmbient�Ĵ���ʹ���ǵõ����ǰ�����0.5���İ�ɫ�����⡣����û�л����⣬δ���������յ��ĵط�������ʮ�ֺڰ���

�ڶ����й�lightDiffuse�Ĵ���ʹ�������������������⡣���еIJ���ֵ��ȡ������ֵ1.0��������������ľ������ǰ�棬������ͦ�á�

�������й�lightPosition�Ĵ���ʹ���DZ�����Դ��λ�á�ǰ����������glTranslate�е�һ�������ηֱ���XYZ���ϵ�λ�ơ�����������Ҫ����ֱ��������ľ�������棬����XY���ϵ�λ�ƶ���0.0��������ֵ��Z���ϵ�λ�ơ�Ϊ�˱�֤��������ľ����ǰ�棬�������ǽ���Դ��λ�ó��Ź۲��ߣ��������ġ���Ų����Ļ������ͨ������ĻҲ������ʾ������Ļ����������λ�ó���Z����0.0�㡣����Z���ϵ�λ��������Ϊ2.0���������ܹ�������Դ�Ļ������͸�������ʾ����ǰ������Ȼ������ľ�䲻����ʾ������Ļ���������Ļ�����Ҳ�޷��������ӡ�����һ������ȡΪ1.0���⽫����OpenGL����ָ�����������ǹ�Դ��λ�ã��Ժ��Ľ̳����һ����ӽ��͡�

NeHeWidget::NeHeWidget( QWidget* parent, const char* name, bool fs )
    : QGLWidget( parent, name )
{
  xRot = yRot = zRot = 0.0;
  zoom = -5.0;
  xSpeed = ySpeed = 0.0;

  filter = 0;

  light = false;

  fullscreen = fs;
  setGeometry( 0, 0, 640, 480 );
  setCaption( "NeHe's Texture, Lighting & Keyboard Tutorial" );

  if ( fullscreen )
    showFullScreen();
}

������Ҫ�ڹ��캯���и�������������ֵ��xRot��yRot��zRot��0.0��zoom��-5.0��xSpeed��ySpeed����0��filter��0��light��false��

void NeHeWidget::loadGLTextures()
{
  QImage tex, buf;
  if ( !buf.load( "./data/Crate.bmp" ) )
  {
    qWarning( "Could not read image file, using single-color instead." );
    QImage dummy( 128, 128, 32 );
    dummy.fill( Qt::green.rgb() );
    buf = dummy;
  }
  tex = QGLWidget::convertToGLFormat( buf );
  
  glGenTextures( 3, &texture[0] );

��һ���֣���һ�½����ˡ��������ﴴ����3��������

  glBindTexture( GL_TEXTURE_2D, texture[0] );
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  glTexImage2D( GL_TEXTURE_2D, 0, 3, tex.width(), tex.height(), 0,
      GL_RGBA, GL_UNSIGNED_BYTE, tex.bits() );

������������ʹ���������˲���������ͼ������Ҫ�������൱�ߵĴ��������������ǿ������ܲ�������һ���У����ǽ���Ҫ�����ĵ�һ������ʹ��GL_NEAREST��ʽ����ԭ���Ͻ������ַ�ʽû�����������˲�����ֻռ�ú�С�Ĵ���������������Ҳ�ܲΨһ�ĺô����������ǵĹ����ںܿ��ͺ����Ļ����϶������������С�����ע�⵽������MIN��MAGʱ��������GL_NEAREST,�����Ի���ʹ��GL_NEAREST��GL_LINEAR������������Ч������Щ�������Ǹ������ٶȣ�����ȫ���õ�������ͼ��MIN_FILTER��ͼ������ʱС����ͼ��ԭʼ�ߴ�ʱ���á�MAG_FILTER��ͼ������ʱ������ͼ��ԭʼ�ߴ�ʱ���á�

  glBindTexture( GL_TEXTURE_2D, texture[1] );
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
  glTexImage2D( GL_TEXTURE_2D, 0, 3, tex.width(), tex.height(), 0,
      GL_RGBA, GL_UNSIGNED_BYTE, tex.bits() );

���������������ε���ͬ�������˲���Ψһ�IJ�ͬ�����η�����texture[1]�С���Ϊ���ǵڶ�����������������texture[0]�еĻ�����������ǰ�洴����GL_NEAREST������

  glBindTexture( GL_TEXTURE_2D, texture[2] );
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );

�����Ǵ����������·�����Mipmapping�������ܻ�ע�⵽��ͼ������Ļ�ϱ��ú�С��ʱ�򣬺ܶ�ϸ�ڽ��ᶪʧ���ղŻ��ܲ�����ͼ�����ú��ѿ�����������OpenGL����һ�� mipmapped����������OpenGL�����Դ�����ͬ�ߴ��ĸ�������������������Ļ����һ��mipmapped������ʱ����OpenGL��ѡ�����Ѿ��������������ѵ�����(���и���ϸ��)�����ƣ���������������ԭ�ȵ�ͼ�����⽫����ϸ�ڶ�ʧ����

������˵���а취�����ƹ�OpenGL���������Ⱥ͸߶����ӵ����ơ���64��128��256���ȵȡ��취����gluBuild2DMipmaps�����ҵķ��֣�������ʹ��������λͼ������������OpenGL���Զ��������ŵ������Ĵ�С��

��Ϊ�ǵ��������������ǽ����浽texture[2]�����������е���������ȫ���������ˡ� gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, tex.width(), tex.height(), GL_RGBA, GL_UNSIGNED_BYTE, tex.bits() );

��һ������ mipmapped ����������ʹ��������ɫ���죬�̣�����������һ��2D������tex.width()��λͼ���ȣ�tex.height()��λͼ�߶ȣ�extureImage[0]->sizeY ��λͼ�߶ȣ�GL_RGBA��ζ����������ʹ��RGBAɫ�ʡ�GL_UNSIGNED_BYTE��ζ���������ݵĵ�λ���ֽڡ�tex.bits()ָ�����Ǵ����������õ�λͼ��

}

loadGLTextures()���������������������ġ�

void NeHeWidget::paintGL()
{
  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  glLoadIdentity();
  glTranslatef(  0.0,  0.0, zoom );
  
  glRotatef( xRot,  1.0,  0.0,  0.0 );
  glRotatef( yRot,  0.0,  1.0,  0.0 );

  glBindTexture( GL_TEXTURE_2D, texture[filter] );

����filter����������ʹ���ĸ�������

  glBegin( GL_QUADS );
    glNormal3f( 0.0, 0.0, 1.0 );
    glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, -1.0,  1.0 );
    glTexCoord2f( 1.0, 0.0 ); glVertex3f(  1.0, -1.0,  1.0 );
    glTexCoord2f( 1.0, 1.0 ); glVertex3f(  1.0,  1.0,  1.0 );
    glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0,  1.0,  1.0 );
  
    glNormal3f( 0.0, 0.0, -1.0 );
    glTexCoord2f( 1.0, 0.0 ); glVertex3f( -1.0, -1.0, -1.0 );
    glTexCoord2f( 1.0, 1.0 ); glVertex3f( -1.0,  1.0, -1.0 );
    glTexCoord2f( 0.0, 1.0 ); glVertex3f(  1.0,  1.0, -1.0 );
    glTexCoord2f( 0.0, 0.0 ); glVertex3f(  1.0, -1.0, -1.0 );

    glNormal3f( 0.0, 1.0, 0.0 );
    glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0,  1.0, -1.0 );
    glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0,  1.0,  1.0 );
    glTexCoord2f( 1.0, 0.0 ); glVertex3f(  1.0,  1.0,  1.0 );
    glTexCoord2f( 1.0, 1.0 ); glVertex3f(  1.0,  1.0, -1.0 );

    glNormal3f( 0.0, -1.0, 0.0 );
    glTexCoord2f( 1.0, 1.0 ); glVertex3f( -1.0, -1.0, -1.0 );
    glTexCoord2f( 0.0, 1.0 ); glVertex3f(  1.0, -1.0, -1.0 );
    glTexCoord2f( 0.0, 0.0 ); glVertex3f(  1.0, -1.0,  1.0 );
    glTexCoord2f( 1.0, 0.0 ); glVertex3f( -1.0, -1.0,  1.0 );

    glNormal3f( 1.0, 0.0, 0.0 );
    glTexCoord2f( 1.0, 0.0 ); glVertex3f(  1.0, -1.0, -1.0 );
    glTexCoord2f( 1.0, 1.0 ); glVertex3f(  1.0,  1.0, -1.0 );
    glTexCoord2f( 0.0, 1.0 ); glVertex3f(  1.0,  1.0,  1.0 );
    glTexCoord2f( 0.0, 0.0 ); glVertex3f(  1.0, -1.0,  1.0 );

    glNormal3f( -1.0, 0.0, 0.0 );
    glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, -1.0, -1.0 );
    glTexCoord2f( 1.0, 0.0 ); glVertex3f( -1.0, -1.0,  1.0 );
    glTexCoord2f( 1.0, 1.0 ); glVertex3f( -1.0,  1.0,  1.0 );
    glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0,  1.0, -1.0 );
  glEnd();

���������������ķ�������һ���Ѿ��������ˡ�

  xRot += xSpeed;
  yRot += ySpeed;

��xRot��yRot����תֵ�ֱ�����xSpeed��ySpeed����λ��xSpeed��ySpeed��ֵԽ����������ת�þ�Խ�졣

}
void NeHeWidget::initializeGL()
{
  loadGLTextures();

  glEnable( GL_TEXTURE_2D );
  glShadeModel( GL_SMOOTH );
  glClearColor( 0.0, 0.0, 0.0, 0.5 );
  glClearDepth( 1.0 );
  glEnable( GL_DEPTH_TEST );
  glDepthFunc( GL_LEQUAL );
  glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
  
  glLightfv( GL_LIGHT1, GL_AMBIENT, lightAmbient );
  glLightfv( GL_LIGHT1, GL_DIFFUSE, lightDiffuse );
  glLightfv( GL_LIGHT1, GL_POSITION, lightPosition );
  
  glEnable( GL_LIGHT1 );

���↑ʼ���ù�Դ����һ�����û������ķ���������ԴGL_LIGHT1��ʼ���⡣��һ�εĿ�ʼ���������ǽ��������ķ�����������lightAmbient�����С��������Ǿ�ʹ�ô����飨�����Ȼ����⣩��

���������������������ķ���������������lightDiffuse�����У�ȫ���Ȱ׹⣩��

Ȼ�����ù�Դ��λ�á�λ�ô�����lightPosition �����У�����λ��ľ��ǰ�������ģ�X��0.0��Y��0.0��Z���������۲���2����λ��λ����Ļ���棩��

��������������һ�Ź�Դ�����ǻ�û������GL_LIGHTING���������������κι��ߡ���ס��ֻ�Թ�Դ�������á���λ���������ã���Դ�����Ṥ����������������GL_LIGHTING��

}
void NeHeWidget::keyPressEvent( QKeyEvent *e )
{
  switch ( e->key() )
  {
  case Qt::Key_L:
    light = !light;
    if ( !light )
    {
      glDisable( GL_LIGHTING );
    }
    else
    {
      glEnable( GL_LIGHTING );
    }
    updateGL();
    break;

������L�����Ϳ����л��Ƿ��򿪹�Դ��

  case Qt::Key_F:
    filter += 1;;
    if ( filter > 2 )
    {
      filter = 0;
    }
    updateGL();
    break;

������F�����Ϳ���ת��һ����ʹ�õ����������DZ任�������˲���ʽ����������

  case Qt::Key_Prior:
    zoom -= 0.2;
    updateGL();
    break;

������PageUp������ľ��������Ļ�ڲ���

  case Qt::Key_Next:
    zoom += 0.2;
    updateGL();
    break;

������PageDown������ľ��������Ļ�ⲿ��

  case Qt::Key_Up:
    xSpeed -= 0.01;
    updateGL();
    break;

������Up������������xSpeed��

  case Qt::Key_Down:
    xSpeed += 0.01;
    updateGL();
    break;

������Dowm������������xSpeed��

  case Qt::Key_Right:
    ySpeed += 0.01;
    updateGL();
    break;

������Right������������ySpeed��

  case Qt::Key_Left:
    ySpeed -= 0.01;
    updateGL();
    break;

������Left������������ySpeed��

  case Qt::Key_F2:
    fullscreen = !fullscreen;
    if ( fullscreen )
    {
      showFullScreen();
    }
    else
    {
      showNormal();
      setGeometry( 0, 0, 640, 480 );
    }
    update();
    break;
  case Qt::Key_Escape:
    close();
  }
}

��һ������֮������Ӧ��ѧ�ᴴ����ʹ�������ֲ�ͬ������ӳ�����˷�ʽ����ʹ�ü��̺ͳ����еĶ��󽻻�����������Ӧ��ѧ���ڳ�����Ӧ�ü򵥵Ĺ�Դ��ʹ�ó��������������档

���γ̵�Դ������

[��һ�Σ�����ӳ��] [Qt OpenGL�̳���ҳ] [��һ�Σ��ں�]


mailto:[email protected]
2003��2��24��