[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 3 из 4
  • «
  • 1
  • 2
  • 3
  • 4
  • »
Форум Panda3D - по русски » Panda3D » Для начинающих » Tilemap rendering (генерация поверхности на основе набора тайлов)
Tilemap rendering
soosДата: Среда, 22.06.2011, 15:39 | Сообщение # 31
Майор
Группа: Пользователи
Сообщений: 82
Награды: 1
Репутация: 0
Статус: Offline
Quote (ninth)
Кста, как вариант, ты можешь при получении данных формировать временный egg файл и грузить его как обычную модель. Это будет несколько проще чем мусолить внутреннюю структуру в рантайме, т.к. формат egg достаточно подробно описан и в принципе не сложен.

Через одно место конечно, но попробовать стоит.

Quote (ninth)
А ты его что каждый кадр обновляешь? О_о

Нет.

Code

node = GeomNode('gnode')
for x in xrange(0,100):
  for z in xrange(0,100):
   gvd = GeomVertexData('name', GeomVertexFormat.getV3t2(), Geom.UHStatic)
   vertex = GeomVertexWriter(gvd, 'vertex')
   texcoord = GeomVertexWriter(gvd, 'texcoord')
   vertex.addData3f(x, 0, z)
   texcoord.addData2f(0, 0)
   vertex.addData3f(x, 0, z+1)
   texcoord.addData2f(0, 1)
   vertex.addData3f(x+1, 0, z+1)
   texcoord.addData2f(1, 1)
   vertex.addData3f(x+1, 0, z)
   texcoord.addData2f(1, 0)
   prim = GeomTriangles(Geom.UHStatic)
   prim.addVertices(0, 2, 1)
   prim.addVertices(0, 3, 2)
   geom = Geom(gvd)
   geom.addPrimitive(prim)
   node.addGeom(geom)
terrain = render.attachNewNode(node)
terrain.setRenderModeWireframe()
run()

Вот это рендерится на 10-12 fps

Quote (ninth)
здесь пример удаления текстуры с полигона

Гляну, попробую добавить текстуру.

Quote (serg-kkz)
полигоны по отдельности рендерятся дольше, чем если они относяться к одному обьекту

Как это? Полигоны можно рендерить по отдельности?
 
ninthДата: Среда, 22.06.2011, 16:12 | Сообщение # 32
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
Добавь перед run()
terrain.flattenMedium() или terrain.flattenStrong()

Оптимизируется довольно долго перед запуском.

До оптимизации:

1 total nodes (including 0 instances); 0 LODNodes.
0 transforms; 100% of nodes have some render attribute.
10000 Geoms, with 10000 GeomVertexDatas and 1 GeomVertexFormats, appear on 1 Geo
mNodes.
40000 vertices, 0 normals, 0 colors, 40000 texture coordinates.
GeomVertexData arrays occupy 782K memory.
GeomPrimitive arrays occupy 118K memory.
9999 GeomPrimitive arrays are redundant, wasting 118K.
20000 triangles:
0 of these are on 0 tristrips.
20000 of these are independent triangles.
0 textures, estimated minimum 0K texture memory required.

После:

1 total nodes (including 0 instances); 0 LODNodes.
0 transforms; 0% of nodes have some render attribute.
1 Geoms, with 1 GeomVertexDatas and 1 GeomVertexFormats, appear on 1 GeomNodes.
40000 vertices, 0 normals, 0 colors, 40000 texture coordinates.
GeomVertexData arrays occupy 782K memory.
GeomPrimitive arrays occupy 118K memory.
20000 triangles:
0 of these are on 0 tristrips.
20000 of these are independent triangles.
0 textures, estimated minimum 0K texture memory required.

Почувствуй разницу ) 10000 Geoms и 1 Geoms
Зато разница в FPS видна невооружённым глазом ) И причина тоже )
 
serg-kkzДата: Среда, 22.06.2011, 16:33 | Сообщение # 33
Генерал-полковник
Группа: Модераторы
Сообщений: 803
Награды: 3
Репутация: 18
Статус: Offline
Quote (soos)
Как это? Полигоны можно рендерить по отдельности?


