PMG https://forum.pmg.org.ru/ |
|
О трансформации https://forum.pmg.org.ru/viewtopic.php?f=1&t=8039 |
Страница 1 из 1 |
Автор: | zauber [ 09 сен 2010 10:59 ] |
Заголовок сообщения: | О трансформации |
В Open GL новичек. Возник вопроc. Если я правильно понял, при трансформации матрица применяется к сцене. После чего необходимо перерисовывать объекты на сцене. К примеру: void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { glMatrixMode(GL_PROJECTION); if(Key == VK_LEFT) glRotatef(-5, 0.0f, 1.0f, 0.0f); else if(Key == VK_RIGHT) glRotatef(5, 0.0f, 0.1f, 0.0f); else if(Key == VK_UP) glRotatef(5, 1.0f, 0.0f, 0.0f); else if(Key == VK_DOWN) glRotatef(-5, 1.0f, 0.0f, 0.0f); PaintScene(); } void TForm1::PaintScene() { glMatrixMode(GL_MODELVIEW); glColor3f(1.0f,0.0f,1.0f); gluSphere (quadObj, 30, 16, 16); } Ели это так, есть ли способ выполнять трансформацию сцены с объектами, не перерисовывая объекты на сцене ? И еще, как зафиксировать источник света, чтобы он не вращался вместе со сценой ? В одном топике прочел, что этот вопрос уже задавался, но так и не нашел ответ. |
Автор: | isaer [ 09 сен 2010 11:42 ] |
Заголовок сообщения: | Re: О трансформации |
можно сделать таймер и вызывать в нем каждые 10 милисекунд отрисовку и тогда можно не писать это а просто само будет как бы с освещением е знаю точно но читал там нужно для него установить матрицупроекционную вроде и нарисовать а я вобще не понимаю зачем эти матрицы писать можешь объяснить?? просто нигде не видел вроде, я делал так: писал в решейпе установку матрицы проекции потом очищял ее потом устанавливал перспективу потом ставил матрица вида моделей и очишял ее и получалось что все нормально не понимаю зачем писать при рисовании объекта если можно сразу написать и потом она автоматически будет как бы подстовлятся и так же ее надо очистить glLoadIdentity(); после установки матрицы Цитата: не перерисовывая объекты на сцене ? или это вобще не рисуя их?? если не рисую то это невозможно, у тя будет просто стоять картинка и все Код: PaintScene(); } void TForm1::PaintScene() зачем так делать?? можно хотябы сделать glutPostRedisplay(); и тоже самое будет но рендер надо написать в glutDisplayFunc(PaintScene); ну это если ты через глут |
Автор: | zauber [ 09 сен 2010 18:30 ] |
Заголовок сообщения: | Re: О трансформации |
Думаю, перерисовывать каждые 10 миллисекунд не самый хороший путь. Зачем заставлять проц выполнять лишнюю работу ? А так перерисовка наступает только при событии нажатия клавиши. Вопрос возник вот почему- если объектов на сцене десятки тысяч - придется перерисовывать их в цикле. Подумал если трансформируется сцена, то может вместе с ней сразу и трансформировать объекты можно ? Матрица, я так понимаю, вызывается неявно при вызове функции преобразования: Rotatef - по параметрам строится матрица поворота. |
Автор: | zauber [ 09 сен 2010 18:33 ] |
Заголовок сообщения: | Re: О трансформации |
Забыл. Ни glaux ни glut не использую. Glut, думаю, при использовании Buildera вообще нет смысла использовать. |
Автор: | isaer [ 09 сен 2010 21:42 ] |
Заголовок сообщения: | Re: О трансформации |
а ну тогда не знаю к сожелению |
Автор: | rabbit [ 09 сен 2010 23:12 ] |
Заголовок сообщения: | Re: О трансформации |
Вообще по работе с OpenGL под C++ Builder с формами есть много инфы. В гугле просто вбиваешь "C++ Builder 6 OpenGL" Сам програмлю на бюлдере. Первые опыты были как раз под форму, но потом перешел под консоль - люблю что б везде был мой код: если что-то не работает, можно понять почему; да и ничего лишнего не написано никогда. 1) glMatrixMode(GL_MODELVIEW); не нужно вызывать каждый раз при отрисовке. Если в событии FormResize ты написал код обработки типа: {glViewport(0,0,Width,Heigth); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective("твои параметры); //возможно gluOrho - не знаю у тебя выбрано glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //и раз ты хочешь отрисовку только по нажатию по клавише, а не постоянно, то тебе нужно добавить вызов //перерисоки сцены после изменения размеров формы PaintScene(); } 2) При каждом новом рисовании нужно обнулять старую картинку, потому что будет каша void TForm1::PaintScene() {//так что вначале функции поставишь glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //glMatrixMode(GL_MODELVIEW); - это удалишь, не нужно оно тут glColor3f(1.0f,0.0f,1.0f); gluSphere (quadObj, 30, 16, 16); } 3) Если не пользоваться стеком состояния видовой матрицы: glPushMatrix(); и glPopMatrix(); или если не обнулять ее glLoadIdentity(); то ты думаю понимаешь, что сохраняется ее все трансформации, и новые трансформации применяться потом будут уже к матрице, измененной в прошлый раз. Пока что у тебя все будет работать, но когда добавиться побольше транформаций - или будет вылетать иногда прога, или будут непредвиденные казусы. Советуется при обработке клавиш сохранять результаты в некие переменные, а при отрисовке их использовать, например: else if(Key == VK_RIGHT) //glRotatef(5, 0.0f, 0.1f, 0.0f); <---- заменить на ---> yRot +=5; и код рисования должен иметь вид: PaintScene() {glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); <все трансформации над обьектом, типа> <glRotatef(yRot, 0.0f, 0.1f, 0.0f);> <отрисовка обьекта> glPopMatrix(); и т.д. } 4) В Бюлдере точность таймера составляет около 30-60 мс, на разных процессорах по разном себя показывает. Так что или каждые 50мс, или нужно писать свой высокоточный таймер. 5) Да, ты прав ![]() 6) По параметрам glRotatef строится матрица поворота и множится потом она на текущую матрицу GL_MODELVIEW, преобразовывая ее. И ко всем обьектам, которые будут нарисованы после преобразования - будут применено это преобразование. 7) На форуме очень сложно все обьяснить - на картинках это намного нагляднее и понятно. Хорошо помогут уроки Нехе, и немного сайт gamedev.ru - правда там нету норм примеров с скрин-шотами. Мне очень помогла "OpenGL Супер книга 3е издание" . Правда когда искал в электронке ее не было, так что купил на рынке бумажный вариант. |
Автор: | zauber [ 10 сен 2010 11:22 ] |
Заголовок сообщения: | Re: О трансформации |
Как раз пытаюсь писать по книге Open GL суперкнига - нашел ее в сети. ) К сожалению там не описано как зафиксировать источник света. Читал и уроки NeHe и RedBook там про это как- то не очень понятно написано. В какое бы место кода я не вставлял строчки GLfloat lightpos[] = {-200.0f,200.0f,300.0f,1.0f}; glLightfv(GL_LIGHT0,GL_POSITION,lightpos); источник света вращается вместе со сценой. Должны быть три координатных оси графера. Сфера в центре просто для проверки освещения. Точек на графике может быть в пределе 860 000 - каждая объект типа сфера. То есть по любому придется при трансформациях их все перерисовывать в цикле ? И еще столкнулся с тем, что иногда создается неокрашенная панель - как-будто программа не получает hDc. При этом никаких сообщений не возникает. Код в общем такой: bool TForm1::OpenGLInit() { if((hDC = GetDC(Panel1->Handle)) == NULL) return false; SetGLPixelFormat(hDC); if((hRC = wglCreateContext(hDC)) == NULL) return false; if(!wglMakeCurrent(hDC, hRC)) return false; GLfloat diffuselight[] = {0.7f,0.7f,0.7f,1.0f}; GLfloat ambientlight[] = {0.3f,0.3f,0.3f,1.0f}; glLightfv(GL_LIGHT0,GL_AMBIENT,ambientlight); glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuselight); GLfloat lightpos[] = {-200.0f,200.0f,300.0f,1.0f}; glLightfv(GL_LIGHT0,GL_POSITION,lightpos); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE); glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glColor3f(0.0f,1.0f,0.0f); glEnable(GL_DEPTH_TEST); return true; } //--------------------------------------------------------------------------- void TForm1::SetGLPixelFormat(HDC hdc) { int PixelFormatIndex; PIXELFORMATDESCRIPTOR PixelFormat = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0 }; PixelFormatIndex = ChoosePixelFormat(hdc, &PixelFormat); SetPixelFormat(hdc, PixelFormatIndex, &PixelFormat); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormCreate(TObject *Sender) { if(!OpenGLInit()) ShowMessage("..."); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormPaint(TObject *Sender) { PaintScene(); } //--------------------------------------------------------------------------- void TForm1::ShowAxe() { glShadeModel(GL_FLAT); glFrontFace(GL_CW); quadObj = gluNewQuadric (); gluQuadricNormals(quadObj, GLU_SMOOTH); gluQuadricDrawStyle(quadObj, GLU_FILL); glPushMatrix(); glRotatef(90, 0.0f, 1.0f, 0.0f); gluCylinder(quadObj,1,1, 200, 32, 32); glTranslatef(0.0f,0.0f,200.0f); glColor3f(0.0f,0.0f,1.0f); gluCylinder(quadObj,4,0, 30, 32, 32); glColor3f(0.0f,0.5f,0.1f); gluDisk(quadObj,0.0f,4.0f,32,32); glPopMatrix(); } //--------------------------------------------------------------------------- void TForm1::PaintScene() { glMatrixMode(GL_MODELVIEW); glPushMatrix(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); ShowAxe(); glLoadIdentity(); glRotatef(-90,0,1,0); ShowAxe(); glLoadIdentity(); glRotatef(90,0,0,1); ShowAxe(); glColor3f(1.0f,0.0f,1.0f); gluSphere (quadObj, 30, 16, 16); glPopMatrix(); glMatrixMode(GL_PROJECTION); SwapBuffers(hDC); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormResize(TObject *Sender) { SetSize(); } //--------------------------------------------------------------------------- void TForm1::SetSize() { float nRange = (Panel1->Width < Panel1->Height)?Panel1->Width/2:Panel1->Height/2; w = Panel1->Width; h = Panel1->Height; if(h == 0) h = 1; glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(w <= h) glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -500, 500); else glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -500, 500); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormDestroy(TObject *Sender) { wglMakeCurrent (NULL, NULL) ; wglDeleteContext(hRC); ReleaseDC(Handle,hDC); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { glMatrixMode(GL_PROJECTION); if(Key == VK_LEFT) glRotatef(-5, 0.0f, 1.0f, 0.0f); else if(Key == VK_RIGHT) glRotatef(5, 0.0f, 0.1f, 0.0f); else if(Key == VK_UP) glRotatef(5, 1.0f, 0.0f, 0.0f); else if(Key == VK_DOWN) glRotatef(-5, 1.0f, 0.0f, 0.0f); PaintScene(); } |
Автор: | MagicWolf [ 10 сен 2010 14:50 ] |
Заголовок сообщения: | Re: О трансформации |
zauber писал(а): Ели это так, есть ли способ выполнять трансформацию сцены с объектами, не перерисовывая объекты на сцене ? Не понимаю, можно сколько угодно трансформировать объекты и не рендерить их. Вроде проблем нет. |
Автор: | rabbit [ 10 сен 2010 22:55 ] |
Заголовок сообщения: | Re: О трансформации |
Ага.... теперь понял чего ты хочешь добиться.... Лучше я проверю сначала все свои догадки на примерах, и потом скажу что тебе лучше делать. Сегодня уже нету времени... Завтра постараюсь отписаться по твоим вопросам. |
Автор: | zauber [ 11 сен 2010 00:21 ] |
Заголовок сообщения: | Re: О трансформации |
Спасибо. В части фиксации источника света- я понял как это сделать. Можно двумя разными способами. В части повторной перерисовки после поворотов -понял, что избежать этого невозможно. Только с периодической потерей контекста не разобрался. ) Но все равно будет интересно узнать твое мнение. ) |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа [ Летнее время ] |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |