This is just a little test while I was making up my mind what render effect to use for the Image Processing challenge, I've since decided to do something else instead of motion blur so this is posted just so it doesn't end up gathering dust on my HD.
A lot of motion blur is faked and simply works by keeping the last few frames and drawing them with increasing opacity. It's a cheap way of doing the effect and looks kind of shitty.
Motion blur happens when a fast moving image is over exposed to film, photography where you see the trailing headlights of cars at night time is a good example of this, so to simulate the effect I've rendered a cheap and shitty 3D starfield 4 times each vbl, after the rendering, the four frame buffers are combined into one to give a more true representation of motion blur.
Hope it helps someone.
'
' MOTION BLUR
' ===========
'
' By Shockwave / Codigos 2011
'
' WWW.DBFINTERACTIVE.COM
' Coded in a hurry - could be made 500% faster ;-)
' This just explains the technique.
'-------------------------------------------------------------------------------
RANDOMIZE TIMER
'-------------------------------------------------------------------------------
#INCLUDE "TINYPTC_EXT.BI"
#INCLUDE "WINDOWS.BI"
OPTION STATIC
OPTION EXPLICIT
'-------------------------------------------------------------------------------
CONST XRES = 640
CONST YRES = 480
CONST HALFX = 320
CONST HALFY = 240
DIM SHARED AS DOUBLE RAD2DEG
RAD2DEG = (4 * ATN ( 1 )) / 180
DIM SHARED AS UINTEGER SCREEN_BUFFER ( XRES * YRES )
DIM SHARED AS UINTEGER M_BUFFER_1 ( XRES * YRES )
DIM SHARED AS UINTEGER M_BUFFER_2 ( XRES * YRES )
DIM SHARED AS UINTEGER M_BUFFER_3 ( XRES * YRES )
DIM SHARED AS UINTEGER M_BUFFER_4 ( XRES * YRES )
CONST STARNUM = 4000
DIM SHARED STARX (STARNUM) AS DOUBLE
DIM SHARED STARY (STARNUM) AS DOUBLE
DIM SHARED STARZ (STARNUM) AS DOUBLE
DIM SHARED PALETTE_(10000)
DECLARE SUB SETSTARS()
DECLARE SUB DRAWSTARS(BYVAL BUFFER AS INTEGER)
DECLARE SUB RENDER()
SETSTARS()
'-------------------------------------------------------------------------------
PTC_ALLOWCLOSE(0)
PTC_SETDIALOG(1,"Test"+CHR$(13)+"Full Screen?",0,1)
IF (PTC_OPEN("Shockwave 2011",XRES,YRES)=0) THEN
END-1
END IF
SLEEP 5
DIM SHARED AS DOUBLE DV,OLD,GADD,RR ,SAD
'-------------------------------------------------------------------------------
WHILE(GETASYNCKEYSTATE(VK_ESCAPE)<> -32767 and PTC_GETLEFTBUTTON=FALSE)
OLD=TIMER
DRAWSTARS(1)
DRAWSTARS(2)
DRAWSTARS(3)
DRAWSTARS(4)
RENDER()
PTC_UPDATE@SCREEN_BUFFER(0)
SLEEP 1
DV=(TIMER-OLD)*4
GADD=GADD+DV
WEND
EXITPROCESS(0)
'-------------------------------------------------------------------------------
END
SUB RENDER()
DIM AS UINTEGER PTR PP1
DIM AS UINTEGER PTR PP2
DIM AS UINTEGER PTR PP3
DIM AS UINTEGER PTR PP4
DIM AS UINTEGER PTR PP5
PP1=@M_BUFFER_1(0)
PP2=@M_BUFFER_2(0)
PP3=@M_BUFFER_3(0)
PP4=@M_BUFFER_4(0)
PP5=@SCREEN_BUFFER(0)
DIM LP AS INTEGER
FOR LP=1 TO XRES*YRES
*PP5 = PALETTE_(((*PP1+*PP2+*PP3+*PP4) shr 1))
PP1+=1
PP2+=1
PP3+=1
PP4+=1
PP5+=1
NEXT LP
ERASE M_BUFFER_1
ERASE M_BUFFER_2
ERASE M_BUFFER_3
ERASE M_BUFFER_4
END SUB
SUB DRAWSTARS(BYVAL BUFFER AS INTEGER)
DIM AS INTEGER LP,TX,TY
SAD = SAD+(DV*.015)
DIM AS INTEGER L
'-------------------------------------------------------------------------------
' WE WILL ROTATE ONE AXIS OF IT BEFORE WE DO ANYTHING ELSE;
'-------------------------------------------------------------------------------
DIM AS DOUBLE RGADD :' STORES THETA (ROTATION ANGLE)
DIM AS DOUBLE MO1,MO2:' STORES MATRIX CONSTANTS FOR SPEED.
DIM AS DOUBLE MMM,NNN:' STORES X+Y FOR ROTATION
RGADD=.025*SIN(SAD):' CALCULATE THETA
MO1= COS(RGADD):' GENERATE MATRIX CONSTANT 1
MO2= SIN(RGADD):' GENERATE MATRIX CONSTANT 2
FOR L=1 TO STARNUM
'-----------------------------------------------------------------------
' ROTATE THE GRID
'-----------------------------------------------------------------------
NNN=STARX(L)
MMM=STARY(L)
STARX(L) = MO1 * NNN - MO2 * MMM:' ONE AXIS OF ROTATION
STARY(L) = MO1 * MMM + MO2 * NNN:
NEXT
SELECT CASE BUFFER
CASE 1
FOR LP=1 TO STARNUM
TX=(STARX(LP)/STARZ(LP))+HALFX
TY=(STARY(LP)/STARZ(LP))+HALFY
IF TX>0 AND TX<XRES AND TY>0 AND TY<YRES THEN
M_BUFFER_1(TX+(TY*XRES))=(32-STARZ(LP))*8
END IF
STARZ(LP)=STARZ(LP)-DV
IF STARZ(LP)<=0 THEN STARZ(LP)=STARZ(LP)+32
NEXT
CASE 2
FOR LP=1 TO STARNUM
TX=(STARX(LP)/STARZ(LP))+HALFX
TY=(STARY(LP)/STARZ(LP))+HALFY
IF TX>0 AND TX<XRES AND TY>0 AND TY<YRES THEN
M_BUFFER_2(TX+(TY*XRES))=(32-STARZ(LP))*8
END IF
STARZ(LP)=STARZ(LP)-DV
IF STARZ(LP)<=0 THEN STARZ(LP)=STARZ(LP)+32
NEXT
CASE 3
FOR LP=1 TO STARNUM
TX=(STARX(LP)/STARZ(LP))+HALFX
TY=(STARY(LP)/STARZ(LP))+HALFY
IF TX>0 AND TX<XRES AND TY>0 AND TY<YRES THEN
M_BUFFER_3(TX+(TY*XRES))=(32-STARZ(LP))*8
END IF
STARZ(LP)=STARZ(LP)-DV
IF STARZ(LP)<=0 THEN STARZ(LP)=STARZ(LP)+32
NEXT
CASE 4
FOR LP=1 TO STARNUM
TX=(STARX(LP)/STARZ(LP))+HALFX
TY=(STARY(LP)/STARZ(LP))+HALFY
IF TX>0 AND TX<XRES AND TY>0 AND TY<YRES THEN
M_BUFFER_4(TX+(TY*XRES))=(32-STARZ(LP))*8
END IF
STARZ(LP)=STARZ(LP)-DV
IF STARZ(LP)<=0 THEN STARZ(LP)=STARZ(LP)+32
NEXT
END SELECT
END SUB
SUB SETSTARS()
DIM LP AS INTEGER
FOR LP=1 TO STARNUM
STARX(LP) = ((RND(1)*5000))-2500
STARY(LP) = ((RND(1)*5000))-2500
STARZ(LP) = (RND(1)*32)
NEXT
DIM AS DOUBLE RR,GG,BB
RR=0
GG=0
BB=0
FOR LP=1 TO 5000
RR+=1
GG+=.75
BB+=.5
IF RR>255 THEN RR=255
IF GG>255 THEN GG=255
IF BB>255 THEN BB=255
PALETTE_(LP)=RGB(RR,GG,BB)
NEXT
END SUB