Add a few vars, and support for rendering single flames

This commit is contained in:
Steven Robertson 2011-05-03 14:36:20 -04:00
parent 84c2583ba8
commit 8ee5d3edd8
3 changed files with 73 additions and 49 deletions

View File

@ -37,7 +37,7 @@ texture<uchar4, cudaTextureType2D, cudaReadModeNormalizedFloat> palTex;
tmpl = tempita.Template("""
__device__
void apply_xf{{xfid}}(float *ix, float *iy, float *icolor,
const iter_info *info) {
const iter_info *info, mwc_st *rctx) {
float tx, ty, ox = *ix, oy = *iy;
{{apply_affine('ox', 'oy', 'tx', 'ty', px, 'xf.c', 'pre')}}
@ -47,7 +47,7 @@ void apply_xf{{xfid}}(float *ix, float *iy, float *icolor,
{{for v in xform.vars}}
if (1) {
float w = {{px.get('xf.var[%d]' % v)}};
{{variations.var_code[variations.var_nos[v]]()}}
{{variations.var_code[variations.var_nos[v]].substitute(locals())}}
}
{{endfor}}
@ -82,7 +82,7 @@ void iter(mwc_st *msts, iter_info *infos, float *accbuf, float *denbuf) {
{{for xfid, xform in enumerate(features.xforms)}}
if (xfsel <= {{packer.get('cp.norm_density[%d]' % xfid)}}) {
apply_xf{{xfid}}(&x, &y, &color, info);
apply_xf{{xfid}}(&x, &y, &color, info, &rctx);
} else
{{endfor}}
{
@ -97,7 +97,7 @@ void iter(mwc_st *msts, iter_info *infos, float *accbuf, float *denbuf) {
nsamps--;
if (x <= -1.0f || x >= 1.0f || y <= -1.0f || y >= 1.0f) {
if (x <= -0.5f || x >= 0.5f || y <= -0.5f || y >= 0.5f) {
consec_bad++;
if (consec_bad > {{features.max_oob}}) {
x = mwc_next_11(&rctx);
@ -109,8 +109,8 @@ void iter(mwc_st *msts, iter_info *infos, float *accbuf, float *denbuf) {
}
// TODO: dither?
int i = ((int)((y + 1.0f) * 511.0f) * 1024)
+ (int)((x + 1.0f) * 511.0f) + 1025;
int i = ((int)((y + 0.5f) * 1023.0f) * 1024)
+ (int)((x + 0.5f) * 1023.0f) + 1025;
// since info was declared const, C++ barfs unless it's loaded first
float cp_step_frac = {{packer.get('cp_step_frac')}};
@ -129,7 +129,7 @@ void iter(mwc_st *msts, iter_info *infos, float *accbuf, float *denbuf) {
def silly(features, cps):
nsteps = 1000
nsteps = 500
abuf = np.zeros((1024, 1024, 4), dtype=np.float32)
dbuf = np.zeros((1024, 1024), dtype=np.float32)
seeds = mwc.MWC.make_seeds(512 * nsteps)
@ -139,28 +139,37 @@ def silly(features, cps):
for lno, line in enumerate(code.split('\n')):
print '%3d %s' % (lno, line)
mod = SourceModule(code, options=[], keep=True)
mod = SourceModule(code, options=['--use_fast_math'], keep=True)
cps_as_array = (Genome * len(cps))()
for i, cp in enumerate(cps):
cps_as_array[i] = cp
cp = Genome()
memset(byref(cp), 0, sizeof(cp))
infos = []
pal = np.empty((16, 256, 4), dtype=np.uint8)
# TODO: move this into a common function
pal = np.empty((16, 256, 4), dtype=np.uint8)
sampAt = [int(i/15.*(nsteps-1)) for i in range(16)]
if len(cps) > 1:
cp = Genome()
memset(byref(cp), 0, sizeof(cp))
sampAt = [int(i/15.*(nsteps-1)) for i in range(16)]
for n in range(nsteps):
flam3_interpolate(cps_as_array, 2, float(n)/nsteps - 0.5, 0, byref(cp))
flam3_interpolate(cps_as_array, 2, float(n)/nsteps - 0.5,
0, byref(cp))
cp._init()
if n in sampAt:
pidx = sampAt.index(n)
for i, e in enumerate(cp.palette.entries):
pal[pidx][i] = np.uint8(np.array(e.color) * 255.0)
infos.append(iter.packer.pack(cp=cp, cp_step_frac=float(n)/nsteps))
else:
for i, e in enumerate(cps[0].palette.entries):
pal[0][i] = np.uint8(np.array(e.color) * 255.0)
pal[1:] = pal[0]
infos.append(iter.packer.pack(cp=cps[0], cp_step_frac=0))
infos *= nsteps
infos = np.concatenate(infos)
dpal = cuda.make_multichannel_2d_array(pal, 'C')

View File

@ -1,40 +1,58 @@
import tempita
var_nos = {}
var_code = {}
def _var(num, name = None):
def _var1(func):
if name:
namelo = name
else:
namelo = func.__name__
var_nos[num] = namelo
var_code[namelo] = func
return _var1
def var(num, name, code):
var_nos[num] = name
var_code[name] = tempita.Template(code)
# Variables note: all functions will have their weights as 'w',
# input variables 'tx' and 'ty', and output 'ox' and 'oy' available
# from the calling context. Each statement will be placed inside brackets,
# to avoid namespace pollution.
@_var(0)
def linear():
return """
var(0, 'linear', """
ox += tx * w;
oy += ty * w;
"""
""")
@_var(1)
def sinusoidal():
return """
ox += w * sin(tx);
oy += w * sin(ty);
"""
var(1, 'sinusoidal', """
ox += w * sinf(tx);
oy += w * sinf(ty);
""")
@_var(2)
def spherical():
return """
var(2, 'spherical', """
float r2 = w / (tx*tx + ty*ty + 1e-20);
ox += tx * r2;
oy += ty * r2;
"""
""")
var(5, 'polar', """
ox += w * atan2f(tx, ty) * M_1_PI;
oy += w * (sqrtf(tx * tx + ty * ty) - 1.0);
""")
var(10, 'hyperbolic', """
float a = atan2f(tx, ty);
float r = sqrt(tx*tx + ty*ty) + 1e-20;
ox += w * sinf(a) / r;
oy += w * cosf(a) * r;
""")
var(33, 'juliascope', """
float ang = atan2f(ty, tx);
float power = {{px.get('xf.juliascope_power', 'juscope_power')}};
float t_rnd = truncf(mwc_next_01(rctx) * fabsf(power));
// TODO: don't draw the extra random number
if (mwc_next(rctx) & 1) ang = -ang;
float tmpr = (2 * M_PI * t_rnd + ang) / power;
float cn = {{px.get('xf.juliascope_dist / xf.juliascope_power / 2',
'juscope_cn')}};
float r = w * powf(tx * tx + ty * ty, cn);
ox += r * cosf(tmpr);
oy += r * sinf(tmpr);
""")

View File

@ -32,21 +32,18 @@ from cuburn.code.iter import silly, membench
def main(args):
membench()
return
#MWCTest.test_mwc()
with open(args[-1]) as fp:
genomes = Genome.from_string(fp.read())
anim = Animation(genomes)
accum, den = silly(anim.features, genomes)
if '-g' not in args:
return
noalpha = np.delete(accum, 3, axis=2)
scipy.misc.imsave('rendered.png', noalpha)
if '-g' not in args:
return
imgbuf = (np.minimum(accum * 255, 255)).astype(np.uint8)
image = pyglet.image.ImageData(1024, 1024, 'RGBA', imgbuf.tostring(), -4096)