PMG

Форумы по созданию игр
Текущее время: 26 ноя 2022 20:31

Часовой пояс: UTC + 3 часа [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 10 ] 
Автор Сообщение
 Заголовок сообщения: О трансформации
СообщениеДобавлено: 09 сен 2010 10:59 
Не в сети
Новичок

Зарегистрирован: 09 сен 2010 10:44
Сообщения: 8
В 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);
}

Ели это так, есть ли способ выполнять трансформацию сцены с объектами, не перерисовывая объекты на сцене ?
И еще, как зафиксировать источник света, чтобы он не вращался вместе со сценой ? В одном топике прочел, что этот вопрос уже задавался, но так и не нашел ответ.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: О трансформации
СообщениеДобавлено: 09 сен 2010 11:42 
Не в сети
Любитель
Аватара пользователя

Зарегистрирован: 06 сен 2010 21:15
Сообщения: 21
можно сделать таймер и вызывать в нем каждые 10 милисекунд отрисовку и тогда можно не писать это а просто само будет как бы
с освещением е знаю точно но читал там нужно для него установить матрицупроекционную вроде и нарисовать

а я вобще не понимаю зачем эти матрицы писать
можешь объяснить?? просто нигде не видел вроде, я делал так: писал в решейпе установку матрицы проекции потом очищял ее потом устанавливал перспективу потом ставил матрица вида моделей и очишял ее и получалось что все нормально
не понимаю зачем писать при рисовании объекта если можно сразу написать и потом она автоматически будет как бы подстовлятся и так же ее надо очистить glLoadIdentity(); после установки матрицы


Цитата:
не перерисовывая объекты на сцене ?

или это вобще не рисуя их?? если не рисую то это невозможно, у тя будет просто стоять картинка и все


Код:
PaintScene();
}

void TForm1::PaintScene()


зачем так делать?? можно хотябы сделать glutPostRedisplay();
и тоже самое будет но рендер надо написать в glutDisplayFunc(PaintScene);
ну это если ты через глут

_________________
(\_/)
(O.O) <= слушай его!
(>..<)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: О трансформации
СообщениеДобавлено: 09 сен 2010 18:30 
Не в сети
Новичок

Зарегистрирован: 09 сен 2010 10:44
Сообщения: 8
Думаю, перерисовывать каждые 10 миллисекунд не самый хороший путь. Зачем заставлять проц выполнять лишнюю работу ? А так перерисовка наступает только при событии нажатия клавиши. Вопрос возник вот почему- если объектов на сцене десятки тысяч - придется перерисовывать их в цикле. Подумал если трансформируется сцена, то может вместе с ней сразу и трансформировать объекты можно ? Матрица, я так понимаю, вызывается неявно при вызове функции преобразования: Rotatef - по параметрам строится матрица поворота.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: О трансформации
СообщениеДобавлено: 09 сен 2010 18:33 
Не в сети
Новичок

Зарегистрирован: 09 сен 2010 10:44
Сообщения: 8
Забыл. Ни glaux ни glut не использую. Glut, думаю, при использовании Buildera вообще нет смысла использовать.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: О трансформации
СообщениеДобавлено: 09 сен 2010 21:42 
Не в сети
Любитель
Аватара пользователя

Зарегистрирован: 06 сен 2010 21:15
Сообщения: 21
а ну тогда не знаю к сожелению

_________________
(\_/)
(O.O) <= слушай его!
(>..<)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: О трансформации
СообщениеДобавлено: 09 сен 2010 23:12 
Не в сети
Любитель
Аватара пользователя

Зарегистрирован: 09 янв 2009 15:11
Сообщения: 16
Вообще по работе с 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е издание" . Правда когда искал в электронке ее не было, так что купил на рынке бумажный вариант.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: О трансформации
СообщениеДобавлено: 10 сен 2010 11:22 
Не в сети
Новичок

Зарегистрирован: 09 сен 2010 10:44
Сообщения: 8
Как раз пытаюсь писать по книге 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();
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: О трансформации
СообщениеДобавлено: 10 сен 2010 14:50 
Не в сети
Гуру
Аватара пользователя

Зарегистрирован: 03 авг 2004 10:37
Сообщения: 2694
zauber писал(а):
Ели это так, есть ли способ выполнять трансформацию сцены с объектами, не перерисовывая объекты на сцене ?


Не понимаю, можно сколько угодно трансформировать объекты и не рендерить их. Вроде проблем нет.

_________________
С уважением, Сергей


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: О трансформации
СообщениеДобавлено: 10 сен 2010 22:55 
Не в сети
Любитель
Аватара пользователя

Зарегистрирован: 09 янв 2009 15:11
Сообщения: 16
Ага.... теперь понял чего ты хочешь добиться.... Лучше я проверю сначала все свои догадки на примерах, и потом скажу что тебе лучше делать. Сегодня уже нету времени... Завтра постараюсь отписаться по твоим вопросам.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: О трансформации
СообщениеДобавлено: 11 сен 2010 00:21 
Не в сети
Новичок

Зарегистрирован: 09 сен 2010 10:44
Сообщения: 8
Спасибо. В части фиксации источника света- я понял как это сделать. Можно двумя разными способами. В части повторной перерисовки после поворотов -понял, что избежать этого невозможно. Только с периодической потерей контекста не разобрался. )
Но все равно будет интересно узнать твое мнение. )


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 10 ] 

Часовой пояс: UTC + 3 часа [ Летнее время ]


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения

Найти:
Перейти:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB