Insight...
Here is the first BassBox plugin:
'+--------------------------------------------------------------------------+
'| |
'| PLUG002 |
'| BassBox OpenGL plugin |
'| |
'| Version 1.00 |
'+--------------------------------------------------------------------------+
'| |
'| Author Patrice TERRIER |
'| |
'| copyright(c) 2007 |
'| |
'| Patrice Terrier http://www.zapsolution.com |
'| |
'+--------------------------------------------------------------------------+
'| Project started on : 10-23-2007 (MM-DD-YYYY) |
'| Last revised : 10-23-2007 (MM-DD-YYYY) |
'+--------------------------------------------------------------------------+
'
#COMPILE DLL "PLUG002.dll"
#INCLUDE "BBPlugin.inc"
%GL_MODELVIEW = &H1700
%GL_PROJECTION = &H1701
%GL_DEPTH_TEST = &H0B71
%GL_SMOOTH = &H1D01
%GL_TRIANGLE_FAN = &H0006
%GL_DEPTH_BUFFER_BIT = &H00000100
%GL_COLOR_BUFFER_BIT = &H00004000
%GL_LINES = &H0001???
TYPE RECT
nLeft AS LONG
nTop AS LONG
nRight AS LONG
nBottom AS LONG
END TYPE
TYPE tColorBox
length AS DOUBLE
r1 AS BYTE
g1 AS BYTE
b1 AS BYTE
r2 AS BYTE
g2 AS BYTE
b2 AS BYTE
END TYPE
DECLARE FUNCTION GetClientRect LIB "USER32.DLL" ALIAS "GetClientRect" (BYVAL hwnd AS DWORD, lpRect AS RECT) AS LONG
DECLARE SUB glClearColor LIB "OPENGL32.DLL" ALIAS "glClearColor" (BYVAL red AS SINGLE, BYVAL green AS SINGLE, BYVAL blue AS SINGLE, BYVAL alpha AS SINGLE)
DECLARE SUB glEnable LIB "OPENGL32.DLL" ALIAS "glEnable" (BYVAL cap AS DWORD)
DECLARE SUB glShadeModel LIB "OPENGL32.DLL" ALIAS "glShadeModel" (BYVAL mode AS DWORD)
DECLARE SUB glMatrixMode LIB "OPENGL32.DLL" ALIAS "glMatrixMode" (BYVAL mode AS DWORD)
DECLARE SUB glLoadIdentity LIB "OPENGL32.DLL" ALIAS "glLoadIdentity" ()
DECLARE SUB gluPerspective LIB "glu32.dll" ALIAS "gluPerspective" (BYVAL fovy#, BYVAL aspect#, BYVAL zNear#, BYVAL zFar AS DOUBLE)
DECLARE SUB glClear LIB "OPENGL32.DLL" ALIAS "glClear" (BYVAL mask AS DWORD)
DECLARE SUB glRotated LIB "OPENGL32.DLL" ALIAS "glRotated" (BYVAL angle AS DOUBLE, BYVAL x AS DOUBLE, BYVAL y AS DOUBLE, BYVAL z AS DOUBLE)
DECLARE SUB glBegin LIB "OPENGL32.DLL" ALIAS "glBegin" (BYVAL mode AS DWORD)
DECLARE SUB glEnd LIB "OPENGL32.DLL" ALIAS "glEnd" ()
DECLARE SUB glColor3ub LIB "OPENGL32.DLL" ALIAS "glColor3ub" (BYVAL red AS BYTE, BYVAL green AS BYTE, BYVAL blue AS BYTE)
DECLARE SUB glVertex3d LIB "OPENGL32.DLL" ALIAS "glVertex3d" (BYVAL x AS DOUBLE, BYVAL y AS DOUBLE, BYVAL z AS DOUBLE)
DECLARE SUB glPushMatrix LIB "OPENGL32.DLL" ALIAS "glPushMatrix" ()
DECLARE SUB glPopMatrix LIB "OPENGL32.DLL" ALIAS "glPopMatrix" ()
DECLARE SUB glTranslated LIB "OPENGL32.DLL" ALIAS "glTranslated" ( BYVAL DOUBLE, BYVAL DOUBLE, BYVAL DOUBLE )
DECLARE SUB gluLookAt LIB "glu32.dll" ALIAS "gluLookAt" (BYVAL eyex#, BYVAL eyey#, BYVAL eyez#, BYVAL centerx#, BYVAL centery#, BYVAL centerz#, BYVAL upx#, BYVAL upy#, BYVAL upz AS DOUBLE)
DECLARE FUNCTION wglMakeCurrent LIB "OPENGL32.DLL" ALIAS "wglMakeCurrent" (BYVAL hdc AS DWORD, BYVAL hglrc AS DWORD) AS LONG
GLOBAL gColor() AS LONG
SUB ColorInit()
DIM gColor(1 TO 33) AS LONG
gColor(1) = RGB(32,32,32)
gColor(2) = RGB(0,44,233)
gColor(3) = RGB(0,67,210)
gColor(4) = RGB(0,89,187)
gColor(5) = RGB(0,112,164)
gColor(6) = RGB(0,135,142)
gColor(7) = RGB(0,159,117)
gColor(8) = RGB(0,183,88)
gColor(9) = RGB(0,207,58)
gColor(10) = RGB(0,231,29)
gColor(11) = RGB(26,234,26)
gColor(12) = RGB(52,237,23)
gColor(13) = RGB(79,240,20)
gColor(14) = RGB(105,243,17)
gColor(15) = RGB(126,245,14)
gColor(16) = RGB(147,248,11)
gColor(17) = RGB(168,250,8)
gColor(18) = RGB(189,253,5)
gColor(19) = RGB(210,255,2)
gColor(20) = RGB(233,255,0)
gColor(21) = RGB(255,255,0)
gColor(22) = RGB(255,251,0)
gColor(23) = RGB(255,235,0)
gColor(24) = RGB(255,215,0)
gColor(25) = RGB(255,196,0)
gColor(26) = RGB(255,176,0)
gColor(27) = RGB(255,156,0)
gColor(28) = RGB(253,137,0)
gColor(29) = RGB(255,117,0)
gColor(30) = RGB(255,97,0)
gColor(31) = RGB(255,78,0)
gColor(32) = RGB(255,58,0)
gColor(33) = RGB(255,0,0)
END SUB
FUNCTION LevelColr(BYVAL nLevel AS LONG) AS LONG
LOCAL nColor AS LONG
nLevel = nLevel + 1: IF nLevel > 33 THEN nLevel = 33
nColor = 0: IF nLevel > 0 THEN nColor = gColor(nLevel)
FUNCTION = nColor
END FUNCTION
'// Get Red byte from a RGB color.
FUNCTION zGetRValue (BYVAL colrRGB???) AS BYTE
FUNCTION = (colrRGB??? AND &H000000FF???)
END FUNCTION
'// Get Green byte from a RGB color.
FUNCTION zGetGValue (BYVAL colrRGB???) AS BYTE
SHIFT RIGHT colrRGB???, 8
FUNCTION = (colrRGB??? AND &H000000FF???)
END FUNCTION
'// Get Blue byte from a RGB color.
FUNCTION zGetBValue (BYVAL colrRGB???) AS BYTE
SHIFT RIGHT colrRGB???, 16
FUNCTION = (colrRGB??? AND &H000000FF???)
END FUNCTION
'// The main exported plugin's function would be bbProc, like this:
FUNCTION BBProc ALIAS "BBProc" (BYREF BBP AS BBPLUGIN) EXPORT AS LONG
STATIC rXangle, rYangle, rZangle, LastTime AS DOUBLE
DIM PulseMemory(0 TO 128) AS STATIC tColorBox
LOCAL nRet AS LONG
nRet = %BBP_SUCCESS
SELECT CASE LONG BBP.Msg
CASE %BBP_RENDER
'// Draw the scene using BBP.LeftPeak and BBP.RightPeak
LOCAL K, nLValue, nRValue, RGBColor AS LONG
LOCAL xD, pulse AS DOUBLE, R1, G1, B1, R2, G2, B2 AS BYTE
LOCAL PulseMemorySample AS tColorBox
nLValue = (BBP.Lpeak / 700)
nRValue = (BBP.Rpeak / 768)
rXangle = rXangle + 0.3 '// grDXangle
rYangle = rYangle + 0.5 '// grDYangle
rZangle = rZangle + 0.7 '// grDZangle
pulse = MAX(nLValue, nRValue) / 7
'// Pulsating section
CALL glMatrixMode(%GL_PROJECTION)
CALL glLoadIdentity()
CALL gluPerspective(35.0 - pulse, 1.25, 0.1, 150.0)
CALL glMatrixMode(%GL_MODELVIEW)
'// Velocity section
pulse = ABS(pulse / 4)
rXangle = rXangle + pulse '// grDXangle
rYangle = rYangle + pulse '// grDYangle
rZangle = rZangle + pulse '// grDZangle
'// Very important we must reassign UseRC to the new UseDC
'// Note: don't use permanent DC, this produce better and smoother display
CALL wglMakeCurrent(BBP.DC, BBP.RC)
CALL glClear(%GL_COLOR_BUFFER_BIT OR %GL_DEPTH_BUFFER_BIT)
CALL glLoadIdentity()
CALL gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
'// Draw Visualisation
RGBColor = LevelColr(nLValue)
R2 = zGetRValue(RGBColor)
G2 = zGetGValue(RGBColor)
B2 = zGetBValue(RGBColor)
RGBColor = LevelColr(nRValue)
R1 = zGetRValue(RGBColor)
G1 = zGetGValue(RGBColor)
B1 = zGetBValue(RGBColor)
PulseMemorySample.r1 = r1
PulseMemorySample.g1 = g1
PulseMemorySample.b1 = b1
PulseMemorySample.r2 = r2
PulseMemorySample.g2 = g2
PulseMemorySample.b2 = b2
PulseMemorySample.length = pulse
IF TIMER - LastTime > 0.02 THEN ' Not more frequent than 50 Hz
ARRAY INSERT PulseMemory(LBOUND(PulseMemory)), PulseMemorySample
LastTime = TIMER
END IF
FOR K = LBOUND(PulseMemory) TO UBOUND(PulseMemory)
CALL glPushMatrix()
CALL glTranslated(0, 0, -K / 10)
CALL glRotated( K * 3, 0, 0, 1)
xD = 0.25 * (1 + pulse): GOSUB SubRender
CALL glPopMatrix()
CALL glPushMatrix()
CALL glTranslated(0, 0, -K / 10)
CALL glRotated(-K * 3, 0, 0, 1)
xD = 0.125: GOSUB SubRender
CALL glPopMatrix()
NEXT
CASE %BBP_TITLE
'// Retrieve plugin details
BBP.Title = "Mikado"
BBP.Author = "Petr Schreiber"
BBP.Version = MAKDWD(1, 0) '// Version 1.0"
CASE %BBP_INIT
'// Do your code initialisation there
BBP.RenderTo = %BBP_OPENGL '// or %BBP_GDIPLUS, or %BBP_DIRECTX
CALL BBP_SplitColorARGB(BBP.BackARGB, A?, R?, G?, B?)
Alpha! = A? + 1: Red! = R? + 1: Green! = G? + 1: Blue! = B? + 1
CALL glClearColor(Red! / 256, Green! /256, Blue! / 256, Alpha! / 256)
CALL glEnable(%GL_DEPTH_TEST)
CALL glShadeModel(%GL_SMOOTH)
CALL ColorInit()
CASE %BBP_SIZE
'// The size of the view port has changed.
LOCAL rAspect AS DOUBLE, rc AS RECT
CALL GetClientRect(BBP.ParentWindow, rc)
CALL glMatrixMode(%GL_PROJECTION)
CALL glLoadIdentity()
rAspect = 0: IF rc.nBottom THEN rAspect = rc.nRight / rc.nBottom
CALL gluPerspective(35.0, rAspect, 0.1, 150.0)
CALL glMatrixMode(%GL_MODELVIEW)
CASE %BBP_DESTROY
'// Free up your resources there
CASE ELSE
nRet = %BBP_ERROR
END SELECT
FUNCTION = nRet
EXIT FUNCTION
SubRender:
CALL glBegin(%GL_LINES)
CALL glColor3ub(PulseMemory(K).r1, PulseMemory(K).g1, PulseMemory(K).b1)
CALL glVertex3d( xD, -PulseMemory(K).length,-PulseMemory(K).length)
CALL glColor3ub(PulseMemory(K).r2, PulseMemory(K).g2, PulseMemory(K).b2)
CALL glVertex3d( xD, -PulseMemory(K).length, PulseMemory(K).length)
CALL glColor3ub(PulseMemory(K).r1, PulseMemory(K).g1, PulseMemory(K).b1)
CALL glVertex3d( xD, -PulseMemory(K).length, -PulseMemory(K).length)
CALL glColor3ub(PulseMemory(K).r2, PulseMemory(K).g2, PulseMemory(K).b2)
CALL glVertex3d( xD, -PulseMemory(K).length, PulseMemory(K).length)
CALL glEnd()
RETURN
END FUNCTION
and this is the include file declaration:
'+--------------------------------------------------------------------------+
'| BBplugin.inc |
'| |
'| BassBox Plugin interface definition. |
'| |
'+--------------------------------------------------------------------------+
'| |
'| Author Patrice TERRIER |
'| copyright(c) 2007 |
'| www.zapsolution.com |
'| pterrier@zapsolution.com |
'| |
'+--------------------------------------------------------------------------+
'| Project started on : 10-23-2007 (MM-DD-YYYY) |
'| Last revised : 10-23-2007 (MM-DD-YYYY) |
'+--------------------------------------------------------------------------+
%BBP_RENDER = 1 '// Render the scene.
%BBP_TITLE = 2 '// Retrieve Title, Name, Version.
%BBP_INIT = 3 '// Init the OpenGL.
%BBP_SIZE = 4 '// The size of the control has changed.
%BBP_DESTROY = 5 '// Free Up resources.
%BBP_GDIPLUS = 0 '// GDImage GDIPLUS compatible mode.
%BBP_OPENGL = 1 '// OpenGL mode.
%BBP_DIRECTX = 2 '// DirectX mode (for future extension).
%BBP_SUCCESS = 0
%BBP_ERROR = -1
$BBP_PLUGIN_FOLDER = "BBplugin\"
TYPE BBPLUGIN '// 256 bytes
Msg AS LONG '// The plugin's message (see above constant list).
ParentWindow AS LONG '// The parent window handle.
DC AS LONG '// The parent window DC (while in play mode).
RC AS LONG '// The parent OpenGL RC (while in play mode).
Lpeak AS WORD '// The left audio channel peak value (while in play mode).
Rpeak AS WORD '// The right audio channel peak value (while in play mode).
Title AS ASCIIZ * 32 '// Plugin's name or title.
Author AS ASCIIZ * 64 '// Plugin's author name.
Version AS DWORD '// LOWRD major, HIWRD minor.
RenderTo AS LONG '// %BBP_GDIPLUS, %BBP_OPENGL, %BBP_DIRECTX.
BackARGB AS LONG '// Default ARGB color background.
Reserved AS ASCIIZ * 128'// Reserved for future extension.
END TYPE
' Custom types
TYPE COLORBYTES
B AS BYTE
G AS BYTE
R AS BYTE
A AS BYTE
END TYPE
'// Split a true 32-bit ARGB color into its four components.
SUB BBP_SplitColorARGB (BYVAL ARGB&, Alpha AS BYTE, Red AS BYTE, Green AS BYTE, Blue AS BYTE)
DIM bytestruct AS COLORBYTES
LSET bytestruct = MKL$(ARGB&)
Alpha? = bytestruct.A
Red? = bytestruct.R
Green? = bytestruct.G
Blue? = bytestruct.B
END SUB
'// Use a generic "BBPLUGIN" folder that would store all the bbp plugins,
'// each one could have its own embedded subfolders inside of "BBPLUGIN" to store local resources.
'// The main exported plugin's function would be bbProc, like this:
'FUNCTION BBProc ALIAS "BBProc" (BYREF BBP AS BBPLUGIN) EXPORT AS LONG
' LOCAL nRet AS LONG
' nRet = %BBP_SUCCESS
' SELECT CASE LONG BBP.Msg
' CASE %BBP_TITLE
' '// Retrieve plugin details
' BBP.Title = "My BB plugin"
' BBP.Author = "My Name"
' BBP.Version = MAKDWD(1, 0) '// Version 1.0"
' CASE %BBP_INIT
' '// Do your code initialisation there
' BBP.RenderTo = %BBP_OPENGL '// or %BBP_GDIPLUS, or %BBP_DIRECTX
' CASE %BBP_SIZE
' '// The size of the view port has changed.
' CASE %BBP_PLAY
' '// Draw the scene using BBP.LeftPeak and BBP.RightPeak
' CASE %BBP_DESTROY
' '// Free up your resources there
' CASE ELSE
' nRet = %BBP_ERROR
' END SELECT
' FUNCTION = nRet
'END FUNCTION
So far it works well :)
Thanks Patrice,
which version of BassBox is needed to cooperate with it ?
Should I create plugins directory or something ?
Thanks,
Petr
Looking forward to trying it out.
I wonder if I can do something with cubic splines...
Charles, Petr,
Please see the complete plugin version at the end of the BassBox thread.
Note: so far I have done only the OpenGL part.