Команды интерпретации файлов и Glut - PullRequest
0 голосов
/ 28 января 2012

У меня сейчас проблема с программой, которую я пытаюсь создать.Программа берет файл, переданный через argv, анализирует его для команд, извлекает значения и запускает команды перенасыщения на основе информации.

У меня есть метод, directFile, и я специально фокусируюсь на регистре переключателя 'c',Файл, который я передаю, имеет команду 'cone', которая просто создает конус с радиусом .5 и высотой 1. Поэтому, когда коммутатор видит эту команду, он вызывает функцию 'drawCone'.

Issue imв том, что 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 Ответ

1 голос
/ 28 января 2012

Вы должны вызвать рисование конуса из внутри функции обратного вызова дисплея.

Затем вы можете прочитать файл в функции 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 , вы можете контролировать этот аспект.

РЕДАКТИРОВАТЬ в качестве альтернативы рассмотрите возможность использования списков отображения : то есть

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