panda3d/panda/src/tinydisplay/ztriangle.py
2008-05-13 02:09:27 +00:00

162 lines
4.9 KiB
Python
Executable File

""" This simple Python script can be run to generate ztriangle_code.h
and ztriangle_table.h, which are a poor man's form of generated code
to cover the explosion of different rendering options while scanning
out triangles.
Each different combination of options is compiled to a different
inner-loop triangle scan function. The code in
tinyGraphicsStateGuardian.cxx will select the appropriate function
pointer at draw time. """
# We generate an #include "ztriangle_two.h" for each combination of
# these options.
Options = [
# depth write
[ 'zon', 'zoff' ],
# color write
[ 'cstore', 'cblend', 'cgeneral', 'coff' ],
# alpha test
[ 'anone', 'aless', 'amore' ],
# depth test
[ 'znone', 'zless' ],
# texture filters
[ 'nearest', 'mipmap' ],
]
# The various combinations of these options are explicit within
# ztriangle_two.h.
ExtraOptions = [
# shade model
[ 'white', 'flat', 'smooth' ],
# texturing
[ 'untextured', 'textured', 'perspective' ],
]
FullOptions = Options + ExtraOptions
CodeTable = {
# depth write
'zon' : '#define STORE_Z(zpix, z) (zpix) = (z)',
'zoff' : '#define STORE_Z(zpix, z)',
# color write
'cstore' : '#define STORE_PIX(pix, rgb, r, g, b, a) (pix) = (rgb)',
'cblend' : '#define STORE_PIX(pix, rgb, r, g, b, a) (pix) = PIXEL_BLEND_RGB(pix, r, g, b, a)',
'cgeneral' : '#define STORE_PIX(pix, rgb, r, g, b, a) zb->store_pix_func(zb, pix, r, g, b, a)',
'coff' : '#define STORE_PIX(pix, rgb, r, g, b, a)',
# alpha test
'anone' : '#define ACMP(zb, a) 1',
'aless' : '#define ACMP(zb, a) (((unsigned int)(a)) < (zb)->reference_alpha)',
'amore' : '#define ACMP(zb, a) (((unsigned int)(a)) > (zb)->reference_alpha)',
# depth test
'znone' : '#define ZCMP(zpix, z) 1',
'zless' : '#define ZCMP(zpix, z) ((ZPOINT)(zpix) < (ZPOINT)(z))',
# texture filters
'nearest' : '#define CALC_MIPMAP_LEVEL\n#define ZB_LOOKUP_TEXTURE(texture_levels, s, t, level) ZB_LOOKUP_TEXTURE_NEAREST(texture_levels, s, t)',
'mipmap' : '#define CALC_MIPMAP_LEVEL DO_CALC_MIPMAP_LEVEL\n#define INTERP_MIPMAP\n#define ZB_LOOKUP_TEXTURE(texture_levels, s, t, level) ZB_LOOKUP_TEXTURE_NEAREST_MIPMAP(texture_levels, s, t, level)',
}
ops = [0] * len(Options)
class DoneException:
pass
def incrementOptions(ops, i = -1):
if i < -len(ops):
raise DoneException
# Increment the least-significant place if we can.
if ops[i] + 1 < len(Options[i]):
ops[i] += 1
return
# Recurse for the next-most-significant place.
ops[i] = 0
incrementOptions(ops, i - 1)
def getFname(ops):
# Returns the function name corresponding to the indicated ops
# vector.
keywordList = []
for i in range(len(ops)):
keyword = FullOptions[i][ops[i]]
keywordList.append(keyword)
fname = 'FB_triangle_%s' % ('_'.join(keywordList))
return fname
# We write the code that actually instantiates the various
# triangle-filling functions to ztriangle_code.h.
code = open('ztriangle_code.h', 'wb')
print >> code, '/* This file is generated code--do not edit. See ztriangle.py. */'
print >> code, ''
# The external reference for the table containing the above function
# pointers gets written here.
table = open('ztriangle_table.h', 'wb')
print >> table, '/* This file is generated code--do not edit. See ztriangle.py. */'
print >> table, ''
# First, generate the code.
try:
while True:
for i in range(len(ops)):
keyword = Options[i][ops[i]]
print >> code, CodeTable[keyword]
fname = getFname(ops)
print >> code, '#define FNAME(name) %s_ ## name' % (fname)
print >> code, '#include "ztriangle_two.h"'
print >> code, ''
incrementOptions(ops)
except DoneException:
pass
# Now, generate the table of function pointers.
arraySizeList = []
for opList in FullOptions:
arraySizeList.append('[%s]' % (len(opList)))
arraySize = ''.join(arraySizeList)
print >> code, 'const ZB_fillTriangleFunc fill_tri_funcs%s = {' % (arraySize)
print >> table, 'extern const ZB_fillTriangleFunc fill_tri_funcs%s;' % (arraySize)
def writeTableEntry(ops):
indent = ' ' * (len(ops) + 1)
i = len(ops)
numOps = len(FullOptions[i])
if i + 1 == len(FullOptions):
# The last level: write out the actual function names.
for j in range(numOps - 1):
print >> code, indent + getFname(ops + [j]) + ','
print >> code, indent + getFname(ops + [numOps - 1])
else:
# Intermediate levels: write out a nested reference.
for j in range(numOps - 1):
print >> code, indent + '{'
writeTableEntry(ops + [j])
print >> code, indent + '},'
print >> code, indent + '{'
writeTableEntry(ops + [numOps - 1])
print >> code, indent + '}'
writeTableEntry([])
print >> code, '};'