import sys
import os
import webbrowser
import subprocess
import d3d11
import d3d11x
import d3d11gui as gui
from d3d11c import *
from d3d11x import Rect
LEFT_WIDTH = 225
SAMPLE_HEIGHT = 150
#Difficulty.
TUTORIAL = 1
EASY = 2
NORMAL = 3
HARD = 4
#Type.
TYPE_SAMPLE = 0
TYPE_TUTORIAL = 1
TYPE_TOOL = 2
TYPE_OTHER = 3
class Sample:
def __init__(self, name, pyname, text, image, version, level, type):
self.name = name
self.pyname = pyname
self.text = text
self.image = image
self.version = version
self.level = level
self.type = type
samples = [
Sample("Blobs [Sample]", "SampleBlobs", "Moving blobs which interact with each other.",
None, (0, 1, 0), NORMAL, TYPE_SAMPLE),
Sample("Compute shaders [Sample]", "SampleCompute", "Shows how to use compute shaders to perform calculations using the GPU.",
None, (0, 1, 0), EASY, TYPE_SAMPLE),
Sample("GUI [Sample]", "SampleGui", "Shows how to use d3d11gui.",
None, (0, 1, 0), NORMAL, TYPE_SAMPLE),
Sample("Heightmap [Sample]", "SampleHeightMap", "Shows how to load and render a heightmap.",
None, (0, 1, 0), NORMAL, TYPE_SAMPLE),
Sample("Lights [Sample]", "SampleLights", "Renders some very basic objects and lights.",
None, (0, 1, 0), EASY, TYPE_SAMPLE),
Sample("Media [Sample]", "SampleMedia", "Shows how to play media files.",
None, (0, 1, 0), EASY, TYPE_SAMPLE),
Sample("Simple mesh [Sample]", "SampleMesh", "Shows how to render a 3D mesh.",
None, (0, 1, 0), EASY, TYPE_SAMPLE),
Sample("Post processing [Sample]", "SamplePostProcess", "Use multiple render targets for post processing effects.",
None, (0, 1, 0), NORMAL, TYPE_SAMPLE),
Sample("Sprites 3D [Sample]", "SampleSprites", "Use a geometry shader to render point sprites.",
None, (0, 1, 0), NORMAL, TYPE_SAMPLE),
Sample("Threaded loading [Sample]", "SampleThreaded", "Shows how to load resources using threading.",
None, (0, 1, 0), EASY, TYPE_SAMPLE),
Sample("wxPython [Sample]", "SamplewxPython", "Use DirectPython with wxPython.",
None, (0, 1, 0), NORMAL, TYPE_SAMPLE),
Sample("Tutorial 1", "Tutorial1", "This minimal tutorial shows how to initialize DirectPython and present a black window.",
None, (0, 1, 0), TUTORIAL, TYPE_TUTORIAL),
Sample("Tutorial 2", "Tutorial2", "The second tutorial shows how to render a triangle.",
None, (0, 1, 0), TUTORIAL, TYPE_TUTORIAL),
]
infoText = """-%s
-Feature level: %i.%i"""
class SampleBrowser(d3d11x.Frame):
def onCreate(self):
self.window.setTitle("Sample Browser - DirectPython 11 (%i.%i.%i)" % d3d11.DP_VERSION)
self.showHelp = False
self.manager = gui.Manager(self.device, self.window)
gui.Window.color = tuple([x / 255.0 for x in (0xe0, 0xb0, 0xb0, 0xb0)[::-1]])
self.left = gui.Window(self.manager, Rect(0, 0, LEFT_WIDTH, 1))
self.left.captionHeight = 0
self.left.setAnchor((10, 10, None, 10))
self.searchLabel = gui.Label(self.left, Rect(10, 10, LEFT_WIDTH - 20, 70), "", "Search")
self.searchBox = gui.TextBox(self.searchLabel, Rect(10, 25, LEFT_WIDTH - 40, 30), 0)
self.searchBox.singleline = True
self.searchBox.onChange = self.onChangeSearch
sortLabel = gui.Label(self.left, Rect(10, 90, LEFT_WIDTH - 20, 70), "", "Sort results by")
sortBy = gui.Choice(sortLabel, Rect(10, 25, LEFT_WIDTH - 40, 30))
sortBy.onChoice = self.onChoiceSort
sortBy.add("Difficulty")
sortBy.add("Name")
sortBy.add("Age")
showLabel = gui.Label(self.left, Rect(10, 170, LEFT_WIDTH - 20, 130), "", "Show")
self.checkBox = gui.CheckBoxGroup(showLabel, Rect(10, 25, LEFT_WIDTH - 20, 1))
self.checkBox.onCheck = self.onCheckShow
self.checkBox.add("Samples", True)
self.checkBox.add("Tutorials", True)
self.checkBox.add("Tools", True)
self.checkBox.add("Other", True)
featureLevel = d3d11x.featureLevel(self.device.getFeatureLevel())
infoLabel = gui.Label(self.left, Rect(10, 310, LEFT_WIDTH - 20, 110))
infoLabel.title = "Device info"
infoLabel.text = infoText % (self._adapterName, featureLevel[0], featureLevel[1])
openHelp = gui.Button(self.left, Rect(10, 430, 170, 25), "Open Documentation")
openHelp.center(True, False)
openHelp.onClick = self.onClickHelp
openPage = gui.Button(self.left, Rect(10, 465, 170, 25), "Open Home Page")
openPage.center(True, False)
openPage.onClick = self.onClickHomepage
#checkUpdates = gui.Button(self.left, Rect(10, 500, 170, 25), "Check for updates")
#checkUpdates.center(True, False)
#checkUpdates.onClick = self.onClickUpdates
#checkUpdates.disable()
self.right = gui.Window(self.manager, Rect(0, 0, 1, 1))
self.right.captionHeight = 0
self.right.setAnchor((LEFT_WIDTH + 25, 10, 10, 10))
self.scrollBar = gui.ScrollBar(self.right, Rect(0, 0, 100, 100), gui.SCROLL_Y)
self.sortAndShowByIndex(0)
#def onClickUpdates(self, event):
# print("Check")
def onCheckShow(self, *args):
self.resetSamples()
def onChangeSearch(self, event):
self.resetSamples()
def onClickHelp(self, event):
helpIndex = d3d11x.getResourceDir("..", "Docs", "index.html")
os.startfile(helpIndex)
def onClickHomepage(self, event):
webbrowser.open("http://directpython11.sourceforge.net/")
def onChoiceSort(self, event, i, text):
self.sortAndShowByIndex(i)
def onClickLaunchSample(self, event):
pyPath = d3d11x.getResourceDir(event.sender.pyname + ".py")
self.window.show(SW_HIDE)
try:
subprocess.call('"%s" "%s"' % (sys.executable, pyPath))
except:
pass
self.window.show(SW_SHOW)
def sortAndShowByIndex(self, i):
if i == 0:
samples.sort(key=lambda s: s.level)
elif i == 1:
samples.sort(key=lambda s: s.name)
elif i == 2:
samples.sort(key=lambda s: s.version)
self.resetSamples()
def resetSamples(self):
for child in self.right.children[:]:
if child is not self.scrollBar:
child.close()
searchTerm = self.searchBox.text.strip().lower()
levelColors = {TUTORIAL : (0, 1, 0, 1), NORMAL : (1, 1, 0, 1), EASY : (0, 1, 0, 1)}
hits = 0
y = 10
for sample in samples:
if (len(searchTerm) > 1 and sample.name.lower().find(searchTerm) == -1
and sample.text.lower().find(searchTerm) == -1):
continue
if not self.checkBox.boxes[sample.type].checked:
continue
label = gui.Label(self.right, Rect(10, y, 1, SAMPLE_HEIGHT), sample.text, sample.name)
label.setAnchor((10, None, 30, None))
label.borderColor = levelColors[sample.level]
launch = gui.Button(label, Rect(10, SAMPLE_HEIGHT - 40, 100, 30), "Launch")
launch.pyname = sample.pyname
launch.onClick = self.onClickLaunchSample
launch.toolTip = "Launch the sample as a new process."
y += SAMPLE_HEIGHT + 10
hits += 1
self.searchLabel.title = "Search (%i of %i)" % (hits, len(samples))
step = 50
move = hits * (SAMPLE_HEIGHT + 10) // step
self.scrollBar.setScrollData(gui.ScrollData(int(max(move, 1)), step, gui.SCROLL_Y))
def onMessage(self, msg):
return self.manager.onMessage(msg)
def onRender(self):
self.manager.render(self.frameTime)
if __name__ == "__main__":
sample = SampleBrowser("Sample Browser - DirectPython 11")
sample.mainloop()