2012-01-27 39 views
0

我現在有一個問題,正在嘗試創建一個程序。該程序需要一個通過argv傳遞的文件,解析它的命令,提取值,並根據信息運行glut命令。文件解釋和Glut命令

我有一個方法,directFile和im特別專注於開關案例'c'。文件im傳遞的命令是'cone',它只是創建一個半徑爲0.5和高度爲1的圓錐體。所以當開關看到這個命令時,它會調用函數'drawCone'。

問題是,drawCone不會在過剩窗口中繪製一個錐體。它什麼也沒做。但是,如果我把相同的代碼放在顯示功能中,它就可以正常工作。我非常新的貪婪,所以容易在我身上!但是我需要一些建議,讓我的代碼做我想做的事情。

#include <gl\glew.h> 
#include <gl\freeglut.h> 
#include <gl\GLU.h> 
#include <stdio.h> 

void directFile(char input[]); 
void extractVals(char *input,double *val); 
void makeLower(char *input); 
void drawCone(); 

int g_mainWindow = -1; 
float g_lightPos[] = {1, 1, -1, 0}; 

/* 
    Draw a cone 
*/ 
void drawCone(){ 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    glColor3f(1,0,0); 
    glutSolidCone(.5,1,8,1); 




    //glLoadIdentity(); 

    glFlush(); 

} 


void display() 
{ 


    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    /* 
    glColor3f(1,0,0); 
    glutSolidCone(.5,1,8,1);*/ 


    //glLoadIdentity(); 

    glFlush(); 
} 

void reshape(int w, int h) 
{ 
    float aspect = w/(float)h; 

    glViewport(0,0,w,h); 
    glMatrixMode(GL_PROJECTION_MATRIX); 
    glLoadIdentity(); 
    glOrtho(-aspect, aspect, -1, 1, -1, 1); 
    glMatrixMode(GL_MODELVIEW_MATRIX); 
} 


void idle() 
{ 
    glutSetWindow(g_mainWindow); 
    glutPostRedisplay(); 
} 

/* 
    Takes a file input and parses out the instructions needed to draw an object 
*/ 
void directFile(char input[100]){ 
    char switchVal [10] , *s = switchVal; 
    double val[4]; 

    s = strtok(input, " \n\0"); 
    switch(*s){ 
     case 'g'://translate object 
      extractVals(s , val); 
      break; 
     case 's'://scales an object 
      printf("%s is the command to scale, now which one is it?\n",s); 
      extractVals(s , val); 
      if(val[3] == 1.){ 
       printf("The object will be scaled by %f\n", val[0]); 
      } else if (val[3] == 3.){ 
       printf("The object will be shrunk by sx: %f , sy: %f, sz: %f\n", val[0] , val[1] , val[2]); 
      } 
      break; 
     case 'r'://rotates an object 
      printf("%s will rotate the image!\n",s); 
      break; 
     case 'c'://this can call draw cone , cube, or change colors. 
      if(strcmp(s , "cone") == 0){ 
       printf("It appears you have your self a %s. Lets draw it!\n", s); 
       drawCone(); 
      } else if (strcmp(s , "cube") == 0){ 
       printf("%s is cool too\n" , s); 
      } else if (*s == 'c'){ 
       printf("Welp command was \"%s\", lets change some colors huh?\n",s); 
      } 
      break; 
     case 't'://draw a torus or tea pot 
      break; 
     case 'o'://reads a meshfile 
      break; 
     case 'f'://save current frame buffer. 
      break; 
     case 'm': 
      break; 
    } 
} 

/* 
    Using a tolenizer this extracts out values needed for other functions to draw. 
*/ 
void extractVals(char *input, double *val){ 
    int i=0; 
    input = strtok(NULL, " ,"); 
    while(input != NULL){ 
     val[i] = atof(input); 
     input = strtok(NULL, " ,"); 
     i++; 
    } 
    val[3] = i--; 
} 

/* 
    Since the read file is not case sesitive we will force everything lowercase. 
*/ 
void makeLower(char *input) 
{ 
    while (*input != '\0') 
    { 
     *input = tolower(*input); 
     input++; 
    } 
} 

/* 
    main class! 
*/ 
int main(int argc, char **argv) { 

    //imports file from ar 
    FILE *file = fopen(argv[1], "r");//file opened 
    char linebyline [50], *lineStr = linebyline; 


    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH); 
    g_mainWindow = glutCreateWindow("Hello, glut"); 

    while(!feof(file) && file != NULL){ 
     fgets(lineStr , 50, file); 
     makeLower(lineStr); 
     directFile(lineStr); 
    } 
    fclose(file); 

    glClearColor(0.5, 0.5, 0.5, 0); 
    glEnable(GL_LIGHTING); 
    glEnable(GL_LIGHT0); 
    glEnable(GL_DEPTH_TEST); 

    glLightfv(GL_LIGHT0, GL_POSITION, g_lightPos); 

    glutDisplayFunc(display); 
    glutReshapeFunc(reshape); 
    glutIdleFunc(idle); 



    glutMainLoop(); 
} 

回答

1

必須調用錐圖紙從顯示回調函數。

然後,您可以讀取Idle函數中的文件,並且每個命令都會生成glutPostRedisplay(),以獲取動畫顯示。喜歡的東西:

FILE *file; 
void Idle() 
{ 
    /* parse a command from file */ 
    /* store the data for later draw */ 
    glutPostRedisplay(); 
} 

void display() 
{ 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    glLoadIdentity(); 
    /* use data read from Idle 
    glColor3f(1,0,0); 
    glutSolidCone(.5,1,8,1); 
    */ 
    glFlush(); 
    // also consider glutSwapBuffers for smoothness 
} 

int main() 
{ 
    file = fopen(...); 
} 

過剩的一個問題是,永遠不會返回控制給調用者。如果您使用freeglut您可以控制此方面。

編輯另外,考慮使用 'display lists':即

GLuint commands; 
void display() 
{ 
    ... 
    glCallList(commands); 
    ... 
} 
int main() 
{ 
    ... 
    commands = glGenLists(1); 
    glNewList(commands, GL_COMPILE); 
    /* read file and post display commands */ 
    glEndList(); 
    ... 
} 
+0

將這個讀取文件多次?我只希望它讀一次。 – meriley 2012-01-27 23:29:10

+0

對不起,它不明確:我的意思是在讀取的每個命​​令上生成一個重新顯示。 – CapelliC 2012-01-27 23:38:11

+0

感謝您的闡述。與glColor一起使用glLoadIdentity之後的註釋。那些被稱爲內部閒置的功能?或者只是示例代碼可以追溯到? – meriley 2012-01-27 23:40:52