Я другое имел ввиду.

ninth уже ответил
Quote (ninth)
Почувствуй разницу ) 10000 Geoms и 1 Geoms


ООП  -  
 
soosДата: Среда, 22.06.2011, 16:55 | Сообщение # 34
Майор
Группа: Пользователи
Сообщений: 82
Награды: 1
Репутация: 0
Статус: Offline
Понятное дело, что flatten...() объединит все геомы, но суть не в том.
Сейчас для меня главный вопрос в том, как повесить на отдельный полигон текстуру? Устал гуглить уже, но ничего не нашёл. :(
Модель в egg файле - это набор вершин и полигонов, причём у каждого полигона есть текстура. Мне не понятно как это выглядит с точки зрения структур панды, потому что (как я понял) панда цепляет текстуру только к NodePath.
 
serg-kkzДата: Среда, 22.06.2011, 17:05 | Сообщение # 35
Генерал-полковник
Группа: Модераторы
Сообщений: 803
Награды: 3
Репутация: 18
Статус: Offline
NodePath это просто сылка, через которую панда цепляет текстурку на обьект на который она ссылается, а как цеплять её для панды описано в egg файле в соотвествующих тегах. Попробуй в примере multitexture

Code
    <Polygon> {
          <TRef> { 2.png }
          <MRef> { Material }
          <Normal> {0.000000 -1.000000 0.000000}
          <VertexRef> { 0 1 2 3 <Ref> { Plane }}
        }
        <Polygon> {
          <TRef> { 3.png }
          <MRef> { Material }
          <Normal> {0.000000 -1.000000 0.000000}
          <VertexRef> { 8 9 10 11 <Ref> { Plane }}


В строках <VertexRef> {<Ref> { Plane }}
поменять номера вертексов например: 8 9 10 11 на 1 2 3 4 а, 1 2 3 4 на 8 9 10 11. Для наглядности.
Позже я попробую написать генирируемый egg.

Впрочем если заранее определиться с размером полигона и количеством квадратов например 25*25 то можно сделать типа полигон-слот при генирации обекта где в строках имена текстур можно ипользовать переменные имени нужного тайла.


ООП  -  

Сообщение отредактировал serg-kkz - Среда, 22.06.2011, 17:36
 
soosДата: Среда, 22.06.2011, 17:34 | Сообщение # 36
Майор
Группа: Пользователи
Сообщений: 82
Награды: 1
Репутация: 0
Статус: Offline
Генерировать egg чтобы потом его же парсить и генерировать из него модель - это какой то изврат по-моему. Правильнее найти способ генерировать модель без избыточности.
Я сделал в итоге генерацию и пришёл к тому с чего начал - сложный объект который упрощается flatten'ом :(
Должен быть способ генерить эту модель изначально правильно. Порыскаю ещё. Вся суть flatten'а лишь в том, что он все геомы и их ноды объединяет в один.

Code

================================= BEFORE ========
20004 total nodes (including 0 instances); 0 LODNodes.
1 transforms; 49% of nodes have some render attribute.
10000 Geoms, with 10000 GeomVertexDatas and 1 GeomVertexFormats, appear on 10000
  GeomNodes.
40000 vertices, 0 normals, 0 colors, 40000 texture coordinates.
GeomVertexData arrays occupy 782K memory.
GeomPrimitive arrays occupy 118K memory.
9999 GeomPrimitive arrays are redundant, wasting 118K.
20000 triangles:
   0 of these are on 0 tristrips.
   20000 of these are independent triangles.
3 textures, estimated minimum 12K texture memory required.
Code

================================= AFTER =========
5 total nodes (including 0 instances); 0 LODNodes.
0 transforms; 20% of nodes have some render attribute.
3 Geoms, with 1 GeomVertexDatas and 1 GeomVertexFormats, appear on 1 GeomNodes.
40000 vertices, 0 normals, 0 colors, 40000 texture coordinates.
GeomVertexData arrays occupy 782K memory.
GeomPrimitive arrays occupy 118K memory.
20000 triangles:
   0 of these are on 0 tristrips.
   20000 of these are independent triangles.
3 textures, estimated minimum 12K texture memory required.
 
serg-kkzДата: Среда, 22.06.2011, 17:45 | Сообщение # 37
Генерал-полковник
Группа: Модераторы
Сообщений: 803
Награды: 3
Репутация: 18
Статус: Offline
Quote (soos)
Вся суть flatten'а лишь в том, что он все геомы и их ноды объединяет в один


soos ты вроде завел разговор про скорость рендера. Вот и вспомнили про flatten.

Quote (soos)
Генерировать egg чтобы потом его же парсить и генерировать из него модель - это какой то изврат по-моему


soos ты вроде завел разговор про генерацию меша на лету. Вот и вспомнили про egg.

Про избыточность скажу что она ничтожна, ибо все 3d игры страдают такой фигнёй "Loading"

А парсить не надо(то есть писать свой загрузчик) , надо сохранит и всё , а парсить будет загрузчик панды.


ООП  -  

Сообщение отредактировал serg-kkz - Среда, 22.06.2011, 17:49
 
ninthДата: Среда, 22.06.2011, 19:41 | Сообщение # 38
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
Вот тебе переделанный код чтобы писть в 1 геом. По текстурам чуть позже попробую глянуть.

Code

node = GeomNode('gnode')
gvd = GeomVertexData('name', GeomVertexFormat.getV3t2(), Geom.UHStatic)
geom = Geom(gvd)
prim = GeomTriangles(Geom.UHStatic)
vertex = GeomVertexWriter(gvd, 'vertex')
texcoord = GeomVertexWriter(gvd, 'texcoord')
i = 0
for x in xrange(0,100):
   for z in xrange(0,100):
    vertex.addData3f(x, 0, z)
    texcoord.addData2f(0, 0)
    vertex.addData3f(x, 0, z+1)
    texcoord.addData2f(0, 1)
    vertex.addData3f(x+1, 0, z+1)
    texcoord.addData2f(1, 1)
    vertex.addData3f(x+1, 0, z)
    texcoord.addData2f(1, 0)
    prim.addVertices(i*4, i*4 + 2, i*4 + 1)
    prim.addVertices(i*4, i*4 + 3, i*4 + 2)
    i += 1
prim.closePrimitive()
geom.addPrimitive(prim)
node.addGeom(geom)
terrain = render.attachNewNode(node)
terrain.setRenderModeWireframe()
terrain.analyze()
run()  
 
soosДата: Среда, 22.06.2011, 21:06 | Сообщение # 39
Майор
Группа: Пользователи
Сообщений: 82
Награды: 1
Репутация: 0
Статус: Offline
Quote (ninth)
Вот тебе переделанный код чтобы писть в 1 геом

Спасибо. Я тоже до подобного кода дошёл. А вот с текстурами совсем никак. Сейчас буду смотреть исходники на предмет того как Loader загружает egg файл и линкует полигоны с текстурами.
 
ninthДата: Четверг, 23.06.2011, 00:15 | Сообщение # 40
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
Ок. Вот тебе полный пример генерация + текстурирование + скрин )
К коду положи текстурки которые я выкладывал с egg файлом с теми же именами (1.png 2.png 3.png)
Если будешь копировать отсюда код - смотри - местный bb code уже пробелов навтыкал, например 'index' превратил в 'in dex' так что перепроверь.
Code

from pandac.PandaModules import *
loadPrcFileData("editor-startup", "show-frame-rate-meter #t")
import direct.directbase.DirectStart
from random import randint

node = GeomNode('gnode')
geoms = []
for i in xrange(3):
       gvd = GeomVertexData('name', GeomVertexFormat.getV3t2(), Geom.UHStatic)
       geom = Geom(gvd)
       prim = GeomTriangles(Geom.UHStatic)
       vertex = GeomVertexWriter(gvd, 'vertex')
       texcoord = GeomVertexWriter(gvd, 'texcoord')
       tex = loader.loadTexture('%i.png' % (i+1))
       tex.setMagfilter(Texture.FTLinearMipmapLinear)
       tex.setMinfilter(Texture.FTLinearMipmapLinear)
       geoms.append({'geo m': geom,
                     'prim':prim,
                     'vertex':vertex,
                     'texcoord':texcoord,
                     ' in dex':0,
                     'gvd':gvd,
                     'texture':tex})

for x in xrange(0,100):
       for z in xrange(0,100):
           t_img = randint(0,2)
           i = geoms[t_img]['index']
           geoms[t_img]['vertex'].addData3f(x, 0, z)
           geoms[t_img]['texcoord'].addData2f(0, 0)
           geoms[t_img]['vertex'].addData3f(x, 0, z+1)
           geoms[t_img]['texcoord'].addData2f(0, 1)
           geoms[t_img]['vertex'].addData3f(x+1, 0, z+1)
           geoms[t_img]['texcoord'].addData2f(1, 1)
           geoms[t_img]['vertex'].addData3f(x+1, 0, z)
           geoms[t_img]['texcoord'].addData2f(1, 0)
           geoms[t_img]['prim'].addVertices(i*4, i*4 + 2, i*4 + 1)
           geoms[t_img]['prim'].addVertices(i*4, i*4 + 3, i*4 + 2)
           geoms[t_img]['index'] += 1

for i in xrange(3):
       geoms[i]['prim'].closePrimitive()
       geoms[i]['geom'].addPrimitive(geoms[i]['prim'])
       node.addGeom(geoms[i]['geom'])
       node.setGeomState(i, node.getGeomState(i).addAttrib(TextureAttrib.make(geoms[i]['texture'])))

terrain = render.attachNewNode(node)
#terrain.setRenderModeWireframe()
terrain.analyze()

run()    


Прикрепления: 4725106.jpg (244.7 Kb)
 
soosДата: Четверг, 23.06.2011, 10:56 | Сообщение # 41
Майор
Группа: Пользователи
Сообщений: 82
Награды: 1
Репутация: 0
Статус: Offline
Quote (ninth)
Вот тебе полный пример генерация + текстурирование + скрин )

Большое человеческое спасибо! Можно двигаться дальше. Постараюсь прогресс в разработке освещать (в том или ином виде)
 
serg-kkzДата: Воскресенье, 26.06.2011, 13:59 | Сообщение # 42
Генерал-полковник
Группа: Модераторы
Сообщений: 803
Награды: 3
Репутация: 18
Статус: Offline
Вот пример через "цензура"



Добавлено (24.06.2011, 22:35)
---------------------------------------------
Кажется я обнаружил в своём коде кое какое недоразумение, попозже исправлю. Ведь egg моно забацать средствами панды, а не тупым склеиванием строк. happy

Добавлено (25.06.2011, 21:55)
---------------------------------------------
redface оказалось создание egg средствами панды только нервы портить, классы глючат ни какой гибкости, например текстуру можно добавить через EggPolygon который создаёт и Polygon. Загрузка напрямую из EggData в рендер тоже не всё как надо, например 10000 поликов грузит как разные обьекты, хотя если сохранить в файл, и загрузить то будет всё как надо. То лучше уж клеить строки. Легко и просто.

Добавлено (26.06.2011, 13:59)
---------------------------------------------
Вот исправил, не нужных действий меньше. Но всё таки скорость загрузки очень медленная. loadEggData тужится ~ 9 сек, переливание данных из виртуального файла в EggData ~2 сек, сама же генерация 0.2 - 10000 полигонов. Кстати egg сгенирированный методом склеиванием строк можно сохранить пандовским writeEgg то разметка синтаксиса будет оформлена в правильный вид.
Прикрепления: REC.rar (6.1 Kb) · 5099415.jpg (191.7 Kb)


ООП  -  

Сообщение отредактировал serg-kkz - Воскресенье, 26.06.2011, 14:17
 
ninthДата: Понедельник, 27.06.2011, 00:47 | Сообщение # 43
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
В принципе, я думаю оба эти куска можно кинуть в "примеры кода".
 
soosДата: Четверг, 30.06.2011, 19:13 | Сообщение # 44
Майор
Группа: Пользователи
Сообщений: 82
Награды: 1
Репутация: 0
Статус: Offline
Обернул всё в класс:
Code
class tilemap(NodePath):
  def __init__(self, name='tilemap'):
   NodePath.__init__(self, name)
   self.terrain_node = GeomNode(name)
   self.attachNewNode(self.terrain_node)
   self.geoms = []
  def add_tile_type(self, tex_file):
   gvd = GeomVertexData('gvd', GeomVertexFormat.getV3t2(), Geom.UHStatic)
   geom = Geom(gvd)
   prim = GeomTriangles(Geom.UHStatic)
   vertex = GeomVertexWriter(gvd, 'vertex')
   texcoord = GeomVertexWriter(gvd, 'texcoord')
   tex = loader.loadTexture(tex_file)
   tex.setMagfilter(Texture.FTLinearMipmapLinear)
   tex.setMinfilter(Texture.FTLinearMipmapLinear)
   rs = RenderState.make(TextureAttrib.make(tex))
   self.terrain_node.addGeom(geom, rs)
   self.geoms.append({'geom':geom,'prim':prim,'vertex':vertex,'texcoord':texcoord,'index':0,'gvd':gvd,'texture':tex})
  def add_tile(self, x, z, tile_type):
   i = self.geoms[tile_type]['index']
   v = self.geoms[tile_type]['vertex']
   t = self.geoms[tile_type]['texcoord']
   p = self.geoms[tile_type]['prim']
   v.addData3f(x, 0, z)
   t.addData2f(0, 0)
   v.addData3f(x, 0, z+1)
   t.addData2f(0, 1)
   v.addData3f(x+1, 0, z+1)
   t.addData2f(1, 1)
   v.addData3f(x+1, 0, z)
   t.addData2f(1, 0)
   p.addVertices(i*4, i*4 + 2, i*4 + 1)
   p.addVertices(i*4, i*4 + 3, i*4 + 2)
   self.geoms[tile_type]['index'] += 1
  def bake(self):
   for i in xrange(0, len(self.geoms)):
    self.geoms[i]['prim'].closePrimitive()
    self.geoms[i]['geom'].addPrimitive(self.geoms[i]['prim'])

terrain = tilemap()

for i in xrange(0,3):
  terrain.add_tile_type('tile%i.png' % (i+1))

size = 100
for x in xrange(0,size):
  for z in xrange(0,size):
   terrain.add_tile(x, z, random.randint(0,2))

terrain.bake()
terrain.reparentTo(render)
terrain.setPos(-size/2,0,-size/2)
terrain.analyze()

run()


Думаю как это оптимизировать и можно ли сделать динамическое добавление/удаление тайлов.
 
serg-kkzДата: Четверг, 30.06.2011, 19:26 | Сообщение # 45
Генерал-полковник
Группа: Модераторы
Сообщений: 803
Награды: 3
Репутация: 18
Статус: Offline
Ты всё заткнул в иницилизацию, а надо в функцию над который ты будешь иметь контроль, попробуй для начала сделать генерацию по нажатию кнопки. Для поставленой задачи потребуютя координаты, по которым надо расчитать четыре точки и добавить их к геометрии и вызвать функцию.

Вот пример для расчёта:

x = 2
y = 3

Расчитывем координаты vertex'ов из которых будет строиться полигон(это пример если через egg, но может и здесь будет работать)

0 vertex = x-0.5, y-0.5 добавляем к геометрии - 1.5, 1,5
1 vertex = x+0.5, y-0.5 добавляем к геометрии - 2.5, 1.5
2 vertex = x+0.5, y+0.5 добавляем к геометрии - 2.5, 3.5
3 vertex = x-0.5, y+0.5 добавляем к геометрии - 1.5, 3.5

Примечание: это формула для квадрата 1*1

Для оптимизации переделый код чтоб только генерил один полигон без for'ов, ведь ты будешь в место этого вызывать функцию по событию, получил координаты - передал функции с вызовом её.


ООП  -  

Сообщение отредактировал serg-kkz - Четверг, 30.06.2011, 20:36
 
Форум Panda3D - по русски » Panda3D » Для начинающих » Tilemap rendering (генерация поверхности на основе набора тайлов)
  • Страница 3 из 4
  • «
  • 1
  • 2
  • 3
  • 4
  • »
Поиск: