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


Автор: KaraKum 13.3.2008, 21:13
Доброе время суток.
После вызова функции glLoadIdentity() ничего не выводится на экран. Для проверки написал:
Код

glBegin(GL_TRIANGLES);
     glColor3f(1, 0, 0);
     glVertex3f(0, 100, -20);
     glColor3f(0, 1, 0);
     glVertex3f(-100, -100, -20);
     glColor3f(0, 0, 1);
     glVertex3f(100, -100, -20);
glEnd();
glFlush();

Треугольник получается такой гигантский, что должен заполнить весь экран - так и есть, но если перед этим кодом поставить вызов функции glLoadIdentity(), то ничего не рисуется.
Скажите, в чём проблема?

Автор: baldina 14.3.2008, 09:04
здесь играют роль две матрицы - GL_MODELVIEW_MATRIX и GL_PROJECTION_MATRIX. Ты в какую загружаешь?
Какие еще преобразования есть в программе, кроме glLoadIdentity()?

Добавлено через 1 минуту и 2 секунды
Телепатия мне подсказывает, что во вторую, и твой треугольник оказывается за границами отсечения по глубине.

Добавлено через 3 минуты и 36 секунд
Кстати, из приведенного кода не следует, что треугольник гигантский и что-то должен заполнить. Весь код желательно увидеть.
Если только все матрицы у тебя не Identity - тогда на экране единичный куб.

Автор: KaraKum 14.3.2008, 10:32
Твоя интуиция - надёжная штука  smile .

Вот код:
Код

void LineSegment();
void MouseEvent(GLint button, GLint action, GLint xMouse, GLint yMouse);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    ...
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutCreateWindow("My first OpenGL program based on GLUT.lib");
    glutFullScreen();

    InitGL();

    glutMainLoop();    
}

void InitGL()
{
    glutDisplayFunc(LineSegment);
    glutMouseFunc(MouseEvent);

    glClearColor(0, 0, 0, 0);
    glMatrixMode(GL_PROJECTION);
    gluPerspective(45, 1024/768, 0, 100);
    glTranslatef(-4.15, -4.15, -10);
}

void LineSegment()
{
    glLoadIdentity(); //не важно комментировать эту строку или нет - результат тот же - по диагонали экрана проходит линия
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1, 0, 0);
    glBegin(GL_LINES);
        glVertex3f(-100, -100, 100);
        glVertex3f(100, 100, -100);
    glEnd();
    glFlush();
}

void MouseEvent(GLint button, GLint action, GLint xMouse, GLint yMouse)
{
    glLoadIdentity(); //в этой и следующей функции как раз и проблема
    glTranslatef(-4.15, -4.15, -10); //если закоментировать хоть одну из них (причём не важно какую) или обе, то треугольник рисуется
    glBegin(GL_TRIANGLES);
        glColor3f(1, 0, 0);
        glVertex3f(0, 100, -80);
        glColor3f(0, 1, 0);
        glVertex3f(-100, -100, 80);
        glColor3f(0, 0, 1);
        glVertex3f(100, -100, 80);
    glEnd();
    glFlush();
}


Периодически нужно сбрасывать предыдущую матрицу и устанавливать новую, но если использовать функции glLoadIdentity() и glTranslatef() вместе, то уже ничего нельзя вывести на экран.

Автор: Graf_h 14.3.2008, 10:47
Тебе нужно перед преобразованиями записывать состояния матриц а после преобразований их восстановлять и тогда будет тебе счастье  smile 

Автор: KaraKum 14.3.2008, 11:28
После
Код

glLoadIdentity();
glTranslatef(-4.15, -4.15, -10);

вставил функцию glMatrixMode(GL_PROJECTION); - всё равно ничего не рисуется  smile .
И заодно ещё вопросик: почему функция glutTimerFunc(40, ProcessTimerEvent, 1); вызывает функцию ProcessTimerEvent() только один раз, хотя должна делать это 25 раз в секунду?

Автор: Graf_h 14.3.2008, 11:36
glPushMatrix();//Запоминаеш состояние преобразований
   glLoadIdentity(); //Здесь сбиваеш все преобразования и загружаеш единичную матрицу
   glTranslatef(...); // твои преобразования но уже отностельно центра...
    glBegin(GL_TRIANGLES);
        glColor3f(1, 0, 0);
        glVertex3f(0, 100, -80);
        glColor3f(0, 1, 0);
        glVertex3f(-100, -100, 80);
        glColor3f(0, 0, 1);
        glVertex3f(100, -100, 80);
    glEnd();
glPopMatrix():// восстановляеш состояние преобразований
glFlush();


А насчет ProcessTimerEvent(): нужно ее вызывать и в ProcessTimerEvent и также нужно обновлять окно glutPostRedisplay();  

Автор: KaraKum 14.3.2008, 12:09
Изменил код и теперь он выглядит так:
Код

glPushMatrix();
glLoadIdentity();
glTranslated(0, 0, -3);
glBegin(GL_TRIANGLES);
    glColor3f(1, 0, 0);
    glVertex3f(0, 100, -80);
    glColor3f(0, 1, 0);
    glVertex3f(-100, -100, 80);
    glColor3f(0, 0, 1);
    glVertex3f(100, -100, 80);
glEnd();
glFlush();
glPopMatrix();

Но всё равно ничего не рисуется!  smile А если закомментировать 2-ю и 3-ю строки, то всё ОК.

Насчёт таймера: если я правильно понял, в конце функции ProcessTimerEvent() нужно вызвать glutTimerFunc(40, ProcessTimerEvent, 1);
И если так, то плохо, что в таком случае программа пожирает всё процессорное время.

Автор: Graf_h 14.3.2008, 12:27
Код

....
void SetupRC(void){
glClearColor(0.0f,0.0f,0.0f,1.0f);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);


}
//рисуем твой треугольник
void RenderScene(void){
     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
     
     glPushMatrix();
glLoadIdentity();
glTranslated(0, 0, -40);
glBegin(GL_TRIANGLES);
    glColor3f(1, 0, 0);
    glVertex3f(0, 10, -8);
    glColor3f(0, 1, 0);
    glVertex3f(-10, -10, 8);
    glColor3f(0, 0, 1);
    glVertex3f(10, -10, 8);
glEnd();

glPopMatrix();
glutSwapBuffers();
glutPostRedisplay();
}

void changeSize(GLsizei w,GLsizei h){
GLfloat asp;

    if (h==0) h=1;

glViewport(0,0,w,h);
asp= GLfloat (w)/GLfloat (h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,asp,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

}

void  main(void)
{
    HWND hdwind = GetDesktopWindow();
    HDC hdescDc = GetDC(hdwind);
    int resolutWIDTH=GetDeviceCaps(hdescDc,HORZRES); 
            int resolutHEIGHT = GetDeviceCaps(hdescDc,VERTRES);
    int xx= (resolutWIDTH/2)-400;
    int yy= (resolutHEIGHT/2)-300;

    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB |GLUT_DEPTH);
    glutInitWindowSize(800,600);
    glutInitWindowPosition(xx,yy);
    glutCreateWindow("VSL_Game studio");
    glutReshapeFunc(changeSize);
    glutDisplayFunc(RenderScene);
    SetupRC();
    glutMainLoop();
    
}





Вот тебе пример твоей програмы, все работает! smile 

Ты задавал очень большие координаты, поэтому триугольник у тебя был большой и ты его не видел

Автор: KaraKum 14.3.2008, 13:15
Вуаля! В InitGL() добавил функцию glMatrixMode(GL_MODELVIEW); и всё заработало!
Большое спасибо smile .

Но с таймером так и не решилось:
Цитата

Насчёт таймера: если я правильно понял, в конце функции ProcessTimerEvent() нужно вызвать glutTimerFunc(40, ProcessTimerEvent, 1);
И если так, то плохо, что в таком случае программа пожирает всё процессорное время.

Автор: Graf_h 14.3.2008, 13:29
Я ставил 2 таймера, и ничего не пожерало работало отлично и без тормозов! Здесь просто 25 раз в секунду вызывается твоя функция и все...Можеш сделать свой таймер, например через GetTickCount()

Автор: KaraKum 14.3.2008, 13:54
Да я проверил. Хоть в диспетчере задач и написано, что прога потребляет 100% процессорного времени, но все остальные проги работают нормально, даже проигрыватель.
Вобщем всё что хотел узнать - узнал. Спасибо. Вопрос решён.

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