![]() |
|
![]() ![]() ![]() |
|
nns2009 |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 174 Регистрация: 1.2.2009 Репутация: нет Всего: 1 |
Решил заняться разработкой 3d движка(на ActionScript 3.0(Язык разработки для Adobe flash)).
На удивление, с преобразованием координат из 3d в 2d проблем не возникло(проверял, создав простенькую функцию для рисования треугольника средствами ActionScript 3.0). Программа просто летала, но была проблема: нарисованные треугольники хаотично перекрывали друг друга! Тогда я решил заняться z-буфером(для определения более ближнего к камере объекта), и сразу возникла проблема: т. к. каждой точке, кроме цвета, надо поставить в соответсвие дополнительную характеристику "глубина", нельзя сразу нарисовать фигуру на экран, а нужно поначалу нарисовать фигуру в массив(screen[width][height]) размером с экран(элементы которого содержат по 2 характеристики(глубина и цвет)), при этом рисование должно производиться поточечно: если у данной точки треугольника глубина меньше, чем в соответсвующей точке массива(то есть треугольник ближе, чем самый близкий объект, нарисованный до этого), то заменить цвет точки в массиве на цвет треугольника. В конце концов нужно поточечно отобразить элементы массива. Я попробовал реализовать что-то подобное, но треугольники рисовались не совсем правильно и всего-лишь 6 треугольников жутко тормозили(а ведь в современных играх рисуются 1000000-ны треугольников без торможения, да и с текстурой!). Пусть
Подскажите реализацию этой функции или более эффективный метод(желательно на ActionScript или на C++). |
|||
|
||||
Pavia |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 6.12.2008 Репутация: 11 Всего: 12 |
nns2009,
По поводу 1 000 000 треугольников. Достигается это припомощи отсечения. Оптимизация, оптимизация и еще раз оптимизация. По мимо z - буфера есть и другие методы. Возможно стоит обратить на них внимание. Правда они не такие хорошии как z-буфер. Звто можно будет использовать вывод 2d треугольника не проверяя каждый пиксель. Алгоритм художника, алгоритм витвей и границ и др. И еще привиди свой код. |
|||
|
||||
Чупакабро |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 220 Регистрация: 27.2.2007 Репутация: нет Всего: 4 |
Скорость рисования зависит не только от способа нахождения z-координаты пикселя, но и от того, как ты передаешь значения массива screen на экран...
Если вызываешь функцию рисования для каждого пикселя, то это очень тормозно. Ну и инетересно, как ты все-таки определяешь z-координату. Я делал как сумму z-координаты одной из трех вершин и произведений приращений координаты пикселя по осям x и y на частные производные z по этим осям. делал на Delphi, рисовалось довольно быстро, но я использовал функцию Win API setdibitstodevice --------------------
Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address 00459B8B in module 'Project1.exe'. Read of address 0000019C'. Process stopped. Use Step or Run to continue. |
|||
|
||||
nns2009 |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 174 Регистрация: 1.2.2009 Репутация: нет Всего: 1 |
Проблема в том, что даже если я не вывожу ничего на экран, а просто вычисляю цвета всех точек экрана, программа жутко тормозит(тормозит ползунок, который я кручу для изменения позиции камеры). Я определяю z-координату, не для конкретной точки, а при полной отрисовке треугольника, для каждой точки входящей в его состав: вычисляю z-координату и если она меньше, чем значение screen[x][y].depth, то screen[x][y].color = цветТреугольника. В ближайшее время выложу код. Честно говоря, я ничего не понял. Можешь привести соответсвующий код(только желательно не на Delphi, т.к. он очень сильно отличается от всех остальных языков программирования и будет сложно разобраться). |
|||
|
||||
Чупакабро |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 220 Регистрация: 27.2.2007 Репутация: нет Всего: 4 |
Перевел, как мог на С, заранне извиняюсь за ошибки, неграмотный я... p1, p2, p3 - вершины треугольника (экранные координаты) triangle.p1, triangle.p2, triangle.p3 - вершины треугольника в мировых координатах i,j координаты текущего пикселя функция intriangle проверяет принадлежность пикселя (i,j) треугльнику (p1,p2,p3) clientwidth - ширина экрана функция getroots решает систему уравнений: triangle.p2.z=(p2.x-p1.x)*dzdx+(p2.y-p1.y)*dzdy+triangle.p1.z triangle.p3.z=(p3.x-p1.x)*dzdx+(p3.y-p1.y)*dzdy+triangle.p1.z -находим dzdx - скорость приращения z по х и dzdy - скорость приращения z по y В общем, смысл такой: при увеличении координаты Х пикселя треугольника на 1, его координата Z изменяется на некоторую постоянную величину, то же самое при изменении координаты У. И если известна координата Z хотя бы одного пикселя треугольника, то для любого другого пикселя мы можем ее посчитать, прибавив к этому начальному значению два приращения: от изменения координаты Х и от изменения координаты У. --------------------
Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address 00459B8B in module 'Project1.exe'. Read of address 0000019C'. Process stopped. Use Step or Run to continue. |
|||
|
||||
nns2009 |
|
||||
Бывалый ![]() Профиль Группа: Участник Сообщений: 174 Регистрация: 1.2.2009 Репутация: нет Всего: 1 |
В общем код понятен, только есть несколько вопросов:
1) Функция getroots() ничего не возвращает. Насколько я понял она вычисляет dzdx и dzdy? 2) Все координаты, к моменту когда мы доходим до функции draw2DTriangleToArray() уже переведены в экранные(с z-координатой, обозначающей дальность точки до экрана), мне кажется лучше было бы, что бы функция getroots() решала такую систему:
Тогда мы сразу бы получили приращения z-координаты(глубины) в экранных координатах. И тогда в цикле:
|
||||
|
|||||
Чупакабро |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 220 Регистрация: 27.2.2007 Репутация: нет Всего: 4 |
Ага Да, совершенно верно. Можно и так. Просто в моей программе нужно было знать координаты пикселя в мировых координатах для расчета освещения. По поводу тормозов. Я не знаком с ActionScript, но мне кажется там плохо сделана работа с массивами, отсюда и тормоза. А может я ошибаюсь --------------------
Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address 00459B8B in module 'Project1.exe'. Read of address 0000019C'. Process stopped. Use Step or Run to continue. |
|||
|
||||
nns2009 |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 174 Регистрация: 1.2.2009 Репутация: нет Всего: 1 |
А как выглядит изнутри intriangle() ?
Сам язык медленнее, чем C++ и т.п., так как исполняется не непосредственно Windows, а средой выполнения Flash. |
|||
|
||||
nns2009 |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 174 Регистрация: 1.2.2009 Репутация: нет Всего: 1 |
После некоторых раздумий, я решил, что будет лучше отказаться от z-буфера и использовать алгоритм художника(поначалу рисовать дальние объекты, а потом, поверх них - ближние), не только из-за производительности, но и из-за того, что при использовании z-буфера, я рисую треугольник не сглаживая и он получается не очень красивый.
Но тогда возникает новая проблема: как произвести сортировку треугольников по удалённости? Предположим у нас есть массив triangles в котором 100 элементов. Если поначалу пройтись по нему с тем, чтобы найти самый дальний элемент, затем заново пройтись в поисках элемента поближе, то получится очень долго. Как его отсортировать? |
|||
|
||||
Чупакабро |
|
||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 220 Регистрация: 27.2.2007 Репутация: нет Всего: 4 |
для сортировки треугольников создаешь массив структур из двух полей:
- расстояние от экрана до треугольника - номер треугольника в массиве triangles сортируешь массив и все! перебираешь его с конца, в текущем элементе записан номер треугольника, который надо вывести. Насчет intriangle - там используется сравнение площадей (см картинку), при нажождении точки внутри треугольника сумма площадей треугольников, образуемых точкой и вершинами треугольника равна площади исходноготреугольника
Это сообщение отредактировал(а) Чупакабро - 7.3.2010, 22:44 Присоединённый файл ( Кол-во скачиваний: 14 ) ![]() --------------------
Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address 00459B8B in module 'Project1.exe'. Read of address 0000019C'. Process stopped. Use Step or Run to continue. |
||||
|
|||||
nns2009 |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 174 Регистрация: 1.2.2009 Репутация: нет Всего: 1 |
Я попробовал реализовать что-то подобное, но получилось не очень хорошо: получается неправильная разрисовка, что в принципе можно было бы исправить, если бы вся конструкция не тормозила из-за 6 треугольников! Я пожалуй забуду про z-буфер(его на ассемблере наверное надо программировать чтобы он нормальную скорость выдавал!) и перейду к алгоритму художника.
|
|||
|
||||
nns2009 |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 174 Регистрация: 1.2.2009 Репутация: нет Всего: 1 |
Реализовал алгоритм художника. Разработка движка постепенно продвигается. Всем спасибо.
|
|||
|
||||
![]() ![]() ![]() |
Правила форума "Алгоритмы" | |
|
Форум "Алгоритмы" предназначен для обсуждения вопросов, связанных только с алгоритмами и структурами данных, без привязки к конкретному языку программирования и/или программному продукту.
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Алгоритмы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |