#!/usr/bin/python # -*- coding: utf-8 -*- """Could you write most of a software rasterizer in SQL, or is it too slow? asks this question. This program gets about 800–900 frames per second on one core of my laptop so I think the answer is a qualified yes. But I haven't actually rendered the results. """ from __future__ import print_function, division import sqlite3, random, time def render_frame(db): cursor = db.cursor() cursor.execute('''select ycp - rp as ybegin, xcp, ycp, rp, z, r, g, b from ( select x / z as xcp, y / z as ycp, r / z as rp, z, r, g, b from balls ) order by ybegin desc''') for ybegin, xcp, ycp, rp, z, r, g, b in cursor: pass def main(): db = sqlite3.Connection(':memory:') cursor = db.cursor() cursor.execute('''create table balls ( x float, y float, z float, radius float, r float, g float, b float)''') for i in range(256): cursor.execute('''insert into balls (x, y, z, radius, r, g, b) values (?, ?, ?, ?, ?, ?, ?)''', (random.random(), random.random(), random.random(), random.random(), random.random(), random.random(), random.random())) prev = start = time.time() max_frame = 0 for frame in range(60000): render_frame(db) db.cursor().execute('update balls set y = max(0, y - 0.001)') # Rotate the scene in SQL! sin = 0.05 cos = (1 - sin**2)**(1/2) db.cursor().execute('update balls set x = x * ? + y * ?, y = x * ? + y * ?', (cos, sin, -sin, cos)) end = time.time() max_frame = max(max_frame, end - prev) prev = end print(end - start, 'seconds, frame', frame, 'fps', (frame+1)/(end-start), 'max frame time', max_frame) if __name__ == '__main__': main()