текстурирование "кубика"
|
|
akzy | Дата: Понедельник, 29.04.2013, 11:45 | Сообщение # 1 |
Лейтенант
Группа: Пользователи
Сообщений: 55
Награды: 0
Репутация: 3
Статус: Offline
| Здравствуйте. У меня к вам скромный вопрос - генерирую куб, накладываю на него текстуру,но она в случае 3d текстуры "натягивается" неправильно, а в случае 2д - то одна картинка на все стороны. Подскажите ,куда двигаться, чтобы можно было на каждую сторону применить свою текстуру. часть кода: Код def addcube(self,x,y,z,id): self.mesh = cubik(name="c."+str(x)+"."+str(y)+"."+str(z)+"."+str(id)) self.mesh.makeLeftFace(x,y,z) self.mesh.makeRightFace(x,y,z) self.mesh.makeBackFace(x,y,z) self.mesh.makeFrontFace(x,y,z) self.mesh.makeBottomFace(x,y,z) self.mesh.makeTopFace(x,y,z) mc=render.attachNewNode(self.mesh.getGeomNode()) mc.setTexture(self.texture[id]) mc.reparentTo(render) ..... def makeFace(self, x1, y1, z1, x2, y2, z2, color): # создаёт 1 "сторону"
if x1 != x2: #проверка "плоскости"
self.vertex.addData3f(x1, y1, z1) self.vertex.addData3f(x2, y1, z1) self.vertex.addData3f(x2, y2, z2) self.vertex.addData3f(x1, y2, z2)
else: # координаты self.vertex.addData3f(x1, y1, z1) self.vertex.addData3f(x2, y2, z1) self.vertex.addData3f(x2, y2, z2) self.vertex.addData3f(x1, y1, z2) # r g b ? self.color.addData4f(color, color, color, 1.0) self.color.addData4f(color, color, color, 1.0) self.color.addData4f(color, color, color, 1.0) self.color.addData4f(color, color, color, 1.0)
self.texcoord.addData2f(0.0, 1.0) self.texcoord.addData2f(0.0, 0.0) self.texcoord.addData2f(1.0, 0.0) self.texcoord.addData2f(1.0, 1.0)
vertexId = self.faceCount * 4
self.triangles.addVertices(vertexId, vertexId + 1, vertexId + 3) self.triangles.addVertices(vertexId + 1, vertexId + 2, vertexId + 3)
self.faceCount += 1 #load textures .... for i in range(0,textures): self.texture[i]=loader.loadTexture("texture"+str(i)+".png") ...[/i]
|
|
| |
ninth | Дата: Понедельник, 29.04.2013, 12:04 | Сообщение # 2 |
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
| Сперва надо определиться - тебе нужно Цитата на каждую сторону применить свою текстуру или применить на куб именно 3d текстуру? Это разные вещи.
|
|
| |
akzy | Дата: Понедельник, 29.04.2013, 12:15 | Сообщение # 3 |
Лейтенант
Группа: Пользователи
Сообщений: 55
Награды: 0
Репутация: 3
Статус: Offline
| В случае когда модель грузится loader ом из файла, 3д текстура натягивается как надо, если можно подобное делать на генерируемую модель, то подскажите, где пример посмотреть,это пригодится позже. Мне хотелось для начала на каждую сторону применить разную текстуру, к примеру из того же массива self.textures. upd создавать для каждой меши отдельный объект и накладывать текстуру конечно напрашивается, но не затронет ли это производительность?
Сообщение отредактировал akzy - Понедельник, 29.04.2013, 12:49 |
|
| |
ninth | Дата: Понедельник, 29.04.2013, 12:46 | Сообщение # 4 |
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
| Цитата (akzy) В случае когда модель грузится loader ом из файла, 3д текстура натягивается как надо Насколько я знаю, ни одно приложение на данный момент не умеет экспортировать 3D текстуры в EGG, так что рискну предположить, что тебе нужно работать с обычными 2D текстурами из массива -> во-первых тебе нужны всего две координаты под UV, а во-вторых под каждую текстуру должен быть отдельный геометрический примитив, на который эта текстура будет прменена. Я здесь выложил похожий пример http://panda3d.org.ru/forum/5-267-1
|
|
| |
akzy | Дата: Понедельник, 29.04.2013, 12:52 | Сообщение # 5 |
Лейтенант
Группа: Пользователи
Сообщений: 55
Награды: 0
Репутация: 3
Статус: Offline
| ninth, хорошо, попробую так сделать. А для "удаления" куба только detachnode поможет?
|
|
| |
ninth | Дата: Понедельник, 29.04.2013, 13:19 | Сообщение # 6 |
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
| detachnode отсоединяет нод из иерархии сцены, но он остаётся в памяти и его можно потом прицепить куда-то ещё. Для полного удаления служит removeNode()
|
|
| |
akzy | Дата: Четверг, 02.05.2013, 11:48 | Сообщение # 7 |
Лейтенант
Группа: Пользователи
Сообщений: 55
Награды: 0
Репутация: 3
Статус: Offline
| Цитата (ninth) пример http://panda3d.org.ru/forum/5-267-1
Если в этом примере увеличить количество текстур, то он не работает Message File Name Line Position Traceback <module> D:\_dev\_test\17.py 59 AssertionError: primitive->check_valid(cdata->_data.get_read_pointer()) at line 370 of c:\buildslave\release_sdk_win32\build\panda3d\panda\src\gobj\geom.cxx
|
|
| |
ninth | Дата: Четверг, 02.05.2013, 11:51 | Сообщение # 8 |
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
| Сну надо больше времени уделять Куча ошибок, причём по-невнимательности. Например, банально забыл скобки в 20 строке, id в fill везде единички проставлены, ну и т.п. Привожу пофикшенный код. Единственное, что я не стал разбираться с координатами вершин - сам поковыряешь. Сейчас у тебя полигоны вывернуты внутрь, а два - вообще почему-то отсутствуют. При взгляде на треугольник (фэйс) сверху - если координаты вершин добавляются против часовой стрелки, то нормаль будет на тебя (полигон будет повёрнут к тебе), если по часовой - от тебя. Пример (обозначены номера вершин в полигоне): 0 1 2 3 Здесь чтобы полигон был к тебе лицом добавляем треугольники 210 - 231 или 031 - 023
Собсно код Код from pandac.PandaModules import * import direct.directbase.DirectStart from direct.showbase.DirectObject import DirectObject
class jo():
def __init__(self): self.texturescount=6 self.node=GeomNode('gnode2') self.geoms=[] self.loadtextures() x=0 y=0 z=0 self.fill(x ,y+1,z-1,x ,y ,z ,0)#left self.fill(x+1,y ,z-1,x+1,y+1,z ,1)#right self.fill(x+1,y+1,z-1,x ,y+1,z ,2)#front self.fill(x ,y ,z-1,x+1,y ,z ,3)#back self.fill(x+1,y+1,z ,x ,y ,z ,4)#top self.fill(x ,y+1,z-1,x+1,y ,z-1,5)#bottom self.close() def loadtextures(self): for i in xrange(self.texturescount): 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('_data/_img/cu%i.png' % (i)) tex.setMagfilter(Texture.FTLinearMipmapLinear) tex.setMinfilter(Texture.FTLinearMipmapLinear) self.geoms.append({ 'geom':geom, 'prim':prim, 'vertex':vertex, 'texcoord':texcoord, 'index':0, 'gvd':gvd, 'texture':tex};) def fill(self,x,y,z,x2,y2,z2,id): i=self.geoms[id]['index']
self.geoms[id]['vertex'].addData3f(x ,y , z) self.geoms[id]['vertex'].addData3f(x2 ,y , z) self.geoms[id]['vertex'].addData3f(x2 ,y2 , z2) self.geoms[id]['vertex'].addData3f(x ,y2 , z2)
self.geoms[id]['texcoord'].addData2f(0, 1) self.geoms[id]['texcoord'].addData2f(0, 0) self.geoms[id]['texcoord'].addData2f(1, 0) self.geoms[id]['texcoord'].addData2f(1, 1)
d=i * 4
self.geoms[id]['prim'].addVertices(d, d + 2, d + 1) self.geoms[id]['prim'].addVertices(d, d + 3, d + 2) self.geoms[id]['index'] += 1
def close(self): for i in xrange(self.texturescount): self.geoms[i]['prim'].closePrimitive() self.geoms['geom'].addPrimitive(self.geoms['prim']) self.node.addGeom(self.geoms['geom']) self.node.setGeomState(i, self.node.getGeomState(i).addAttrib( TextureAttrib.make(self.geoms['texture']))) terrain = render.attachNewNode(self.node) #terrain.setRenderModeWireframe() terrain.analyze()
def main(): j=jo() base.cam.setPos(0,-50,15) base.cam.lookAt(0, 0, 0) run() if __name__ == '__main__': main()[/i]
|
|
| |
ninth | Дата: Четверг, 02.05.2013, 11:53 | Сообщение # 9 |
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
| Цитата (akzy) Если в этом примере увеличить количество текстур, то он не работает А самих файлов текстур хватает? И насколько увеличиваешь?
|
|
| |
akzy | Дата: Четверг, 02.05.2013, 11:55 | Сообщение # 10 |
Лейтенант
Группа: Пользователи
Сообщений: 55
Награды: 0
Репутация: 3
Статус: Offline
| Да,я только минут 5 назад увидел и поправил "часть" ошибок) и про скобки не сразу вспомнил... текстур у меня пока 6, попозже хочу добавить "много", пока учусь, ориентируюсь на тот самый minecraft.
|
|
| |
ninth | Дата: Четверг, 02.05.2013, 12:06 | Сообщение # 11 |
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
| В примере нашёл почему текстур много не получается - пофиксил
|
|
| |
akzy | Дата: Четверг, 02.05.2013, 12:15 | Сообщение # 12 |
Лейтенант
Группа: Пользователи
Сообщений: 55
Награды: 0
Репутация: 3
Статус: Offline
| надо мне отпуск брать...чтото 3д меня затягивает...
|
|
| |
ninth | Дата: Четверг, 02.05.2013, 12:39 | Сообщение # 13 |
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
| К слову. По-моему, удобнее всё же не 6 отдельных текстур делать, а развёртку
|
|
| |
akzy | Дата: Четверг, 02.05.2013, 12:44 | Сообщение # 14 |
Лейтенант
Группа: Пользователи
Сообщений: 55
Награды: 0
Репутация: 3
Статус: Offline
| Цитата (ninth) К слову. По-моему, удобнее всё же не 6 отдельных текстур делать, а развёртку функция load3dtexture ? или в генераторе сделать типа разделения Код if id == 1: self.texcoord.addData2f(0.0, 1.0) self.texcoord.addData2f(0.0, 0.0) self.texcoord.addData2f(0.5, 0.0) self.texcoord.addData2f(0.5, 1.0) elif id == 2: self.texcoord.addData2f(0.5, 1.0) self.texcoord.addData2f(0.5, 0.0) self.texcoord.addData2f(1.0, 0.0) self.texcoord.addData2f(1.0, 1.0) хм... если можно, тыкните, куда посмотреть и ещё мысль- если текстуры сложить в 1 файл ,то чтобы их вставить в прогу, нужен PIL и буфер?
Сообщение отредактировал akzy - Четверг, 02.05.2013, 13:05 |
|
| |
ninth | Дата: Пятница, 03.05.2013, 00:26 | Сообщение # 15 |
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
| Всё значительно проще ) Погугли по словам UV-развёртка, UV-координаты, текстурные координаты Вики: http://ru.wikipedia.org/wiki....8%D0%B5
Если коротко, то с помощью UV-координат ты просто указываешь с какого места текстуры треугольник/полигон получит картинку, так что можно просто расположить все нужные тебе изображения на одной текстуре с помощью любого удобного растрового редактора. И кстати в этом случае не надо будет куб бить аж на 6 геомов - можно всё в один упихать, т.к. текстура будет одна
Насчёт генератора - верно texcoord как раз и есть эти самые текстурные координаты, однако имхо разумнее делать не через if, a просто добавив координаты U и V в fill как ты это сделал для координат вершин
|
|
| |