-
Notifications
You must be signed in to change notification settings - Fork 15
/
textureRenderer.py
140 lines (112 loc) · 4.74 KB
/
textureRenderer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
from panda3d.core import Texture
from panda3d.core import GraphicsOutput
from direct.task.Task import Task
from panda3d.core import FrameBufferProperties
import collections
"""
This is intended to serve is a queueing system for one shot rendering to textures.
"""
def dispose(nodePath):
def kill(n):
for p in n.getChildren():
kill(p)
n.removeNode()
kill(nodePath.getTop())
class QueueItem:
def __init__(self, width, height, callback, getCam, callbackParams=(), getCamParams=(), cleanUpCamCall=dispose,toRam=False, texture=None):
self.cleanUpCamCall=cleanUpCamCall
self.width=width
self.height=height
self.callbackProp=callback
self.getCamMethod=getCam
self.getCamParams=getCamParams
self.toRam=toRam
self.callbackParams=callbackParams
self.texture=texture if texture is not None else Texture()
def callback(self,tex):
self.callbackProp(tex,*self.callbackParams)
def getCam(self):
return self.getCamMethod(*self.getCamParams)
class SimpleQueueItem(QueueItem):
"""
cam is passed to __init__ instead of getCam, thus, scene must be pregenerated, rather than assemblerd when needed.
Use QueueItem instead to dynamically build the scene at the last possible moment with getCam to save space/memory or
to spread scene assembly time out using queue.
"""
def __init__(self, width, height, callback, cam, toRam=False, texture=None):
self.cam=cam
QueueItem.__init__(self, width, height, callback,getCam=None, toRam=toRam, texture=texture)
def getCam(self):
return self.cam
class Queue:
def __init__(self):
self.buffs={}
self.queue=collections.deque()
self.currentItem=None
self.displayRegions={}
self.currentBuff=None
self.renderFrame=0
taskMgr.add(self.processQueue,"processRenderTexQueue")
def flush(self):
"""
force the processing of all current items in a blocking manner
"""
allBuffers=base.graphicsEngine.getWindows()
toActivate=[]
for b in allBuffers:
if b.isActive() and b is not self.currentBuff:
b.setActive(False)
toActivate.append(b)
while self.queue or self.currentItem:
base.graphicsEngine.renderFrame()
self.processQueue()
for b in toActivate:
b.setActive(True)
def processQueue(self,task=None):
self.renderFrame+=1
if self.currentItem is None:
if len(self.queue) > 0:
# Process a queue item!
self.currentItem=self.queue.popleft()
self.renderFrame=0
self.currentBuff=self.getBuff(self.currentItem.width,self.currentItem.height)
self.currentBuff.setActive(True)
# maybe should use RTMCopyTexture?
mode=GraphicsOutput.RTMCopyRam if self.currentItem.toRam else GraphicsOutput.RTMBindOrCopy
self.currentBuff.addRenderTexture(self.currentItem.texture,mode)
self.cam=self.currentItem.getCam()
self.displayRegions[self.currentBuff].setCamera(self.cam)
self.displayRegions[self.currentBuff].setActive(True)
elif self.renderFrame>0:
# Should be rendered by now. Could potentially add extra wait here.
tex = self.currentBuff.getTexture()
#print tex.getFormat()
self.currentBuff.setActive(False)
self.displayRegions[self.currentBuff].setActive(False)
self.currentBuff.clearRenderTextures()
self.currentItem.callback(tex)
self.currentItem.cleanUpCamCall(self.cam)
del self.cam
self.currentItem=None
return Task.cont
def removeBuffers(self):
for s in self.buffs:
base.graphicsEngine.removeWindow(self.buffs[s])
self.buffs={}
def getBuff(self,width,height):
size=(width,height)
if size in self.buffs:
buff=self.buffs[size]
else:
mainWindow=base.win
fbp=FrameBufferProperties(mainWindow.getFbProperties())
#print fbp.getColorBits()
fbp.setColorBits(24*2)
fbp.setDepthBits(0)
fbp.setAlphaBits(0)
buff=mainWindow.makeTextureBuffer('QueueBuff'+str(size),width,height,Texture(),True)
dr=buff.makeDisplayRegion(0, 1, 0, 1)
self.buffs[size]=buff
self.displayRegions[buff]=dr
print "saved buffer "+str(size)
return buff