1. Регистрируешься в облачном хостинге.
2. Выбираешь тариф исходя из нужных объемов, нужной пропускной способности и прочего
3. Получаешь адреса ftp, базы и пароли
4. Profit!
Изучать там нечего абсолютно, все тоже, что и с обычным хостингом.
Имеется отрисовываемый ландшафт в 3д посредством OpenGL. Требуется по клику мышки определить координату X,Y,Z куда кликнули на этом ландшафте. Знаю, что можно при клике отрисовать этот ландшафт в задний буфер, считать значение глубины для пикселя под мышкой и через gluUnProject получить искомые координаты... Только слышал я, что этот glReadPixels как то тормозит хорошо, наверное, из за того что чтение видеопамяти выполняется намного дольше чем запись в нее. Есть ли какие то альтернативы? Это я к тому что этот glReadPixels придется вызывать каждый кадр для того чтобы определить какой юнит или предмет под мышкой стоит например, ну или при выделении рамкой... Понятно, что в моих мелких проектах это вряд ли сильно повлияет на производительность, но все таки....
Помимо отрисовки ландшафта в невидимый буффер и дальше определения по цвету есть честные геометрические методы.
Для перевода координат из экранных в видовые и обратно есть 2 функции gluProject и glUnproject. Внутри довольно сложные - обратные матрицы и все дела, но пользоваться довольно просто, если понять как.
Вторая часть головоломки - формулы пересечения лучей и треугольников.
Можно честно сделать это в 3д, можно наоборот - проецировать точки мешей на экран, отсеивать повернутые попой треугольники(это можно сделать, определив по часовой или против заданы точки треугольников) и искать пересечение кординат мышки и треугольника. На самом деле формулы не очень даже и сложные, но в целом реализация может съесть некислое количество нервов.
Пример есть в моей конкурсной игре туточки http://igdc.ru/igdc_top.php?konkurs=48
там таким методом определяется клики по плиткам пола. Плитки могут быть любой формы, метод универсален.
2Mefistofel,
gluProject и gluUnproject требуют на входе значение глубины, которое в общем то неизвестно, если не нарисовать и не прочитать с буфера) Ну а насчет честных геометрических методов.... Как то неприкольно искать пересечения всех треугольников большого ландшафта с лучом... Если ландшафт плоский, то еще как то можно просто найти точку пересечения, а иначе треуглов дофига слишком, по производительности вдарит.... Да и проблему выбора обьектов это не решит(если под мышкой не ландшафт, а предмет на ландшафте).
Слышал, есть что то типа рендера в текстуру... Может из нее быстрее читаться будет?
Что касается глубины, тут все просто. Если функции перевода в 3д отдать в качестве глубины мышки 0 и 1, то тебе вернется 2 точки - 3д точка "на поверхности монитора" и 3д точка в глубине сцены. Если соединить их вместе, как раз и получится прямая, которая является лучом выбора мыши - с ней надо искать пересечения.
Если преобразовываешь обратно, то отдает тоже 3д точку, но в ней z координату смело можно отбросить обычно, а оставшиеся 2 точки - это x и y мышки, с инвертированным y.
Ну для предметов нужно искать пересечения с bound box'ами предметов, а не треугольниками ландшафта. Методы те же.
Что касается производительности - если решать в лоб, то конечно будет туго, но эти вещи уже долго и упорно оптимизируются. Самый простой метод - отображать точки только того куска ландшафта, который рисуется. Можно оптимизировать еще, проще всего - разбиениями.
Вообще не тешьте себя иллюзиями, геометрия - это основной способ. Правда в готовых движках под это есть инструменты. В том же юнити можно натянуть mesh collider на поверхность и по box collider у на каждый юнит и элементарно при кликах смотреть пересечения.
Че то я не так походу делаю.... Вроде работает все, только в 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 снизу вверх
И еще одна проблемка, к знатокам winApi.... пустое окно... ловлю сообщения WM_Char... Постоянно приходят только русские символы, на переключение раскладки не реагирует... Кроме этого еще и индикатор раскладки рядом с часами пропадает когда мое окно в фокусе, ну оно и понятно - окон ввода то нет. Но как только добавляю контрол EDIT к этому окну, так сразу и индикатор появляется и английские символы начинают приходить адекватно раскладке... И это несмотря на то, что этот эдит не имеет фокуса ввода. Но мне этот эдит как то ни к чему, как бы без него обойтись то?
Upd. Решено заменой
while PeekMessage(Msg, Window.Handle, 0, 0, PM_REMOVE) do
на
while PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do
Какая разница - непонятно, окно у меня всего одно. Ну еще консольное есть, но оно вроде как не в счет. Кто то может обьяснить эту темную магию?
Ты будешь ловить нажатия всех клавиш независимо от того, посылают их тебе или нет. То есть если окно неактивно, то все равно будут приходить сообщения.
Daemon,
врешь же) когда передаешь в PeekMessage хэндл конкретного окна, то происходит выборка сообщения для этого конкретного окна. когда передаешь 0, то происходит выборка сообщения для всех окон данного треда, в моем случае окно всего одно, так что никакой разницы не должно быть. если окно неактивно то никаких сообщений нажатых клавиш не приходит и не будет приходить, проверено.
KeeperKira написал:
Шум Перлинга можно было и на простую решетку накинуть. А душа просила разврата)
Не, это другое.
Шум Перлина изначально "одномерный" и его можно легко натянуть на прямую. Потом нормализовать результат так, чтобы к концам отрезка амплитуда была минимальна (для исключения пересечений с другими границами)
к тому же этот Перлинг, у меня уже где только можно и нельзя использовался.