Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Мультимедия, OpenGL/DirectX > Программа тормозит, OpenGL


Автор: BezImeni 6.6.2007, 20:18
   Тормозит!!  smile 

   Это система (типа солнечная   smile)

   Может где-то что-то не так сделал? smile 
Код

void init()
{
   GLfloat LIGHT_POSITION[] = {0.0, 0.0, 0.0, 1.0};
   GLfloat WHITE_LIGHT[]    = {1.0, 1.0, 1.0, 1.0};

   glClearColor(0.8, 0.8, 0.8, 0.0);
   glShadeModel(GL_SMOOTH);

   glLightfv(GL_LIGHT0, GL_POSITION, LIGHT_POSITION);
   glLightfv(GL_LIGHT0, GL_DIFFUSE, WHITE_LIGHT);
   glLightfv(GL_LIGHT0, GL_SPECULAR, WHITE_LIGHT);

   glEnable(GL_LIGHTING);
   glEnable(GL_LIGHT0);
   glEnable(GL_DEPTH_TEST);
}

void reshape(int w, int h)
{   
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluPerspective(60.0, (GLfloat)w / (GLfloat)h, 1.0, 700.0);
   glViewport(0, 0, w, h);
}

void display(void)
{
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

   glMatrixMode( GL_MODELVIEW );
   glLoadIdentity();
   
   loadAndInitTextures();  

   moveCamera();  
    
   drawStarsBorder();//Рисует ограничивающий куб - на нем текстура

   GLfloat sunAmbDiff[] = {1.0, 1.0, 1.0, 1.0};
   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sunAmbDiff);
   drawSun();

   GLfloat planetAmbDiff_1[] = {0.0, 0.0, 1.0, 1.0};
   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, planetAmbDiff_1);
   drawPlanet(intPlanet_1, positionPlanet_1, 3.0, 0.25);
   .
   .
   .   
   GLfloat planetAmbDiff_10[] = {1.0, 0.0, 0.0, 1.0};
   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, planetAmbDiff_10);
   drawPlanet(intPlanet_10, positionPlanet_10, 30.0, 0.4);    

   glutTimerFunc(milliseconds, timer, 1);

   glutSwapBuffers();
}


Автор: sgi1981 6.6.2007, 23:44
О быстродействии этого участка программы нельзя конкретно судить. Например, неизвестен код функции 
drawPlanet.

Автор: BezImeni 6.6.2007, 23:53
   понято  smile  - вот он - если есть лучший вариант - с удовольствием приму  smile 
Код

void drawPlanet(GLuint texture, GLint orbit, GLfloat fromSun,  GLfloat size)
{
   glEnable(GL_TEXTURE_2D);
   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
   glBindTexture(GL_TEXTURE_2D, texture); 
   glPushMatrix();
   glRotatef((GLfloat)orbit, 0.0, 1.0, 0.0);
    glTranslatef(fromSun, 0.0, 0.0);
    glRotatef((GLfloat)day, 0.0, 1.0, 0.0);
    glRotatef(90.0, 1.0, 0.0, 0.0);
   drawSphere(size, 20, 16);      
   glPopMatrix();
   glDisable(GL_TEXTURE_2D);     
}
.
.
.
float static PI = 3.14159;

void drawPolCaps(float radius, int longitudesNumber, int latitudesNumber);

void drawSphere(float radius, int longitudesNumber, int latitudesNumber)
{
   float angleBetweenLongitudesOnCap = 2.0 * PI / longitudesNumber;
   float angleBetwLongAndLatOnCap = PI / latitudesNumber;
   float angleBetwLongAndLatNotOnCap_1; 
   float angleBetwLongAndLatNotOnCap_2;
   float pointOnZ_1;
   float pointOnZ_2;
   float radiusLat_1; 
   float radiusLat_2;
   float phi;
  
   for (int counter_1 = 1; counter_1 <= latitudesNumber - 2; counter_1++) 
   {
      angleBetwLongAndLatNotOnCap_1 = counter_1 * angleBetwLongAndLatOnCap;
      angleBetwLongAndLatNotOnCap_2 = (counter_1 + 1) * 
                                       angleBetwLongAndLatOnCap;
                                       
      pointOnZ_1  = radius * cos(angleBetwLongAndLatNotOnCap_1);
      pointOnZ_2  = radius * cos(angleBetwLongAndLatNotOnCap_2);
      radiusLat_1 = radius * sin(angleBetwLongAndLatNotOnCap_1);
      radiusLat_2 = radius * sin(angleBetwLongAndLatNotOnCap_2);
      
      glBegin(GL_TRIANGLE_STRIP);
      for (int counter_2 = 0; counter_2 <= longitudesNumber; counter_2++) 
      {
         phi = counter_2 * angleBetweenLongitudesOnCap;
         
         glNormal3f(sin(angleBetwLongAndLatNotOnCap_1) * cos(phi), 
                    sin(angleBetwLongAndLatNotOnCap_1) * sin(phi),
                    cos(angleBetwLongAndLatNotOnCap_1));
         glTexCoord2f(static_cast<float>(counter_2) / longitudesNumber, 
                      static_cast<float>(latitudesNumber - 1 - counter_1) / 
                      (latitudesNumber - 2));
         glVertex3f(radiusLat_1 * cos(phi), radiusLat_1 * sin(phi), pointOnZ_1);
         
         glNormal3f(sin(angleBetwLongAndLatNotOnCap_2) * cos(phi), 
                    sin(angleBetwLongAndLatNotOnCap_2) * sin(phi), 
                    cos(angleBetwLongAndLatNotOnCap_2));
         glTexCoord2f(static_cast<float>(counter_2) / longitudesNumber, 
                      static_cast<float>(latitudesNumber - 2 - counter_1) / 
                      (latitudesNumber - 2));
         glVertex3f(radiusLat_2 * cos(phi), radiusLat_2 * sin(phi), pointOnZ_2);
      }
      glEnd();
   }
   
   drawPolCaps(radius, longitudesNumber, latitudesNumber);   
}

void drawPolCaps(float radius, int longitudesNumber, int latitudesNumber)
{
   float radiusLatitude;  
   float pointOnZ_1;
   float pointOnZ_2;
   float phi;
   float angleBetwLongAndLatOnCap = PI / latitudesNumber;
   float angleBetweenLongitudesOnCap = 2.0 * PI / longitudesNumber;
     
     
   radiusLatitude = radius * sin(angleBetwLongAndLatOnCap);
   pointOnZ_1     = radius;
   pointOnZ_2     = radius * cos(angleBetwLongAndLatOnCap);
   
   glBegin(GL_TRIANGLE_FAN);
   glNormal3f(0.0, 0.0, 1.0);
   glVertex3f(0.0, 0.0, pointOnZ_1);
   for (int counter = 0; counter <= longitudesNumber; counter++) 
   {
      phi = counter * angleBetweenLongitudesOnCap;
      glNormal3f(sin(angleBetwLongAndLatOnCap) * cos(phi),
                 sin(angleBetwLongAndLatOnCap) * sin(phi), 
                 cos(angleBetwLongAndLatOnCap));
                 
      glVertex3f(radiusLatitude * cos(phi), radiusLatitude * sin(phi), 
      pointOnZ_2);
   }
   glEnd();
      
   radiusLatitude = radius * sin(angleBetwLongAndLatOnCap);
   pointOnZ_1 = -radius;
   pointOnZ_2 = -radius * cos(angleBetwLongAndLatOnCap);
   glBegin(GL_TRIANGLE_FAN);
   glNormal3f(0.0, 0.0, -1.0);
   glVertex3f(0.0, 0.0, pointOnZ_1);
   for (int counter = longitudesNumber; counter >= 0; counter--) 
   {
      phi = counter * angleBetweenLongitudesOnCap;
      glNormal3f(sin(angleBetwLongAndLatOnCap) * cos(phi), 
                 sin(angleBetwLongAndLatOnCap) * sin(phi), 
                 -cos( angleBetwLongAndLatOnCap));
      glVertex3f(radiusLatitude * cos(phi), radiusLatitude * sin(phi), pointOnZ_2);
   }
   glEnd();   
}

Автор: Rickert 7.6.2007, 07:10
0) ты не пробовал точки сферы расчитать лишь однажды, при загрузке программы, а не вычислять их в каждом кадре?
1) Значения sin и cos, тоже можно вычислить лишь однажды, при загрузке программы. Причём тебе понадобиться лишь 180 (если точность угла всегда 1) значений, потому что cos и sin повторяются с периодичностью pi/2 (90 градусов).
2) После того, как получишь точки сферы, загоняй их в один большой массив указателем float и делай вывод изображения через glDrawArrays.

Прирост почувствуешь всем телом.

Автор: BezImeni 7.6.2007, 08:29
   Rickert, а можешь пожалуйста как код твои мысли  smile  smile 

Автор: Rickert 7.6.2007, 08:58
BezImeni, запомни: для программиста, самое главное, в профессиональном росте - это разбор ошибок и составление алгоритмов. А ещё лучше, если применять мозг и самомум решать вс епроблемы. Так что ты начни разбираться, и задавай вопросы, а я тебя пинать буду в нужном направлении.
Первый пинок: создай чистый проект, который только инициализирует и выводит сферу, затем загляни в мат. справочник и найди уравнение сферы, после чего попробуй создать указатель float, который будет указывать на массив значений вершин сферы. Если что непонятно - задавай вопросы. Делай всё последовательно, я помогу. smile 

Автор: BezImeni 7.6.2007, 19:57
   Полностью с тобой согласен smile  smile - в том причина вопроса, что время поджимает - надо сдавать задание по графике - а это не моя тема, т.е. иногда приходится действовать по принципу сначала получил зачет, сэкономил время для других предметов - потом разобрался.  smile 

   За то что подсказал причину тормозов нереальных - спасибо!  smile 

Автор: DigitSphinx 8.6.2007, 22:51
Просмотрел код по быстрому , думаю что функцию loadAndInitTextures(); тоже можно выполнить только один раз.

Автор: BezImeni 9.6.2007, 00:11
DigitSphinx Спасибо!! - уже летает!  smile   smile   smile 

Автор: DigitSphinx 9.6.2007, 22:50
Если что, обращайся  smile 

Автор: Rickert 10.6.2007, 16:56
BezImeni, тему как решённую пометь smile

Автор: sgi1981 14.6.2007, 09:14
Еще можно скачать и испытать вот это
http://sgi.bigtruck-canada.ca/my_demo_programs/DPOpenGLsgi1981.rar
Это программа составленная мной на ассемблере FASM использует OpenGL и демонстрирует сферы.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)