| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Программирование игр, графики и искусственного интеллекта > Свой 3D формат |
| Автор: ZC1989 1.11.2006, 00:34 |
| Вот такая вот делема: начал было писать свой формат... для начала решил что надо бы хотя бы из OBJ сделать свой файл... написал программку експорта, там я брал структуру ОБДЖА и перегонял в свою... в итоге у меня не было разделений по объектам (как в ОБДЖЕ) и вся эта куча треугольников была обном объектом... на тестах с кубиком всё было пучком, но когда я попытался перегнать фигуру посложнее, состоящую из 200 треугольников, при загрузке его в сцену всё висло... я тут думаю, может надо соблюдать структуру того же ОБДЖА? тобишь создавать при чтении столько боъектов сколько в первоисточнике и поочереди их рендерить? подскажите, я уже запутался во всём этом... ЗЫ: DirectX 9, C++ |
| Автор: Rickert 1.11.2006, 13:52 |
| Структуру соблюдать не нужно - это точно. Ты просто криво экспортёр написал. Думай, ищи ошибку. |
| Автор: arilou 1.11.2006, 14:29 |
| ZC1989, а .X формат не устраивает? |
| Автор: ZC1989 3.11.2006, 10:25 |
| arilou, я стараюсь от этих "шаблонов" как Х файл уйти, да и попробовать надо, не помешает... |
| Автор: arilou 3.11.2006, 11:18 |
| ZC1989, я к чему спрашивал: практически всегда полезно не просто задавать вопрос, а описывать всю ситуацию. Тебе не хватает ф-ти .X файла? Или ты делаешь cross-platform формат? Или что-то еще...? Не помешало бы привести код, и картинку более сложного объекта для начала. |
| Автор: ZC1989 4.11.2006, 13:16 |
| я решил для начала тупо загружать примитивы ( что бы понять что где/как лифт вызывается) и во внешнем файле описал объект (все треугольники для рендеринга, потом в максе нарисовал куб и перевёл его в тот формат под который написал читалку, он рендерился нормально, когда же я там же нарисовал сферу и конус, и то же их перевёл в "свой" формат, при начале рендеринга моего творения всё взвисло... вот я и спрашиваю "возможная причина этого?" формат не кросс-платформенный... просто попытка своё создать... и библиотеки к нему |
| Автор: arilou 4.11.2006, 14:15 |
| ZC1989, так трудно сказать. Ты определил, в каком именно месте происходит зависание? Отладчиком прошелся? |
| Автор: Rickert 5.11.2006, 07:43 |
| ZC1989, возможно где-то не читаешь переменную, которая после является членом цикла, в результате чего - бесконечный цикл. |
| Автор: Bitter 10.11.2006, 00:20 |
| Если ты рисуешь в 3DMax, то лучше всего использовать формат ASE. Это очень удобный, на мой взляд, формат. Я написал конвектор без проблем. Потом создал 3D движок, который загружает уже файлы нужного мне формата и теперь клепаю 3D проги тока-так. Правда, есть и там проблемка: файлы ASE неправильно хранят нормали объектов. Точнее, если ты создашь, скажем, шарик, а потом его экспортируешь а ASE, то всё вроде нормально. Но стОит этот шарик повернуть... В общем нормали приходится расчитывать самому. И еще описание вершин в ASE приводится ПРОТИВ часовой стрелки. Если хочешь, могу тебе выслать эту прогу и движок (406 Кб). Но, дело в том, что сам конвектор около 2000 строк текста и движок - около 700. А как извесно нет ничего хуже, чем разбираться в чужих прогах. Я, конечно, напишу тебе ReadMe, но лучше, писать самому. |
| Автор: Bitter 10.11.2006, 00:47 |
| Да, забыл предупредить. Всё это написано на Delphi 7, а движок использует Direct3D |
| Автор: ZC1989 10.11.2006, 13:58 |
| Bitter, если не трудно пришли пожалуйста... мыло [email protected], в коде попробую разобраться... |
| Автор: $tatic 10.11.2006, 17:12 |
Правильно, т.к. отсекаются невидимые полигоны дефолтно с вершинами по часовой стрелке. |
| Автор: Bitter 10.11.2006, 18:30 | ||
:-) я просто всегда думал, что наоборот |
| Автор: ZC1989 29.12.2006, 16:30 |
| оживляю топик, что бы поинтересоваться в правильности моих мыслей... я по примеру Bitter'a начил писать формат, но возник вопрос такой: у меня объект состоит из нескольких подъобъектов, а вершинный буфер для кадого объекта свой (в классе инициализируется) так вот какое колличество мне памяти выделять, просто посмотреть максимальное их колличество в каждом подобъекте и выбрать большее? или надо как-то по другому... |
| Автор: arilou 29.12.2006, 16:45 |
| ZC1989, загляни в формат меша для Огра. Очень, знаешь ли, занимательно-поучительно |
| Автор: ZC1989 29.12.2006, 17:06 |
| arilou, у меня повремянка, и качать 18 (или сколько там) мегов, мне не оч удобно... да и вопрос помоему не такой уж сложный |
| Автор: arilou 29.12.2006, 17:10 |
| Чисто для интереса - Mesh Serializer из Огра: |
| Автор: ZC1989 30.12.2006, 10:34 |
| Rickert, да объект состоит из нескольких объектов. а буфер на это всё один, но какой смысл суммироваться все вершины? ведь каждый подъобъект я отрисовываю поочереди, можно ли в таком случае, если в первом объекте 100 вершин, а во втором 200 завести буфер на 200? при отрисовке первого объекта я заполню его только ста вершинами и их отрисую, а потом в этот буфер скину 200 вершин... или это не правельно? |
| Автор: Bitter 30.12.2006, 16:53 |
| Нет, не правильно. Будет всё сильно тормозить, так как для заполнения буфера на каждом кадре, его нужно запирать, а это "тормознутая" операция. Надо делать так, как сказал Rickert, т.е. подготовить буфер сразу для всех вершин. А потом рисовать какую-то его часть. |
| Автор: ZC1989 30.12.2006, 17:00 |
| Bitter, но я расчитываю производить некоторые действия с вершинами (перемещения к римеру) для этого же то же надо открывать и закрывать буфер Кстати, в твоеё редмишке (из архива) было написано, что нормаль полученные из ASE файла не правельны, как тогда можно для треугольника их раситать? |
| Автор: Rickert 30.12.2006, 21:05 |
| ZC1989, во-первых - никто не делает объект состоящий из нескольких объектов. Как ты анимацию собираешься организовывать? Во-вторых - такты процессора намного важнее количества использованной памяти |
| Автор: DragonFire 31.12.2006, 00:24 | ||
http://forum.vingrad.ru/index.php?showtopic=126238&view=findpost&p=953774 |
| Автор: ZC1989 31.12.2006, 00:37 |
| DragonFire, спасибо! то что надо! С наступающим ВСЕХ!!! |
| Автор: Bitter 31.12.2006, 00:52 | ||
Для этого используют матрицы трансформаций. Хотя с помощью матриц, не сделаешь, например анимацию воды или морфинг. В этом недостаток буфера вершин и соответственно всего DirectX. Хотя может я просто не знаю как это делать матрицами. |
| Автор: ZC1989 31.12.2006, 01:13 |
| Bitter, я не хочу матрицы использовать дирекстовые... да и мой метод, когда на каждый кадр я открываю и закрываю буфер не тормозит, фпс на месте остаётся... подъобъектов на 1500 полигонов Добавлено @ 01:21 правда они без текстур, да и не все параметры заданы... но мне кажется для игры достаточно, ведь яж не только изменять размеры собираюсь Rickert, а что с анимацией?! я не зарекаюсь, но думаю о скелетной анимации, а мне парень, рисующий 3Д описал эту анимацию как привязку некоторых объектов к "ключам" неким точкам (на типе внетренней системы координат) |
| Автор: Bitter 31.12.2006, 14:31 |
| ZC1989, 1500 полигонов это же понт! Одна только более менее ровная сфера уже 1000 полигонов. А если планету делать, то еще и полупрозрачная атмосфера таких же размеров. Если использовать матрицы, 10-15 тысяч с текстурами, полупрозрачностью и прочей ерундой отлично работает. Rickert, как это никто не делает? А как же по твоему делается разрушение объекта? Например, разрушение стены из кирпечей или отпадание колес автомобиля? Именно так. Автомобиль - массив из подобъектов (колеса, двери и т.д.). Каждый подобъект содержит матрицу трансформаций. Чтобы сделать анимацию колеса, например, изменяешь его матрицу одной строчкой в программе и всё! Я делал анимацию человекообразного робота именно матрицами. Он умел ходить как человек и падать, когда его убиваешь. |
| Автор: ZC1989 31.12.2006, 15:19 |
| Bitter, в прошлых попытка сделать draw'илку объекта у меня уже на 500 полигонов фпс падало в 2 раза, тем более для моей сцены я не думаю что отрисовка всех объектов разом привысит 3000 полигонов. я конечно попробую забивать все вершины в один буфер, но как тогда производить перемещение внутренней матрицы?! раньше я передавал в функцию вектор направления и точку центра, получал глобальные координаты, а сейчас как? |
| Автор: Bitter 31.12.2006, 19:04 |
| Напимер, ты нарисовал объект в Max'e с координатами 0,0,0. Импортировал его. В инициализации пишешь Matrix := IdentityMatrix; Это сброс матрицы. Чтобы переместить объект в пространстве пишешь: Matrix._41 := x; Matrix._42 := y; Matrix._43 := z; Перед рендерингом пишешь D3Device.SetTransform(D3DTS_WORLD, Matrix); А потом уже рендеришь функцией DrawPrimitive ... И всё. Объект отрисуется в координатах x,y,z Если нужно повернуть объект вокруг оси пишешь: SetRotateXMatrix(Matrix, Angle); // Поворот по оси Х Angle - угол в радианах Масштаб: SetScaleMatrix(Matrix, x, y, z) |
| Автор: ZC1989 1.1.2007, 17:42 | ||
| DragonFire, я по твоей статье сделал функцию получения нормалей, все расчёты правельны, но почему-то получается некая фигня... я прикрепил скреншот того что мне кажется странным... а вот кусочек кода где нормаль присываиваются к вершинам
так как источник света определён в другой части проги приводить его не буду |
| Автор: DragonFire 1.1.2007, 19:10 | ||
| ZC1989, Долго силился вникнуть в код но понятно только в общих чертах, т.к. сам пишу на Delphi (тут не особенно проблем) и OpenGL (а вот директа не совсем ясна). Я так понял ты сначало задаешь все вершины с нормалями в буфер, потом его отрисовываешь. По причине, описанной выше точно сказать не могу почему так, но есть идея одна. Возможно ты к двем треугольникам лежащим в одной плоскости строишь разные нормали. Одну как бы "вверх", другую "вниз". У меня была такая проблема. Все зависит от последовательности вершин, пихаемых в функцию. На всякий случай приведу свой код, который у меня работает верно:
Тут Normal это просто вектор, тоесть посути запись x,y,z:extended... |
| Автор: ZC1989 1.1.2007, 19:28 |
| DragonFire, так у меня то же вектор это 3 координты (xyz, ijk... как угодно) просто на именно этой грани такая запарка, но о последовательности я уверен что она зде правильно описана (против часово)... ладно, с другими гранями вроде нормально, возможно просто точку у одного увело вниз... буду искать сам... потом расскажу об успехах |
| Автор: DragonFire 1.1.2007, 20:09 |
| А как в директе источник света задается? Может дело в нем? |
| Автор: ZC1989 1.1.2007, 20:27 | ||
| DragonFire, нет, сет не даёт ошибки 100%, это что-то с нормалью или моделью... но всё равно, вот мой свет
|
| Автор: ZC1989 1.1.2007, 21:37 |
| DragonFire, извини за флуд! я прав был, это не ошибки расчётов, просто парень рисовавшый объект смустил точки! с нормалями всё О.К. но всёж спасибо! |
| Автор: DragonFire 2.1.2007, 01:48 |
| Ура ура))) |
| Автор: ZC1989 3.1.2007, 21:23 |
| Решил последовать совету и перевёл все точки в один буфер, потом, разобрался с матрицами, теперь могу делать в пяти строчках все, что мне нужно было, оч удобно! На радостях решил загрузить один файлик, там описан «микроб», состоит он из 22000 полигонов, собс-но это где-то 66000 точек. Перевёл в свой формат, всё пучком, когда загружается сцена, получается такая фишка, что нельзя разом увидеть этот «микроб», его попросту нет на экране, но если повертеть камерой так что в кадре не весь он будет, а половина, то он начинает отрисовываться… от чего такая кривизна, от того что это один объект целиковый или я что-то нафлудил? ЗЫ: грубо говоря «микроб» это сфера с торчащими из неё ножками, оч похожа на мину глубоководную со времён ВМВ. |
| Автор: ZC1989 3.1.2007, 22:08 |
| Bitter, а мне тут вспомнился такой метод работы с нормалями, когда не к плоскости нормаль одна, в следствии чего все 3 точки плоскости имеют одну и ту же нрмаль, а когда для этих трёх точек нормали разные, что даёт более сглаженные границы соединения швов между траинглами... это я вот к чему, ты писал что нормали в ASE описанные не верны, но может этот как раз тот случай когда для каждой точки нормали раные? тем более, если не ошибаюсь, ты говорил нормали "испортятся" если сферу повернуть, но, помоему, они и должны будут поменяться! есть в этом бредовом рассуждении хоть капля здравого смысла? |
| Автор: Bitter 4.1.2007, 03:34 |
По моему в доке, который я тебе присылал, есть описание подобъекта, так вот там как раз каждая точка имеет свою нормаль. Если надо, выложу код для расчета сглаженных нормалей по заданному углу (например, сглаживать, если угол <50 градусов). Но он на Delphi (хотя можно попробовать в словесной форме написать код). |
| Автор: ZC1989 4.1.2007, 11:17 |
| Bitter, я мутно представляю как для точек расчитывать, так что буду раб! и в словесной форме, как-то лучше получается, хоть сразу знаю что делать надо... + у меня проблемы какие-то при экспорте в ASE, объект получается инвертирован слева-на-право, и поднят на 90 градусов |
| Автор: DragonFire 4.1.2007, 12:48 | ||
Выложи плиз)) |
| Автор: Nicholas_S 4.1.2007, 14:28 | ||
| ZC1989, для справки: когда каждая грань объекта имеет 1 нормаль, обычно происходит плоская закраска (flat); гладкие закраски (гуро, фонга, последний точнее и заметно лучше выглядит) происходят из расчета того, что каждая точка грани имеет свою нормаль. При модификации объекта (повороте, непропорциональном сжатии/растяжении) массив нормалей должен соответственно быть модифицирован. Можно пересчитывать нормали при трансформации каждый раз. Нахождение нормали к грани можно получить следующим образом:
Получить нормаль к каждой из вершин грани можно, используя нормали к смежным граням, вычисленные по алгоритму, приведенному выше. |
| Автор: ZC1989 4.1.2007, 16:33 |
| Nicholas_S, впринцыпе оно и есть, я нашёл у себя статью где это опысывалось... если кому надо то суть такая: надо суммировать нормали всех плоскостей содержащих эту точку, потом нормализовать все вектора и вуаля, список нормалей индивидуальных для кажой точки! а изначально, перед началом суммирования, надо все нормальные вектора прописать нулевыми |
| Автор: Bitter 4.1.2007, 23:30 | ||||
ZC1989, именно так! Вот то, что обещал (словесное описание в качестве коментариев):
вообще-то реализация зависит от формы организации данных. В данном случае имеется массив граней, каждый элемент которого хранит три вершины, три нормали и три текстурные координаты.
а если камеру разместить с другой стороны, то получится нормальным. или я может чего-то не понял? |
| Автор: ZC1989 5.1.2007, 00:01 | ||
Bitter,
ты не понял... представь, что будет с объектом если все координаты по Х умножить на -1, получится зеркальное отражение Добавлено @ 00:04 там ещё объект поворачивался на 90 градусов по Y оси, но я нашёл простое решение, менять у точек координаты Y и Z, и менять местами 1 и третью вершыны, что, как мне кажется геморойно... |
| Автор: Bitter 5.1.2007, 01:35 | ||
Да, действительно так и есть. Я про это совсем забыл. У меня в движке написано Read(FileBuf,z); Vertices.X:=-z.X; Vertices.Y:=z.Y; Vertices.Z:=z.Z; Так и напиши. А про Y и Z есть такая мысль: В 3DMaxe ось Z направлена вверх, в то время как в DirectX - в глубину экрана. Просто при иницализации камеры вектор "Up" нужно задавать как (0,0,1). Попробуй по играться с этим вектором, я думаю дело в этом. |
| Автор: ZC1989 5.1.2007, 02:51 |
| Bitter, ну так как всё у меня с матрицей 0,1,0 я наверное останусь при своём, а именно оси менять буду и точки местами, чтоб полигоны не обращались в другую сторону... а про другой вопрос мой наверное забыли, что за фишка была при отрисовке буфера с колличеством точек 66000? это просто ограничение функции DrawPrimitiv или в чём-то другом ошибка? (рисую я их за раз) Добавлено @ 02:53 Bitter, ты извини, я твой код не могу щас мотреть, у меня вылетел Делфи и не ставится больше, винда парит... так что максимум чем я могу пользоваться это твоей РедМи'шкой... |
| Автор: Bitter 5.1.2007, 17:00 | ||||
Ты наверное не понял. я имел ввиду, что у тебя камера неправильно ориентирована. Другими словами ты лежишь на полу и пытаешься прикрепить люсту к стене. А нужно просто встать на ноги. Можешь попробовать другой подход: рисовать в 3DMaxe заведомо под углом -90 градусов. Таким образом, чтобы верх объекта совпадал с осью Y. И не надо менять оси и вершины это же как в анекдоте:
|
| Автор: ZC1989 5.1.2007, 17:08 | ||
| Bitter, ладно, я попробую матрицу камеры повернуть.. пасиб... а что с отрисовкой?
|
| Автор: Bitter 5.1.2007, 19:10 |
| ZC1989, а какой у тебя комп? |
| Автор: ZC1989 5.1.2007, 21:14 |
| Bitter, не спуер уже по мощам... 1.7Гц, 64 видео, 256 озу |
| Автор: Bitter 5.1.2007, 23:17 |
| Может не хватает видео памяти? Буфер-то именно туда записывает инфу... Добавлено @ 23:30 попробуй уменьшить кол-во полигонов и посмотри. если начнет отрисовываться, значит видухи не хватает... |
| Автор: ZC1989 6.1.2007, 02:13 |
| Bitter, если объекты меньше размером (кол-вом точек) то они рисуются... я думаю, а если этот объект разбить на несколько подобъектов, будет возможность отрисовать его? |
| Автор: Bitter 6.1.2007, 17:21 |
| Ну раз обекты по-менье рисуются, этот нет, значит дело в видео памяти. Попробуй рисовать по частям или попробуй разместить буфер в системной памяти: D3Device.CreateVertexBuffer((BufLength) * SizeOf(TBufferVertex), 0,D3DVERTEX, D3DPOOL_SYSTEMMEM, 3DBuffer); |
| Автор: DragonFire 7.1.2007, 08:28 |
| У меня два вопроса по теме: 1) Что быстрее будет работать: Просчитать все нормли к каждой точке заранее и записать в память, или пересчитывать их на каждом шаге. Размеры объекта до 20к точек? 2) Как на все это наложить текстуру по-нормальному? |
| Автор: Bitter 7.1.2007, 15:34 |
| 1) DragonFire, конечно расчитать один раз! ты что! Это же довольно долго даже один раз! 2) Если импортируешь из ASE, то там текстурные координаты указаны. Из файла и загружай |
| Автор: ZC1989 7.1.2007, 19:15 |
| Bitter, слушай, а вот ещё маленький вопросик относительно координат в ASE, когда мы поменяем знак у Z просчёт нормали к треугольнику будет не правельный да и рисоваться он уже не будет, т.к. вершыны будут счиататься в другую сторону... нужно ли местами менять первую и третью вершины? |
| Автор: Bitter 7.1.2007, 19:53 |
| ZC1989, а для чего ты их вообще меняешь? |
| Автор: ZC1989 7.1.2007, 22:34 |
| Bitter, ну если оставить всё как было то объекть рисуется не правильно! порядок вершин в обратную сторону получается... если не менять Z координату, то объект зеркальный... по любому надо что-то делать для нормальной последовательност |
| Автор: Bitter 8.1.2007, 01:26 |
| Так он же у тебя по Х зеркальный был... Или уже и по Z? |
| Автор: arilou 13.1.2007, 00:24 | ||||
Добавлено @ 00:34 ЗЫ. Разделил тему |