![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Полусфера на поверхности сферы (OpenGL) [Delphi, Windows]
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]Пример потрясающий. То, что мне нужно!!!