Динамична светлина
Използваме същия код ( този със слънчевата система ) с изключение на това, че тук добавяме още една функция
( Lighting ), която изплълнява нужните операции за включване на динамичната светлина.

#include < windows.h > // Хедърният файл на Windows
#include < gl/glut.h > // Хедърният файл на GLUT
#include < gl/gl.h > // Хедърният файл на OpenGL

void Render( void );
void Resize( int width, int height );
void Menu( int value );
void Lighting( void );

int MenuID;
// променлива, в която ще съхраняваме инд. номер на нашето меню

// дефинираме променливите които ще регулират завъртането на планетите
float Planet1_Angle;
float Planet2_Angle;
float Moon_Angle;


GLfloat ambient_light[ ] = { 0.4, 0.4, 0.4, 1.0 }; // цвета на AMBIENT светлината
GLfloat diffuse_light[ ] = { 0.8, 0.8, 0.8, 1.0 }; // цвета на DIFFUSE светлината
GLfloat light_position[ ] = { 0.0, 0.0, 0.0, 1.0 }; // позицията на светлинния източник
GLfloat emission[ ] = { 0.8, 0.8, 0.8, 1.0 }; // цвета на EMISSION излъчването
GLfloat emission_none[ ] = { 0.0, 0.0, 0.0, 1.0 }; // черен цвят, нужен за изключване на EMISSION излъчването

int main( int argc, char* argv[ ] )
{

  glutInit( &argc, argv );
// инициализираме библиотеката GLUT

  glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA ); // определяме режим на рендериране

  glutInitWindowSize( 600, 600 ); // определяма големина на прозореца

  glutInitWindowPosition( 100, 100 ); // определяма позиция на прозореца

  glutCreateWindow( "Created with GLUT ( OpenGL Utility Toolkit )" ); // създаваме прозореца

  glutDisplayFunc( Render ); // определяме рендериращата ни функцуя

  // определяме нашата оразмеряваща функция, която се извиква при промяна размерите на прозореца
  glutReshapeFunc( Resize );

   // извикваме нашата функция Lighting, в която сме определили светлинен източник и материал за обектите
  Lighting( );

  glEnable( GL_DEPTH_TEST ); // включваме проверка за разстоянията

  // създаваме нашето меню и указваме функция,
  // която ще се извиква при избиране на елемент от менюто

  MenuID = glutCreateMenu( Menu );

  glutSetMenu( MenuID ); // определямо менюто като текущо меню

  glutAddMenuEntry( "About", 1 ); // първи елемент от менюто

  glutAddMenuEntry( "EXIT", 2 ); // втори елемент от менюто

  glutAttachMenu( GLUT_RIGHT_BUTTON ); // определяме бутона, чието натискане активира менюто

  glMatrixMode( GL_PROJECTION );

  gluPerspective( 45, 1, 1, 200 ); // определяме 3D изгледа

  glMatrixMode( GL_MODELVIEW ); // превключваме обратно на MODELVIEW матрица

  glutMainLoop( );

  return 0;
}



void Render( )
{


  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); // изчистваме буферите

  glLoadIdentity( ); // зареждаме първоначалната матрица

  // увеличаваме ъгъла на завъртване
  Planet1_Angle += 0.5;
  Planet2_Angle += 0.3;
  Moon_Angle += 0.5;


  // определяме позиция на камерата
  gluLookAt( 0.0, 10.0, -50.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 );

  // подновяваме позиията на светлинния източник ( махнете този ред за да видите какво ще стане ;)
  glLightfv( GL_LIGHT0, GL_POSITION, light_position );

  glMaterialfv( GL_FRONT, GL_EMISSION, emission ); // определяме EMISSION излъчването

  glColor3f( 1.0, 1.0, 0.0 ); glutSolidSphere( 4.0, 20, 20 ); // създаваме слънцето :)

   // изключваме EMISSION излъчването, защото не искаме да се отрази на останалите обекти
  glMaterialfv( GL_FRONT, GL_EMISSION, emission_none );

  glPushMatrix( ); // поставяме матрица в стека

      glRotatef( Planet1_Angle, 0.0, 1.0, 0.0 ); // завъртаме сцената

      glTranslatef( 10.0, 0.0, 0.0 ); // преместваме сцената с 10 единици

      glColor3f( 1.0, 0.0, 0.0 ); glutSolidSphere( 1.5, 20, 20 ); // изрисуваме първата планета

  glPopMatrix( ); // изваждаме матрицата от стека

  // за изрисуване на втората планета повтаряме същата процедура
  glPushMatrix( );

      glRotatef( Planet2_Angle, 0.0, 1.0, 0.0 );

      glTranslatef( -20.0, 0.0, 0.0 );

      glColor3f( 0.0, 1.0, 0.0 ); glutSolidSphere( 2.0, 20, 20 );


      // сега идва ред на луната, която трябва да обикаля около планетата
      glRotatef( Moon_Angle, 0.0, 1.0, 0.0 );

      glTranslatef( 5.0, 0.0, 0.0 );

      glColor3f( 0.0, 0.0, 1.0 ); glutSolidSphere( 1.0, 20, 20 );

  glPopMatrix();


  /*
  Забележете че изрисуваме луната в матрицата на втората планета, защото искаме първите две транформации,
  преди изрисуване на втората планета, да се отразят и на луната. Само така ще постигнем желания резултат -
   планета въртяща се около слънцето и луна въртяща се около планетата.
  */


  glutSwapBuffers( ); // разменяме буферите

  glutPostRedisplay( ); // изискваме следващо извикване на рендериращата ни функция
}


void Resize( int width, int height )
{

  if(height==0) height=1;
// проверяваме стойността на height, за да избегнем деление на 0

  // указваме на OpenGL, че искаме изрисуване върху целия прозорец

  glViewport( 0, 0, width, height );

  glMatrixMode( GL_PROJECTION ); // включваме PROJECTION матрицата

  glLoadIdentity( ); // зареждаме първоначалната PROJECTION матрица

  gluPerspective( 45, (GLdouble)width/height, 1, 200 ); // определяме новия 3D изглед

  glMatrixMode( GL_MODELVIEW ); // превключваме отново към MODELVIEW матрица

  glLoadIdentity( );
}


void Menu( int value )
{

  int result;


  // обработваме подаденото на нашата функция съобщение (номера на избрания елемент от менюто)
  switch( value )
  {


  // ако е избран първия елемент от менюто се показва прозорец със съобщение
  case 1: MessageBox( NULL, "Created with GLUT ( OpenGL Utility Toolkit )", "About", MB_OK );
              break;


  // ако е избран втория елемент от менюто ( EXIT ) се показва прозорец с въпрос,
  // дали искаме да затворим програмата

  case 2: result = MessageBox( NULL, "Do you really want to quit?", "Quit?", MB_YESNO );
              if( result == IDYES ) exit( 0 );
              break;
  }
}


void Lighting( void )
{

  glEnable( GL_LIGHTING );
// включваме динамичната светлина

  // определяма глобална AMBIENT светлина
  glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient_light );

  glEnable( GL_LIGHT0 ); // включваме светлинен източник

  glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuse_light ); // определяме DIFFUSE излъчване
  glLightfv( GL_LIGHT0, GL_POSITION, light_position ); // определяме позиция на източника

  // определяме начина по който обектите поглъщат светлина от тип AMBIENT и DIFFUSE
  glMaterialfv( GL_FRONT, GL_AMBIENT, ambient_light );
  glMaterialfv( GL_FRONT, GL_DIFFUSE, diffuse_light );

  // изискваме цвета на нашите обекти, да се запазва при включване на динамичната светлина
  glEnable( GL_COLOR_MATERIAL );

  // определяме при кои видове светлина, цвета на обекта да участва в получаването
  // на крайния цвят след осветяването
  glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );
}



Свалете Visual C++ сорс кода на праграмата.

Автор: Иван Георгиев Иванов [ Nickname: tuschko ]
e-mail: tuschko@abv.bg


Този сайт е хостван от сървър на
Headoff Gaming Intranetwork