Created
January 2, 2022 02:09
-
-
Save samneggs/dc14a35497f549b19cfe82f308f32c6b to your computer and use it in GitHub Desktop.
Plane Deformations with texture bitmaps - Pi Pico in MicroPython
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Based on routines by Inigo Quilez | |
# https://iquilezles.org/ | |
from LCD_3inch5 import LCD_3inch5 | |
import framebuf | |
import math | |
from time import sleep_ms, sleep_us, ticks_diff, ticks_us, sleep | |
from micropython import const | |
import array | |
from usys import exit | |
import gc | |
SCREEN_HEIGHT = const(70) #70 | |
SCREEN_WIDTH = const(SCREEN_HEIGHT*3) | |
TEXTURE_HEIGHT = const(47) #75 | |
TEXTURE_WIDTH = const(90) #75 | |
# blit_image_file borrowed from Stewart Watkiss | |
# http://www.penguintutor.com/programming/picodisplayanimations | |
def blit_image_file(filename,width,height,cw,ch): # file width, file height, char width, char height | |
#global display_buffer,display_buffer2,screen | |
display_buffer = bytearray(cw*ch*2) #(width * height * 2) | |
with open (filename, "rb") as file: | |
file_position = 0 | |
char_position = 0 | |
ecount = 0 | |
current_byte = file.read(4) # header | |
while file_position < (width * height * 2): | |
current_byte = file.read(1) | |
# if eof | |
if len(current_byte) == 0: | |
break | |
# copy to buffer | |
buffer2[char_position] = ord(current_byte) #and LCD.red | |
char_position += 1 | |
file_position += 1 | |
if char_position == (cw * ch* 2): | |
char_position = 0 | |
file.close() | |
#lcd.show_xy(0,0,TEXTURE_WIDTH-1,TEXTURE_HEIGHT-1,buffer2) | |
#sleep(5) | |
return | |
def init_texture(): | |
for i in range(0,TEXTURE_HEIGHT): | |
texture.line(0,i,TEXTURE_WIDTH-1,i,color_l2[i*2+32]) | |
#screen.blit(texture,0,0) | |
lcd.show_xy(0,0,TEXTURE_WIDTH-1,TEXTURE_HEIGHT-1,texture) | |
@micropython.viper | |
def render_texture(): | |
screen_addr=ptr16(screen) | |
texture_addr=ptr16(texture) | |
for j in range(0,SCREEN_HEIGHT): | |
for i in range(0,SCREEN_WIDTH): | |
screen_addr[SCREEN_WIDTH*j+i] = texture_addr[TEXTURE_WIDTH*(j%(TEXTURE_HEIGHT-1)) + (i%(TEXTURE_WIDTH-1)) ] | |
lcd.show_xy(0,0,SCREEN_WIDTH-1,SCREEN_HEIGHT-1,screen) | |
def createLUT(): | |
for j in range(0,SCREEN_HEIGHT): | |
for i in range(SCREEN_WIDTH): | |
x = -1.00 + 2.00*i/SCREEN_WIDTH | |
y = -1.00 + 2.00*j/(SCREEN_HEIGHT+0) | |
d = math.sqrt( x*x + y*y ) | |
a = math.atan2( y, x ) | |
#print(i,x,y,d,a) | |
#print(int((x+1)*100)) | |
#lcd.draw_point(i,int((a+3)*100),lcd.RED) | |
# magic formulas here | |
if y!=0: | |
#u=1/d/2 # messy circles | |
#v=1/d/2 | |
#u = math.cos( a )/d # rotating magnet poles | |
#v = math.sin( a )/d | |
#u = x*math.cos(2*d) - y*math.sin(2*d) # groovy swirls | |
#v = y*math.cos(2*d) + x*math.sin(2*d) | |
#u = 0.3/(d+0.5*x) # spinning pinwheel | |
#v = 3*a/math.pi | |
#u = 0.02*y+0.03*math.cos(a*3)/(d/2) # nice center flower | |
#v = 0.02*x+0.03*math.sin(a*3)/(d/2) | |
#u = 0.1*x/(0.11+(d/2)*0.5) # scrolling bent horizon | |
#v = 0.1*y/(0.11+(d/2)*0.5) | |
#u = 0.5*a/math.pi # pulsating circles | |
#v = math.sin(7*d/2) | |
#u = d/2*math.cos(a+d/2) # swooshing wave | |
#v = d/2*math.sin(a+d/2) | |
#u = 1/(d/2+0.5+0.5*math.sin(5*a)) # spinning flower | |
#v = a*3/math.pi | |
u = x/abs(y) # 3d room | |
v = 1/abs(y) | |
mLUT.append((int(TEXTURE_WIDTH*u)) % (TEXTURE_WIDTH-1)) | |
mLUT.append((int(TEXTURE_HEIGHT*v)) % (TEXTURE_HEIGHT-1)) | |
@micropython.viper | |
def renderDeformation(): | |
gticks=ticks_us() | |
screen_addr=ptr16(screen) | |
texture_addr=ptr16(texture) | |
mLUT_addr=ptr8(mLUT) | |
for itime in range(200): #(0,100,1): | |
h=0 | |
for k in range(3): #3 | |
for j in range(0,SCREEN_HEIGHT-3,3): | |
for i in range(0,SCREEN_WIDTH,3): | |
o = SCREEN_WIDTH*h + i | |
u = mLUT_addr[ 2*o+0 ] + itime | |
v = mLUT_addr[ 2*o+1 ] + itime | |
#color = texture_addr[TEXTURE_WIDTH*(j%(TEXTURE_HEIGHT-1)) + (i%(TEXTURE_WIDTH-1))] | |
color = texture_addr[TEXTURE_WIDTH*(v%(TEXTURE_HEIGHT-1)) + (u%(TEXTURE_WIDTH-1)) ] | |
screen_addr[SCREEN_WIDTH*j+i] = color | |
screen_addr[SCREEN_WIDTH*j+i+1] = color | |
screen_addr[SCREEN_WIDTH*j+i+2] = color | |
screen_addr[SCREEN_WIDTH*(j+1)+i] = color | |
screen_addr[SCREEN_WIDTH*(j+1)+i+1] = color | |
screen_addr[SCREEN_WIDTH*(j+1)+i+2] = color | |
screen_addr[SCREEN_WIDTH*(j+2)+i] = color | |
screen_addr[SCREEN_WIDTH*(j+2)+i+1] = color | |
screen_addr[SCREEN_WIDTH*(j+2)+i+2] = color | |
h+=1 | |
lcd.show_xy(0,(SCREEN_HEIGHT-1)*k,SCREEN_WIDTH-1,(SCREEN_HEIGHT*(k+1))-2,screen) | |
delta = ticks_diff(ticks_us(), gticks) | |
#FPS=(1_000_000//delta) | |
print(delta) | |
def fade(input_color1, input_color2): | |
color1=input_color1<<8 | input_color1>>8 # byte swap to normal RBG565 | |
red1 =color1>>11& 0b11111 # extract red #13 | |
green1=color1>>6 & 0b11111 # extract green | |
blue1 =color1 & 0b11111 # extract blue | |
color2=input_color2<<8 | input_color2>>8 # byte swap | |
red2 =color2>>11& 0b11111 # extract red | |
green2=color2>>6 & 0b11111 # extract green | |
blue2 =color2 & 0b11111 # extract blue | |
inc_red =(red2- red1)/31 # find increment step | |
inc_green=(green2-green1)/31 | |
inc_blue =(blue2- blue1)/31 | |
for i in range(0,32): | |
red3 =red1 +int(i*inc_red) # build colors by steps | |
green3=green1+int(i*inc_green) | |
blue3 =blue1 +int(i*inc_blue) | |
color3=red3<<11 | green3<<6 | blue3 # combine RGB | |
color_l2.append((color3 & 0x00FF)<<8 | (color3>>8)) # byte swap to LCD RGB565 | |
if __name__=='__main__': | |
lcd = LCD_3inch5() | |
lcd.bl_ctrl(50) | |
lcd.Fill(lcd.BLACK) | |
buffer=bytearray(SCREEN_WIDTH*SCREEN_HEIGHT*2) | |
screen=framebuf.FrameBuffer(buffer,SCREEN_WIDTH,SCREEN_HEIGHT,framebuf.RGB565) | |
buffer2=bytearray(TEXTURE_WIDTH*TEXTURE_HEIGHT*2) | |
texture=framebuf.FrameBuffer(buffer2,TEXTURE_WIDTH,TEXTURE_HEIGHT,framebuf.RGB565) | |
blit_image_file("wall.bin",90,47,90,47) #wall | |
color_l2 = array.array('H', []) | |
fade(lcd.BLACK,lcd.BLUE) | |
fade(lcd.BLUE,lcd.GREEN) | |
fade(lcd.GREEN,lcd.YELLOW) | |
fade(lcd.YELLOW,lcd.ORANGE) | |
fade(lcd.ORANGE,lcd.RED) | |
fade(lcd.RED,lcd.ORANGE) | |
#init_texture() | |
render_texture() | |
mLUT = array.array('b',()) | |
createLUT() | |
gc.collect() | |
print(gc.mem_free()) | |
renderDeformation() | |
lcd.bl_ctrl(0) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment