|
Опубликовано 04.10.2014 16:04 (10 лет назад) # |
перспективное направление, чтобы его поизучать
1. Регистрируешься в облачном хостинге.
2. Выбираешь тариф исходя из нужных объемов, нужной пропускной способности и прочего
3. Получаешь адреса ftp, базы и пароли
4. Profit!
Изучать там нечего абсолютно, все тоже, что и с обычным хостингом. |
|
|
|
Опубликовано 14.01.2015 10:33 (10 лет назад) # |
Имеется отрисовываемый ландшафт в 3д посредством OpenGL. Требуется по клику мышки определить координату X,Y,Z куда кликнули на этом ландшафте. Знаю, что можно при клике отрисовать этот ландшафт в задний буфер, считать значение глубины для пикселя под мышкой и через gluUnProject получить искомые координаты... Только слышал я, что этот glReadPixels как то тормозит хорошо, наверное, из за того что чтение видеопамяти выполняется намного дольше чем запись в нее. Есть ли какие то альтернативы? Это я к тому что этот glReadPixels придется вызывать каждый кадр для того чтобы определить какой юнит или предмет под мышкой стоит например, ну или при выделении рамкой... Понятно, что в моих мелких проектах это вряд ли сильно повлияет на производительность, но все таки.... |
|
|
Инженер‑космогоник
|
Опубликовано 14.01.2015 10:57 (10 лет назад) # |
Помимо отрисовки ландшафта в невидимый буффер и дальше определения по цвету есть честные геометрические методы.
Для перевода координат из экранных в видовые и обратно есть 2 функции gluProject и glUnproject. Внутри довольно сложные - обратные матрицы и все дела, но пользоваться довольно просто, если понять как.
Вторая часть головоломки - формулы пересечения лучей и треугольников.
Можно честно сделать это в 3д, можно наоборот - проецировать точки мешей на экран, отсеивать повернутые попой треугольники(это можно сделать, определив по часовой или против заданы точки треугольников) и искать пересечение кординат мышки и треугольника. На самом деле формулы не очень даже и сложные, но в целом реализация может съесть некислое количество нервов.
Пример есть в моей конкурсной игре туточки http://igdc.ru/igdc_top.php?konkurs=48
там таким методом определяется клики по плиткам пола. Плитки могут быть любой формы, метод универсален.
редакция от Mefistofel, 14.01.2015 11:04 |
|
|
|
Опубликовано 14.01.2015 11:09 (10 лет назад) # |
2Mefistofel,
gluProject и gluUnproject требуют на входе значение глубины, которое в общем то неизвестно, если не нарисовать и не прочитать с буфера) Ну а насчет честных геометрических методов.... Как то неприкольно искать пересечения всех треугольников большого ландшафта с лучом... Если ландшафт плоский, то еще как то можно просто найти точку пересечения, а иначе треуглов дофига слишком, по производительности вдарит.... Да и проблему выбора обьектов это не решит(если под мышкой не ландшафт, а предмет на ландшафте).
Слышал, есть что то типа рендера в текстуру... Может из нее быстрее читаться будет? |
|
|
Инженер‑космогоник
|
Опубликовано 14.01.2015 11:28 (10 лет назад) # |
Что касается глубины, тут все просто. Если функции перевода в 3д отдать в качестве глубины мышки 0 и 1, то тебе вернется 2 точки - 3д точка "на поверхности монитора" и 3д точка в глубине сцены. Если соединить их вместе, как раз и получится прямая, которая является лучом выбора мыши - с ней надо искать пересечения.
Если преобразовываешь обратно, то отдает тоже 3д точку, но в ней z координату смело можно отбросить обычно, а оставшиеся 2 точки - это x и y мышки, с инвертированным y.
Ну для предметов нужно искать пересечения с bound box'ами предметов, а не треугольниками ландшафта. Методы те же.
Что касается производительности - если решать в лоб, то конечно будет туго, но эти вещи уже долго и упорно оптимизируются. Самый простой метод - отображать точки только того куска ландшафта, который рисуется. Можно оптимизировать еще, проще всего - разбиениями.
Вообще не тешьте себя иллюзиями, геометрия - это основной способ. Правда в готовых движках под это есть инструменты. В том же юнити можно натянуть mesh collider на поверхность и по box collider у на каждый юнит и элементарно при кликах смотреть пересечения.
|
|
|
|
Опубликовано 14.01.2015 11:32 (10 лет назад) # |
Печально че... придется тогда пока glReadPixels пользоваться.... |
|
|
|
Опубликовано 14.01.2015 16:42 (10 лет назад) # |
Че то я не так походу делаю.... Вроде работает все, только в 2 раза больше координаты возвращает.... т.е. кликаю туда где должно быть (10,10) - возвращает (20,20)..... Где (-10, -10) - соответственно (-20, -20)....
Прилагаю свой говнокод.... может кто подскажет?
// отрисовка карты
procedure T_Map.Draw;
var
i, j : integer;
begin
glBindTexture(GL_TEXTURE_2D, 1);
for i := 0 to Width - 1 do
for j := 0 to Height - 1 do
begin
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex3f(i - 0.5, j - 0.5, 0);
glTexCoord2f(1, 0);
glVertex3f(i + 0.5, j - 0.5, 0);
glTexCoord2f(1, 1);
glVertex3f(i + 0.5, j + 0.5, 0);
glTexCoord2f(0, 1);
glVertex3f(i - 0.5, j + 0.5, 0);
glEnd;
end;
end;
// отрисовка сцены
procedure T_Scene_Game.DrawScene;
begin
inherited DrawScene;
if not a then
glEnable(GL_TEXTURE_2D);
glColor3f(1, 1, 1);
glClearColor(0, 0, 0, 1);
glClearDepth(1.0);
glDepthRange(0, 1);
glDepthFunc(GL_LESS);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
gluPerspective(45, Window.Width / Window.Height, 0.01, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
gluLookAt(0, 0, 40, 0, 0, 0, 0, 1, 0);
Angle := Angle + 0.05;
//glRotatef(Angle, 0, 0, 1);
//glPolygonMode(GL_FRONT, GL_LINE);
Map.Draw;
Player.Draw;
if not a then
Window.SwapBuffers;
end;
procedure T_Scene_Game.OnMapMouseDown(AX, AY: integer; AButton: boolean);
var
xDepth : Single;
xProjection : array[0..150] of Double;
xModelView : array[0..150] of Double;
xViewPort : array[0..30] of Integer;
xX, xY, xZ : Double;
xDepth : Double;
begin
a := True; // вырубаем SwapBuffer
DrawScene; // рисуем сцену
a := False;
AY := Window.Width - AY; // координата Y снизу вверх
glReadPixels(AX, AY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, @xDepth); // находим глубину
glGetDoublev(GL_PROJECTION_MATRIX, @xProjection[0]); // заполняем матрицы проекции, модельвью и вьюпорта
glGetDoublev(GL_MODELVIEW_MATRIX, @xModelView[0]);
glGetIntegerv(GL_VIEWPORT, @xViewPort[0]);
gluUnProject(AX, AY, xDepth, @xModelView[0], @xProjection[0], @xViewPort[0], @xX, @xY, @xZ); // находим мировые координаты куда кликнули
if Player = nil then
Exit;
writeln(FloatToStr(XX) + ' ' + FloatToStr(XY));
Player.Physic.PosEnd[0] := xX; // передвигаем юнит на эту точку
Player.Physic.PosEnd[1] := xY;
// Player.Physic.PosEnd[2] := xX;
end;
P.S. Предложение администрации.... Может как то этот /code сделать поудобнее? а то как то нечитабельно... да и спойлеры добавить....
Upd. С ортографической проекцией все работает как часы.... А с перспективной как то странно....
Upd. Всем спасибо, разобрался) Забыл включить Depth_Test, в итоге в буфере глубины у меня у всех пикселов было 1.0.
редакция от MysticCoder, 14.01.2015 17:38 |
|
|
|
Опубликовано 21.01.2015 19:12 (10 лет назад) # |
И еще одна проблемка, к знатокам winApi.... пустое окно... ловлю сообщения WM_Char... Постоянно приходят только русские символы, на переключение раскладки не реагирует... Кроме этого еще и индикатор раскладки рядом с часами пропадает когда мое окно в фокусе, ну оно и понятно - окон ввода то нет. Но как только добавляю контрол EDIT к этому окну, так сразу и индикатор появляется и английские символы начинают приходить адекватно раскладке... И это несмотря на то, что этот эдит не имеет фокуса ввода. Но мне этот эдит как то ни к чему, как бы без него обойтись то?
Upd. Решено заменой
while PeekMessage(Msg, Window.Handle, 0, 0, PM_REMOVE) do
на
while PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do
Какая разница - непонятно, окно у меня всего одно. Ну еще консольное есть, но оно вроде как не в счет. Кто то может обьяснить эту темную магию?
редакция от MysticCoder, 21.01.2015 19:18 |
|
|
|
Опубликовано 22.01.2015 03:56 (10 лет назад) # |
Ты будешь ловить нажатия всех клавиш независимо от того, посылают их тебе или нет. То есть если окно неактивно, то все равно будут приходить сообщения. |
|
|
|
Опубликовано 22.01.2015 09:44 (10 лет назад) # |
Daemon,
врешь же) когда передаешь в PeekMessage хэндл конкретного окна, то происходит выборка сообщения для этого конкретного окна. когда передаешь 0, то происходит выборка сообщения для всех окон данного треда, в моем случае окно всего одно, так что никакой разницы не должно быть. если окно неактивно то никаких сообщений нажатых клавиш не приходит и не будет приходить, проверено. |
|
|
|
Опубликовано 18.02.2015 13:54 (10 лет назад) # |
Как вам генератор границ Биомов?
Кто узнал алгоритм?))
|
|
|
Копробарон
|
Опубликовано 18.02.2015 14:02 (10 лет назад) # |
Вороной? |
|
|
|
Опубликовано 18.02.2015 14:07 (10 лет назад) # |
А кто его НЕ узнал? :)
|
|
|
|
Опубликовано 18.02.2015 14:12 (10 лет назад) # |
Я не узнал! |
|
|
|
Опубликовано 18.02.2015 14:17 (10 лет назад) # |
Диаграмма Вороного с постобработкой.
(Характерные вытянутые сегменты у границы изображения) |
|
|
|
Опубликовано 18.02.2015 14:25 (10 лет назад) # |
ну да он самый) и пост обработка тоже есть. Меня не устраивали прямые лини которые получались при построении диаграммы.
|
|
|
|
Опубликовано 18.02.2015 14:31 (10 лет назад) # |
И ты каждую линию в сигмоиду превратил? :)
Надо что-нибудь по-разнообразнее. "Зашумить" фракталом или шумом Перлина. |
|
|
|
Опубликовано 18.02.2015 14:47 (10 лет назад) # |
Шум Перлинга можно было и на простую решетку накинуть. А душа просила разврата)
к тому же этот Перлинг, у меня уже где только можно и нельзя использовался.
редакция от KeeperKira, 18.02.2015 14:51 |
|
|
Инженер‑космогоник
|
Опубликовано 18.02.2015 14:56 (10 лет назад) # |
Перлина много не бывает. |
|
|
|
Опубликовано 18.02.2015 15:04 (10 лет назад) # |
KeeperKira написал:
Шум Перлинга можно было и на простую решетку накинуть. А душа просила разврата) Не, это другое.
Шум Перлина изначально "одномерный" и его можно легко натянуть на прямую. Потом нормализовать результат так, чтобы к концам отрезка амплитуда была минимальна (для исключения пересечений с другими границами)
к тому же этот Перлинг, у меня уже где только можно и нельзя использовался.
Mefistofel написал:
Перлина много не бывает.
:)
редакция от Shirson, 18.02.2015 15:04 |
|
|