2015-03-18 5 views
0

Так что я делаю игру (что-то похожее на понг) с помощью openGl в cpp, и когда я пытаюсь запустить программу, рендеринг изображений слишком медленный, я чувствую, что что-то сильно падает моя память GPU, (До сих пор я соревновался с рисунком и движением весла, который отлично работает, и проблема возникает, когда мяч настроен на движение при нажатии кнопки, после этого все замедляется) Здесь я добавил часть своего кода указать на недостатки в моем кодеOpengl Проблемы с производительностью,

#include<stdlib.h> 
    #include<GL/glut.h> 
    #include<windows.h> 
    #include<iostream> 
    //#include<sstream> 
    #include<stdio.h> 
    #include<ctime> 
    #include<string.h> 






    typedef double point[3]; 
    point a,b,c,d; 
    static float xmove=0.0; 
    static int release=0; 
    static float ii=0.00; 

    static int reac_top; 


    using namespace std; 
    //GLvoid player1_box(); 
    GLfloat xangle=0.0; 
    float changeDir=1;// positive direction 
    double vv[4][3]={ {0.5,0.2,0.0},{ 0.5,0.25,0.0},{0.7,0.25,0.0},{0.7,0.2,0.0}}; 


    void renderoutline() 
    { 
     glBegin(GL_LINE_LOOP); 

     glColor3f(1,0,0); 
     glVertex2f(0.0,0.0); 
     glColor3f(1,0,0); 
     glVertex2f(0,1.2); 
     glColor3f(1,0,0); 
     glVertex2f(1.2,1.2); 
     glColor3f(1,0,0); 
     glVertex2f(1.2,0); 

     glEnd(); 
    } 

    void ball() 
    { 
     glBegin(GL_POLYGON); 
     glColor3f(0,0,1); 
     glVertex3f(0.6,0.25,0.0); 
     glColor3f(0,0,1); 
     glVertex3f(0.6,0.28,0.0); 
     glColor3f(0,0,1); 
     glVertex3f(0.62,0.28,0.0); 
     glColor3f(0,0,1); 
     glVertex3f(0.62,0.25,0.0); 

      glEnd(); 
    } 
    void renderbox1(point a , point b , point c, point d) 
    { 

     glBegin(GL_POLYGON); 
     glColor3f(0,0,0); 
     glVertex3dv(a); 
     glColor3f(0,0,0); 
    glVertex3dv(b); 
    glColor3f(0,0,0); 
    glVertex3dv(c); 
    glColor3f(0,0,0); 
    glVertex3dv(d); 
    glEnd(); 
    } 


    void keyboard(unsigned char key,int x,int y) 
    { 

    switch(key){ 

     case 'a':xangle-=0.1; 

       ++xmove; 

       while(xmove>5) 
       { 
        xmove=-5; 

        xangle=0.5; 
        continue; 
       } 
       break; 
     case 'd':xangle+=0.1; 
       --xmove; 
       while(xmove<-5) 
       { 
        xmove=5; 
        xangle =-0.5; 
        continue; 
       } 
       break; 
     case 'r': 

      release=1; 
      //printf("Inside switch r"); 
      break; 
     } 
    glutPostRedisplay(); 

    } 







    void display() 
    { 
     Sleep(2); 

    glClear(GL_COLOR_BUFFER_BIT); 

    glPushMatrix(); 
    glLineWidth(3.0); 
    glLoadIdentity(); 

    glTranslatef(xangle,0,0); 
    renderbox1(vv[0],vv[1],vv[2],vv[3]); // To draw the paddle 
    glPopMatrix(); 
    //printf("x move in disp:%1f \n",xmove); 
    renderoutline(); 

    glPushMatrix(); 
    glTranslatef(0,ii,0); 
    ball();        //To draw the ball 
    glPopMatrix(); 

    glFlush(); 


    } 
    void moveBall(){   //glutidlefunction 

     if(release==1) 
     {    //Release becomes one when the key 'r' is pressed (glutkeyboardfunc) 
     Sleep(500); 

     if(ii>=0&&ii<=0.9) 
     { 
     reac_top=false; 
     ii=ii+0.05;printf("1\n");//The ball which was intially on the paddle starts moving till it reaches the top edge of thescreen 
     } 

    else if(ii>=0.9) 
    { 
           //when the boll reaches top 
     ii=ii-0.05; 
     reac_top=3; 
     printf("2\n"); 

    } 
     else if((ii<0.9)&& (reac_top==3)&&(ii>0.05)) //The balls journey back to the paddle 
     { 
      printf("3\n"); 
      ii=ii-0.05; 

     } 
    release=1; 
     } 

    } 


    void reshape(int w, int h) 
    { 
     glMatrixMode(GL_PROJECTION); 
     glLoadIdentity(); 
     glOrtho(0, 1.2, 0, 1.2,-10.0,10.0); 
     glMatrixMode(GL_MODELVIEW); 
     glViewport(0,0,w,h); 
     //glutPostRedisplay(); 
    //Use the whole window for rendering 
    } 

    int main(int argc ,char **argv) 
    { 
     //clock_t begin= clock(); 
     char n1,n2; 
     int ack; 
    /*printf("The object of Tic Tac Toe is to get three in a row. \n . Players alternate placing Xs and Os(Traingles and Boxes in this version) \n on the game board until either opponent has three \n in a row or all nine squares are filled(Which would be a drawObviously). \n"); 
    printf("\n Press 1 if acknowledged \n"); 
    scanf("%d",&ack);*/ 
    glutInit(&argc,argv); 
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); 
    glutInitWindowSize(1000,500); 
    glutInitWindowPosition(200,0); 

    glutCreateWindow("3d Gasket"); 
    glutDisplayFunc(display); 

    glutKeyboardFunc(keyboard); 
    glutReshapeFunc(reshape); 
    glutIdleFunc(moveBall); 
    glClearColor(1,1,1,1); 
    glutMainLoop(); 
    //clock_t end=clock(); 
    } 
+1

На стороне записки, оказание прямого режима (например, 'glBegin()' и 'glEnd()') является устаревшим с августа 2008 года Другими словами , если бы вы написали свой код 7 лет назад, это было бы уже устаревшим. Вы должны найти учебник, в котором используется современный OpenGL (например, https://open.gl/ или http://www.learnopengl.com/). – Julian

+0

Я попробую современные концепции, как только я познакомлюсь со старыми, я только что начал openGlv :) –

ответ

2
  • Вы с помощью , используйте C++ - стиль (stdlib.h ->cstdlib).
  • Применяйте матрицы матриц проекции/модели каждый раз через display() вместо обратного вызова с изменением формы, что помогает предотвратить неприятные проблемы с матричным стеклом.
  • Не используйте Sleep(), используйте обратный вызов таймера/простоя до glutPostRedisplay(). Бонусные баллы за framerate-independent movement (вы можете использовать glutGet(GLUT_ELAPSED_TIME) для расчета дельта-t).
  • Без Sleep() нет причин перетащить windows.h в вещи.

Все вместе:

#include <GL/glut.h> 
#include <iostream> 
#include <cstdlib> 
#include <cstdio> 
#include <ctime> 
#include <cstring> 

typedef double point[3]; 
point a,b,c,d; 
static float xmove=0.0; 
static int release=0; 
static float ii=0.00; 

static int reac_top; 

using namespace std; 

GLfloat xangle=0.0; 
float changeDir=1;// positive direction 
double vv[4][3]={ {0.5,0.2,0.0},{ 0.5,0.25,0.0},{0.7,0.25,0.0},{0.7,0.2,0.0}}; 

void renderoutline() 
{ 
    glBegin(GL_LINE_LOOP); 

    glColor3f(1,0,0); 
    glVertex2f(0.0,0.0); 
    glColor3f(1,0,0); 
    glVertex2f(0,1.2); 
    glColor3f(1,0,0); 
    glVertex2f(1.2,1.2); 
    glColor3f(1,0,0); 
    glVertex2f(1.2,0); 

    glEnd(); 
} 

void ball() 
{ 
    glBegin(GL_POLYGON); 
    glColor3f(0,0,1); 
    glVertex3f(0.6,0.25,0.0); 
    glColor3f(0,0,1); 
    glVertex3f(0.6,0.28,0.0); 
    glColor3f(0,0,1); 
    glVertex3f(0.62,0.28,0.0); 
    glColor3f(0,0,1); 
    glVertex3f(0.62,0.25,0.0); 

    glEnd(); 
} 

void renderbox1(point a , point b , point c, point d) 
{ 
    glBegin(GL_POLYGON); 
    glColor3f(0,0,0); 
    glVertex3dv(a); 
    glColor3f(0,0,0); 
    glVertex3dv(b); 
    glColor3f(0,0,0); 
    glVertex3dv(c); 
    glColor3f(0,0,0); 
    glVertex3dv(d); 
    glEnd(); 
} 

void keyboard(unsigned char key,int x,int y) 
{ 
    switch(key) 
    { 
    case 'a':xangle-=0.1; 
     ++xmove; 
     while(xmove>5) 
     { 
      xmove=-5; 
      xangle=0.5; 
      continue; 
     } 
     break; 

    case 'd':xangle+=0.1; 
     --xmove; 
     while(xmove<-5) 
     { 
      xmove=5; 
      xangle =-0.5; 
      continue; 
     } 
     break; 

    case 'r': 
     release=1; 
     break; 
    } 
} 

void display() 
{ 
    glClearColor(1,1,1,1); 
    glClear(GL_COLOR_BUFFER_BIT); 

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glOrtho(0, 1.2, 0, 1.2,-10.0,10.0); 

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 

    glPushMatrix(); 
    glLineWidth(3.0); 
    glLoadIdentity(); 

    glTranslatef(xangle,0,0); 
    renderbox1(vv[0],vv[1],vv[2],vv[3]); // To draw the paddle 
    glPopMatrix(); 
    renderoutline(); 

    glPushMatrix(); 
    glTranslatef(0,ii,0); 
    ball(); 
    glPopMatrix(); 

    glFlush(); 
} 

void moveBall() 
{ 
    if(release==1) 
    { 
     //Release becomes one when the key 'r' is pressed (glutkeyboardfunc) 
     if(ii>=0&&ii<=0.9) 
     { 
      reac_top=false; 
      ii=ii+0.05;printf("1\n");//The ball which was intially on the paddle starts moving till it reaches the top edge of thescreen 
     } 

     else if(ii>=0.9) 
     { 
      //when the boll reaches top 
      ii=ii-0.05; 
      reac_top=3; 
      printf("2\n"); 

     } 
     else if((ii<0.9)&& (reac_top==3)&&(ii>0.05)) //The balls journey back to the paddle 
     { 
      printf("3\n"); 
      ii=ii-0.05; 

     } 
     release=1; 
    } 
} 

void timer(int value) 
{ 
    moveBall(); 

    glutTimerFunc(16, timer, 0); 
    glutPostRedisplay(); 
} 

int main(int argc ,char **argv) 
{ 
    glutInit(&argc,argv); 
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); 
    glutInitWindowSize(1000,500); 
    glutInitWindowPosition(200,0); 
    glutCreateWindow("3d Gasket"); 
    glutDisplayFunc(display); 
    glutKeyboardFunc(keyboard); 
    glutTimerFunc(0, timer, 0); 
    glutMainLoop(); 
} 
+0

Кроме того, я бы также рекомендовал использовать двойную буферизацию. Но да, я очень подозрительно отношусь к вызовам 'Sleep()' в исходном коде. Сама рендеринг настолько тривиальна, что не должно быть никаких проблем с производительностью даже при немедленном рендеринге режима. –

+0

@RetoKoradi, Спасибо, много помощника, который действительно закрепил процесс, какова была ваша причина для удаления функции idlecallback? и да, мне понравилась ваша идея о reshapefunc и интеграции модели и проекции внутри дисплея :) –

+0

Ох, да, swapbuffers(), я забыл о двойной буферной части, думаю, я могу оптимизировать ее еще больше, спасибо, человек очень помог :) –

Смежные вопросы