看一下Panda3D的Tut-Procedural-Cube示例;
一个旋转的立方体;
可以在六个面上添加纹理;
单独看一下绘制立方体这部分代码;
from direct.showbase.ShowBase import ShowBase
from panda3d.core import lookAt
from panda3d.core import GeomVertexFormat, GeomVertexData
from panda3d.core import Geom, GeomTriangles, GeomVertexWriter
from panda3d.core import Texture, GeomNode
from panda3d.core import PerspectiveLens
from panda3d.core import Vec3, Vec4, Point3
import sys, os
def myNormalize(myVec):
myVec.normalize()
return myVec
def makeSquare(x1,y1,z1, x2,y2,z2):
format=GeomVertexFormat.getV3n3cpt2()
vdata=GeomVertexData('square', format, Geom.UHDynamic)
vertex=GeomVertexWriter(vdata, 'vertex')
normal=GeomVertexWriter(vdata, 'normal')
color=GeomVertexWriter(vdata, 'color')
texcoord=GeomVertexWriter(vdata, 'texcoord')
#make sure we draw the sqaure in the right plane
if x1!=x2:
vertex.addData3f(x1, y1, z1)
vertex.addData3f(x2, y1, z1)
vertex.addData3f(x2, y2, z2)
vertex.addData3f(x1, y2, z2)
normal.addData3f(myNormalize(Vec3(2*x1-1, 2*y1-1, 2*z1-1)))
normal.addData3f(myNormalize(Vec3(2*x2-1, 2*y1-1, 2*z1-1)))
normal.addData3f(myNormalize(Vec3(2*x2-1, 2*y2-1, 2*z2-1)))
normal.addData3f(myNormalize(Vec3(2*x1-1, 2*y2-1, 2*z2-1)))
else:
vertex.addData3f(x1, y1, z1)
vertex.addData3f(x2, y2, z1)
vertex.addData3f(x2, y2, z2)
vertex.addData3f(x1, y1, z2)
normal.addData3f(myNormalize(Vec3(2*x1-1, 2*y1-1, 2*z1-1)))
normal.addData3f(myNormalize(Vec3(2*x2-1, 2*y2-1, 2*z1-1)))
normal.addData3f(myNormalize(Vec3(2*x2-1, 2*y2-1, 2*z2-1)))
normal.addData3f(myNormalize(Vec3(2*x1-1, 2*y1-1, 2*z2-1)))
#adding different colors to the vertex for visibility
color.addData4f(1.0,0.0,0.0,1.0)
color.addData4f(0.0,1.0,0.0,1.0)
color.addData4f(0.0,0.0,1.0,1.0)
color.addData4f(1.0,0.0,1.0,1.0)
texcoord.addData2f(0.0, 1.0)
texcoord.addData2f(0.0, 0.0)
texcoord.addData2f(1.0, 0.0)
texcoord.addData2f(1.0, 1.0)
#quads arent directly supported by the Geom interface
#you might be interested in the CardMaker class if you are
#interested in rectangle though
tri1=GeomTriangles(Geom.UHDynamic)
tri2=GeomTriangles(Geom.UHDynamic)
tri1.addVertex(0)
tri1.addVertex(1)
tri1.addVertex(3)
tri2.addConsecutiveVertices(1,3)
tri1.closePrimitive()
tri2.closePrimitive()
square=Geom(vdata)
square.addPrimitive(tri1)
square.addPrimitive(tri2)
return square
class MyApp(ShowBase):
def __init__(self):
ShowBase.__init__(self)
self.camera.setPos(0, -10, 0)
square0=makeSquare(-1,-1,-1, 1,-1, 1)
square1=makeSquare(-1, 1,-1, 1, 1, 1)
square2=makeSquare(-1, 1, 1, 1,-1, 1)
square3=makeSquare(-1, 1,-1, 1,-1,-1)
square4=makeSquare(-1,-1,-1,-1, 1, 1)
square5=makeSquare( 1,-1,-1, 1, 1, 1)
snode=GeomNode('square')
snode.addGeom(square0)
snode.addGeom(square1)
snode.addGeom(square2)
snode.addGeom(square3)
snode.addGeom(square4)
snode.addGeom(square5)
cube=render.attachNewNode(snode)
app = MyApp()
app.run()
运行一下;如下;应该是只看到一个面;
square0=makeSquare(-1,-1,-1, 1,-1, 1)
square1=makeSquare(-1, 1,-1, 1, 1, 1)
square2=makeSquare(-1, 1, 1, 1,-1, 1)
square3=makeSquare(-1, 1,-1, 1,-1,-1)
square4=makeSquare(-1,-1,-1,-1, 1, 1)
square5=makeSquare( 1,-1,-1, 1, 1, 1)
这部分把1改为3或者0.5,都是一样;
先大体理解一下上面代码;
顶点信息由GeomVertexData保存;
顶点一般有四列:位置,法线,颜色,纹理坐标;
默认,顶点索引从0开始,连续递增;
每个GeomVertexData和一个GeomVertexFormat关联;GeomVertexFormat描述顶点格式;
GeomTriangles,三角形条带类,三角形条带就是多个三角形组成一条带状;
Geom,几何形体类;单个Geom对象构成最小的场景;
GeomNode,几何形体节点类;一个或多个几何形体组合构成几何形体节点;
GeomVertexWriter,顶点数据读写器,每列都有;
Geom.UHDynamic、Geom.UHStatic,顶点数据在帧之间可调整或不需要修改;
大体就是生成顶点数据,构成三角形条带,构成Geom,再形成几何形体节点,把几何形体节点加入场景;下回再看为什么占了整个绘制窗口;
此处是用三角形条带构成立方体,绘制立方体不一定使用三角形条带;