Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Полусфера на поверхности сферы (OpenGL) [Delphi, Windows]


Страницы:   1 2 3 4 5

Creative ©   (2006-11-28 14:34:00) 

Есть Сфера и есть полусфера. Как сделать следующую вещь:
Нарисовать полусфера таким образом стобы ее можно было возить по сфере , останавливая в произвольной точке?
Была мысль использовать для рисования полусферы gluSphere + glClipPlane, но при тех параметрах, которые принимает в себя glClipPlane, не могу понять, как заставить ее произвольно вертеться.
Подскажите что-нибудь.


ancara   (2006-12-01 13:33:00) [41]


> для каждой из них модно установить

для каждой из них мо жно установить
гыгы, гламурный куллинг :)


ancara   (2006-12-01 13:31:00) [42]


> Я пользуюсь GetCursorPos(lpPoint:TPoint).

Дык в процедуру OnMouseMove и так передаются координаты курсора, они хранятся в переменных X и Y :) Ну результат в принципе такой же будет...


> cull-инг  - а это что?

Face culling - это дословно "отбраковка граней", каждый полигон в OpenGL имеет лицевую и обратную стороны, для каждой из них модно установить отдельные свойства  (материал, например). Включив куллинг (glEnable(GL_CULL_FACE)) и указав какие именно грани не рисовать (например обратные: glCullFace(GL_BACK)) мы позволим OpenGL расчитывать только лицевые грани, сэкономив таким образом процессорное время. Это может быть полезно в случае с какими-то замкнутыми фигурами, кубиком напрмер, если мы будем смотреть на него только снаружи и он непрозрачный мы никогда не увидим его обратных граней, т.к. они будут обращены внутрь (об этом надо позаботится отдельно), следовательно их незачем рисовать. Ну куллинг я как пример привел, его не обязательно использовать :)..


> а его собственно надо заключать в
> PushMatrix;
> PopMatrix;

Как это сделано у меня:
в глобальном рендере каждый кадр:

- устанавливаю единичную матрицу:glLoadIdentity;
- поворачиваю и смещаю сист.коорд. согласно положению камеры:
    glRotatef(FCamera.Beta, 1,0,0);
    glRotatef(-FCamera.Alpha, 0,1,0);
    glTranslatef(-FCamera.Position.X,  -FCamera.Position.Y,  -FCamera.Position.Z);

- всякая приблуда: SetupLights; //солнышко светит
- делаю рендеринг всех объектов:   RenderObjects ... (ну это очень упрощенно :)) )
  причем каждый объект перед рендерингом себя:
   - сохраняет матрицу: glPushMatrix;
   - смещает и крутит сист. координат, согласно своей позиции и ориентации;
   - назначает нужный ему материал, ставит куллинг, если надо, включает нужную ему текстуру и т.д., вобщем они у меня все взрослые и самостоятельные...
  - рендерит сам себя: glCallList;
  - возвращает все как было, чтоб следующий не обиделся: glPopMatrix;
  - ну и после того как нарисовали все что хотели : SwapBuffers


Creative   (2006-12-01 12:59:00) [43]


> lpPoint - а что это?


Это переменная типа TPoint, куда складываются координаты курсора. Я пользуюсь GetCursorPos(lpPoint:TPoint).

в OnMouseMove надо вызвать глобальный рендерер (RenderScene или как там?), а в нем уже

а его собственно надо заключать в
PushMatrix;
PopMatrix;
?

cull-инг  - а это что?


ancara   (2006-12-01 12:42:00) [44]

lpPoint - а что это?

а вот насчет кода в OnMouseMove, я что-то затупил, не пойму что там должно получится...
Просто при изменениях свойств одного из объектов сцены нужно вызывать не егорендерер, а рендерер всейсцены, потому что в OpenGL невозможно перерисовать один объект а остальные нет,  если уж перерисовывать кадр так всю сцену придется рисовать.
  Т.е. в OnMouseMove надо вызвать глобальный рендерер (RenderScene или как там?), а в нем уже:
- подготовка всяких параметров (цвет фона там, cull-инг и пр.)
- настройка света;
- установка положения камеры;
- прочие приблуды;
- перебор всех объектов, подлежащих рендерингу и вызов у них метода Render;
- и наконец SwapBuffers;


Creative   (2006-12-01 12:33:00) [45]

Стрелки заработали. Ну, ты понял, что я хочу сказать :-)


Creative   (2006-12-01 12:23:00) [46]

Угу, попробую.

У меня еще вопросы по поводу шариков.
У меня есть два разных объекта класса TSphere (написанного по твоему примеру). Соответственно у класса есть метод отрисовки TSphere.Render, выглядящий примерно так:


 glPushMatrix;
 glTranslatef
 glRotatef(Fbeta, 1,0,0);
 glRotatef(Falpha, 0,1,0);

 glCallList(ListID);  // рисование собственно сферы

 glPopMatrix;


В обработчике onMouseMove вот такой код:

S1.FAlpha:=Round(S1.FAlpha+(lpPoint.X-pX)*0.5);
S1.FBeta:=Round(S1.FBeta+(lpPoint.Y-pY)*0.5);

S1.Render;
S2.Render;


Я сильно надеялась, что этот код заставляет повернуться только одну сферу, а вторую остаться на месте (ты мне вроде бы так объяснял как крутить разные объекты?). Но при запуске картинка вообще не шевелится. Делаешь углы глобальными переменными - опять все нормально, но по прежнему крутится вся сцена целиком. Где я наглючила? Разве не должны сферы двигаться раздельно? Я где-то неправильно поняла?


ancara   (2006-12-01 12:07:00) [47]

Понятно, можно поступить так:
на форму положи компонент TApplicationEvents (вкладка Additional),
в ее обработчике события OnMessage помести такой код:
 if msg.message=WM_KEYDOWN then
 begin
   if msg.wParam=VK_DOWN then //обработать нажатие клавиши "вниз"
   if msg.wParam=VK_UP then //обработать нажатие клавиши "вверх"
//если не хочешь чтоб фокус прыгал по компонентам
//раскоментируй след. строчку
//    handled:=true;
 end;


Creative   (2006-12-01 11:51:00) [48]

Ну смотри, сам напросился. :-)
У меня на форме лежат несколько компонентов. Я делаю обработчик onKeyDown (или onKeyPress, как получится) для клавиш vk_Up/DOWN/LEFT/RIGHT. Но при запуске оказывается, что этот обработчик к жизни не вызывается, а при нажатии на стрелки просто по всем компонентам форму бегает фокус. Как правильно с этим бороться? Я точно помню, что как-то можно, но напрочь забыла - как. :-(


ancara   (2006-12-01 11:49:00) [49]


> не страшно?

:)) Это очень страшно! Через пол-часа придут люди в погонах и предъявят обвинение в умышленном оффтопе в игровой ветке! Не делай этого! Только не это!


Creative   (2006-12-01 11:35:00) [50]

Спасибо, мне за глаза хватит.
Кстати, если я внутри этой ветки один примитивный вопрос по VCL задам  - не страшно?


ancara   (2006-12-01 11:24:00) [51]

нужна карта мира в виде равноугольной проекции Меркатора, т.е. той, на которой и параллели и меридианы параллельны, а полюсами являются верхняя и нижняя строны прямоугольника. Вобщем, вот такая вот: http://img135.imageshack.us/img135/6897/earthdaynq0.jpg
она там правда не очень высокого разрешения, 1024х1024.


Creative   (2006-12-01 10:38:00) [52]

Объяснение отличное, пошла делать. Только переведу LoadTexture на понятный язык. :-)

Скажи, а ечли я хочу сделать например глобус - мне нужна карта мира, вырезанная в виду "апельсиновой корки" или как лучше? (я и сама конечно попробую, просто вдруг у тебя опыт есть)


ancara   (2006-11-30 19:18:00) [53]


> спасибо

На здоровье! :))

> Будем учиться натягивать на шарик текстуру :-)

Нет ничего проще: в BuildList сферы, после вычислений координат вершин,
ну там где glVertex3fv(@Vec2) и glVertex3fv(@Vec1) вставь такой код:

glNormal3fv(@vNorm2);
glTexCoord2f(azi/pi/2, zenNext/pi+0.5);
glVertex3fv(@Vec2);

glNormal3fv(@vNorm1);
glTexCoord2f(azi/pi/2, zen/pi+0.5);
glVertex3fv(@Vec1);

и все, текстурные координаты для вершин заданы, осталось "применить" текстуру к объекту, для этого в рендере, перед вызовом списка glCallList
нужно "забиндить" соответствующую текстуру:
glBindTexture(GL_TEXTURE_2D, Tex_1);
Tex_1 - это идентификатор текстуры, там в процедуре InitGL загружается картинка 1.jpg в качестве текстуры с номером Text_1:
LoadTexture('1.jpg', Tex_1);

Итого, еще раз:
 - в процессе инициализации создается текстура с номером Tex_1 (эта переменная примет некот. значение, мы его у OpenGL попросим);
 - содержимое этой текстуры загружается из файла 1.jpg;
 - в процессе построения диспл. списка сферы для каждой ее вершины указываются текстурные координаты;
 - перед рендерингом сферы, "биндится" (становится текущей) соответствующая текстура;
 - в результате рендеринга получаем сферу с натянутой текстурой;

Вопросы? :)


Creative   (2006-11-30 16:53:00) [54]

В общем, я перетолмачила твой пример на АПИ и теперь все очень здорово работает. ТЫ мне очень помог, спасибо.
Будем учиться натягивать на шарик текстуру :-)


ancara   (2006-11-30 16:35:00) [55]


> в DisplayMouseMove X и Y - это координаты курсора?

так точно


> что происходит при нажатии Alt+левая мышь?

не обращай внимания, это лишнее, я не заметил и забыл удалить. В этом примере раньше на плоскость накладывались две текстуры и одну из них можно было перемещать как раз левой кнопкой с зажатым альтом, а tx и ty как раз были координаты смещения текстуры... короче это не нужно :))


Creative   (2006-11-30 15:19:00) [56]

И еще вопрос: в твоем последнем примере у тебя в процедуре DisplayMouseMove что происходит при нажатии Alt+левая мышь?


Creative   (2006-11-30 15:13:00) [57]

Скажи, у тебя в DisplayMouseMove X и Y - это координаты курсора?


Creative   (2006-11-30 12:46:00) [58]

Уляпаюсь по уши и еще попрошу! :-)

Только у меня чуть позже могут вопросы возникнуть, так что заглядывай, если не трудно.


ancara   (2006-11-30 12:41:00) [59]

Кушай, не обляпайся :))


Creative   (2006-11-30 12:03:00) [60]

Пример потрясающий. То, что мне нужно!!!


Страницы:   1 2 3 4 5

Наверх

Титульная страница Поиск, карта сайта Написать письмо