ObjReader Community
WIP => WIP => Topic started by: Patrice Terrier on December 13, 2016, 11:12:59 pm
-
PowerBASIC include file for the
BassBox Plugin interface definition
'// 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_RENDER
' '// Draw the scene using BBP.LeftPeak and BBP.RightPeak
' case %BBP_CREATE
' '// Retrieve plugin details
' BBP.Title = "My BB plugin"
' BBP.Author = "My Name"
' BBP.Version = MAKDWD(1, 0) '// Version 1.0"
' BBP.RenderTo = %BBP_OPENGL '// or %BBP_GDIPLUS, or %BBP_DIRECTX
' case %BBP_INIT
' '// do your code initialisation there
' case %BBP_SIZE
' '// The size of the view port has changed.
' case %BBP_KEYBOARD
' '// Handle all Windows keyboard messages there
' Msg = BBP.WinMsg
' wParam = BBP.wParam
' lParam = BBP.lParam
' case %BBP_MOUSE
' '// Handle all Windows mouse messages there
' Msg = BBP.WinMsg
' wParam = BBP.wParam
' lParam = BBP.lParam
' case %BBP_DESTROY
' '// Free up your resources there
' case else
' nRet = %BBP_ERROR
' end select
' function = nRet
'end function
The BBplugin.inc is attached to this post
-
Here is a very simple example to show you how to create a Visual BBplugin with OpenGL.
'+--------------------------------------------------------------------------+
'| |
'| Woofer |
'| BassBox OpenGL plugin |
'| |
'| Version 1.00 |
'| |
'+--------------------------------------------------------------------------+
'| |
'| Author Patrice TERRIER |
'| |
'| copyright(c) 2007 |
'| |
'| Patrice Terrier http://www.zapsolution.com |
'| |
'+--------------------------------------------------------------------------+
'| Project started on : 10-30-2007 (MM-DD-YYYY) |
'| Last revised : 11-14-2007 (MM-DD-YYYY) |
'+--------------------------------------------------------------------------+
'
#COMPILE DLL "Woofer.dll"
#INCLUDE "Include\BBPlugin.inc"
'//declare sub skDebug lib "SKENGINE.DLL" (byval Msg$)
type RECT
nLeft as long
nTop as long
nRight as long
nBottom as long
end type
macro const = macro
' Key State Masks for Mouse Messages
const MK_LBUTTON = &H0001
const MK_RBUTTON = &H0002
const MK_SHIFT = &H0004
const MK_CONTROL = &H0008
const MK_MBUTTON = &H0010
const MK_XBUTTON1 = &H0020
const MK_XBUTTON2 = &H0040
const WM_MOUSEMOVE = &H200
const WM_LBUTTONDOWN = &H201
const WM_LBUTTONUP = &H202
const WM_LBUTTONDBLCLK = &H203
const WM_RBUTTONDOWN = &H204
const WM_RBUTTONUP = &H205
const WM_RBUTTONDBLCLK = &H206
const WM_MBUTTONDOWN = &H207
const WM_MBUTTONUP = &H208
const WM_MBUTTONDBLCLK = &H209
const WM_MOUSEWHEEL = &H20A
const WM_XBUTTONDOWN = &H20B
const WM_XBUTTONUP = &H20C
const WM_XBUTTONDBLCLK = &H20D
const GL_UNSIGNED_BYTE = &h1401&
const GL_QUADS = &h0007&
const GL_COLOR_BUFFER_BIT = &h4000&
const GL_DEPTH_BUFFER_BIT = &h0100&
const GL_MATRIX_MODE = &h0BA0&
const GL_MODELVIEW = &h1700&
const GL_PROJECTION = &h1701&
const GL_SMOOTH = &h1D01&
const GL_DEPTH_TEST = &h0B71&
const GL_SRC_ALPHA = &h0302&
const GL_ONE = &h0001&
const GL_BLEND = &h0BE2&
const GL_LINEAR = &h2601&
const GL_PERSPECTIVE_CORRECTION_HINT = &h0C50&
const GL_NICEST = &h1102&
const GL_TEXTURE_2D = &h0DE1&
const GL_TEXTURE_MAG_FILTER = &h2800&
const GL_TEXTURE_MIN_FILTER = &h2801&
const GL_LUMINANCE = &h1909&
const GL_RGB = &H1907
const GL_RGBA = &H1908
const GL_TEXTURE = &H1702
const GL_LESS = &H0201
const GL_LIGHTING = &H0B50
const GL_GREATER = &H0204
declare function GetClientRect lib "USER32.DLL" alias "GetClientRect" (byval hwnd as dword, lpRect as RECT) as long
declare function wglGetProcAddress lib "opengl32.dll" alias "wglGetProcAddress" (lpStr as asciiz) as long
declare sub glEnd lib "opengl32.dll" alias "glEnd"
declare sub glPushMatrix lib "opengl32.dll" alias "glPushMatrix"
declare sub glLoadIdentity lib "opengl32.dll" alias "glLoadIdentity"
declare sub glBegin lib "opengl32.dll" alias "glBegin" (byval long)
declare sub glClear lib "opengl32.dll" alias "glClear" (byval dword)
declare sub glEnable lib "opengl32.dll" alias "glEnable" (byval dword)
declare sub glDisable lib "opengl32.dll" alias "glDisable" (byval dword)
declare sub glClearDepth lib "opengl32.dll" alias "glClearDepth" (byval double)
declare sub glShadeModel lib "opengl32.dll" alias "glShadeModel" (byval dword)
declare sub glMatrixMode lib "opengl32.dll" alias "glMatrixMode" (byval dword)
declare sub glHint lib "opengl32.dll" alias "glHint" (byval dword, byval dword)
declare sub glBlendFunc lib "opengl32.dll" alias "glBlendFunc" (byval long, byval long)
declare sub glTexCoord2f lib "opengl32.dll" alias "glTexCoord2f" (byval single, byval single)
declare sub glTexEnvi lib "opengl32.dll" alias "glTexEnvi" (byval dword, byval dword, byval long)
declare sub glVertex3f lib "opengl32.dll" alias "glVertex3f" (byval single, byval single, byval single)
declare sub glTranslatef lib "opengl32.dll" alias "glTranslatef" (byval single, byval single, byval single)
declare sub glColor3f lib "opengl32.dll" alias "glColor3f" (byval single, byval single, byval single)
declare sub glFrustum lib "opengl32.dll" alias "glFrustum" (byval double, byval double, byval double, byval double, byval double, byval double)
declare sub glColor4f lib "opengl32.dll" alias "glColor4f" (byval single, byval single, byval single, byval single)
declare sub glViewport lib "opengl32.dll" alias "glViewport" (byval long, byval long, byval long, byval long)
declare sub glClearColor lib "opengl32.dll" alias "glClearColor" (byval single, byval single, byval single, byval single)
declare sub glGenTextures lib "opengl32.dll" alias "glGenTextures" (byval dword, textures as ANY)
declare sub glBindTexture lib "opengl32.dll" alias "glBindTexture" (byval dword, byval dword)
declare sub glTexParameteri lib "opengl32.dll" alias "glTexParameteri" (byval dword, byval dword, byval long)
declare sub glTexImage2D lib "opengl32.dll" alias "glTexImage2D" (byval dword, byval long, byval long, byval long, byval long, byval long, byval dword, byval dword, npixels as ANY)
declare sub glDeleteTextures lib "opengl32.dll" alias "glDeleteTextures" (byval long, textures as ANY)
declare function glGetError lib "opengl32.dll" alias "glGetError" () as dword
declare function wglMakeCurrent lib "OPENGL32.DLL" alias "wglMakeCurrent" (byval hdc as dword, byval hglrc as dword) as long
declare sub gluPerspective lib "glu32.dll" alias "gluPerspective" (byval fovy#, byval aspect#, byval zNear#, byval zFar as double)
declare sub glRotatef lib "OPENGL32.DLL" alias "glRotatef" (byval angle as single, byval x as single, byval y as single, byval z as single)
declare sub glDepthFunc lib "OPENGL32.DLL" alias "glDepthFunc" (byval func as dword)
declare sub glAlphaFunc lib "OPENGL32.DLL" alias "glAlphaFunc" (byval func as dword, byval ref as single)
global gsR(), gsG(), gsB() as single
global gColor() as long, gzRegistryPluginCXYZ as asciiz * 64
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
'// The main exported plugin's function would be bbProc, like this:
function BBProc alias "BBProc" (BYREF BBP as BBPLUGIN) export as long
local x, y, k, KK, nRet, Msg, wParam, lParam as long
local sDataString as STRING
static Mx, My, MDown as long
static UseFont as ZGLFONT
static Cx, _ '// Camera rotation
Cy, _ '// Camera rotation
Cz _ '// Zoom
as single
' static ptr_wglSwapIntervalEXT as dword
dim mt(1 TO 1) as static BBPTEXTURE
nRet = %BBP_SUCCESS
select case long BBP.Msg
case %BBP_RENDER
local Direction as long, Ax, Bx, Ay, By as single
local nLValue, nRValue as dword, UseColor as long
nLValue = (BBP.Lpeak / 700)
nRValue = (BBP.Rpeak / 700)
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)
'// Draw coordinates using OpenGL font
UseColor = BBP_ColorARGB(255, RGB(20, 20, 148))
Af$ = "CX " + str$(cint(CX)) + " CY " + str$(cint(CY)) + " CZ " + str$(cint(CZ))
BBP_DrawGLText(BBP.ParentWindow, UseFont, 10, 10, (Af$), UseColor)
'BBP_DrawGLText(BBP.ParentWindow, UseFont, 10, 10 + UseFont.fontHeight, ("CY " + str$(cint(CY))), UseColor)
'BBP_DrawGLText(BBP.ParentWindow, UseFont, 10, 10 + UseFont.fontHeight * 2, ("CZ " + str$(cint(CZ))), UseColor)
glLoadIdentity()
glTranslatef(0.0, 0.0, Cz)'-50.0)
glrotatef(Cx, 1.0, 0.0, 0.0)
glrotatef(Cy, 0.0, 1.0, 0.0)
'// This is where the magic happens:
'// BBP.FFTsize returns a pointer to an area of memory containing an array of 256 singles.
'// This is then mapped to the fft() array where it can be accessed.
dim fft(BBP.FFTsize) as single at BBP.FFTdata
dim SoundBuffer(BBP.FFTsize) as single
'// Try and smooth out the buffer by averaging the last results:
for k = 0 TO 255
'// We use sqr to bring out the midtone of the music, otherwise the spectrum is very flat.
'// And fortunatly sqr is highy optimized in PowerBASIC
SoundBuffer(k) = sqr(sqr(fft(k))*2)
next
for Direction = -1 TO 1
if (Direction) then
for KK = 0 TO 2
k = KK * 16
glPushMatrix()
'// The iterator k goes from 0 (deepest bass) to 255 (highest treble pitch)
'// Ax is the distance from the center. Ay & By are width and height of the flares.
Ax = (KK * 16) / 64 * 125 * Direction
Ay = 2 + SoundBuffer(k) * (50 + k / 255 * 70) '// as k increases, the relative size of the signal
By = 2 + SoundBuffer(k) * (50 + k / 255 * 70) '// drops, so the (k / 255 * 20) compensates by boosting the signal at higher frequencies.
glColor4f(gsR(k) * SoundBuffer(k), gsG(k) * SoundBuffer(k), gsB(k) * SoundBuffer(k) + 0.1, 0.7)
glTranslatef(Ax, 0.0, 0.0)
glrotatef(Cx, 1, 0, 0)
glrotatef(Cy, 0, 1, 0)
glBegin(GL_QUADS)
glTexCoord2f(0,0): glVertex3f(-By , Ay, 0.0)
glTexCoord2f(1,0): glVertex3f( By , Ay, 0.0)
glTexCoord2f(1,1): glVertex3f( By ,-Ay, 0.0)
glTexCoord2f(0,1): glVertex3f(-By ,-Ay, 0.0)
glEnd()
glPopMatrix()
next
end if
next
'// Very important we must reassign BBP.RC to the new BBP.DC
'// Note: don't use permanent DC, this produce better and smoother display
wglMakeCurrent(BBP.DC, BBP.RC)
case %BBP_CREATE
'// Retrieve plugin details
BBP.Title = "Woofer"
BBP.Author = "Patrice Terrier"
BBP.Version = MAKDWD(1, 0) '// Version 1.0"
BBP.RenderTo = %BBP_OPENGL '// or %BBP_GDIPLUS, or %BBP_DIRECTX
gzRegistryPluginCXYZ = $RegistryPluginCXYZ + BBP.Title
case %BBP_INIT
'// May I ask you at which pretty pointer wglSwapIntervalEXT situated is ?
'ptr_wglSwapIntervalEXT = wglGetProcAddress("wglSwapIntervalEXT")
'// Do your code initialisation there
ColorInit()
'// Set random-number seed.
RANDOMIZE TIMER
BBP_SplitColorARGB(BBP.BackARGB, A?, R?, G?, B?)
Alpha! = A? + 1: Red! = R? + 1: Green! = G? + 1: Blue! = B? + 1
glClearColor(Red! / 256, Green! /256, Blue! / 256, Alpha! / 256)
glShadeModel(GL_SMOOTH) '// Enables Smooth Color Shading
glClearDepth(1.0) '// Depth Buffer Setup
glDisable(GL_DEPTH_TEST)'// Disable Depth Buffer
'**'glBlendFunc(GL_SRC_ALPHA, GL_ONE)
glBlendFunc(GL_ONE, GL_ONE)
glDepthFunc(GL_LESS) '// The type Of Depth Test To Do
glDisable(GL_LIGHTING)
glEnable(GL_BLEND)
glAlphaFunc(GL_GREATER, 0.01)
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
glEnable(GL_TEXTURE_2D)
mt(1).FullName = $BBP_PLUGIN_FOLDER + "Texture\Boomer.png": mt(1).ID = 1: mt(1).Square = 0
MakeMultipleTexture (byval varptr(mt(lbound(mt))), ubound(mt) - lbound(mt) + 1)
UseFont.fontName = "Arial"
UseFont.fontHeight = 10
UseFont.fontWeight = %FW_BOLD
BBP_BuildGLfont(BBP.DC, UseFont) ' Build OpenGL font for our OpenGL window
MakeColorLUT()
'// Retrieve CX, CY, CZ from registry
sDataString = BBP_GetReg(0, $RegistryKey, gzRegistryPluginCXYZ)
if (parsecount(sDataString) = 3) then
Cx = VAL(PARSE$(sDataString, 1))
CY = VAL(PARSE$(sDataString, 2))
Cz = VAL(PARSE$(sDataString, 3))
else
gosub ResetCXCYCZ
end if
case %BBP_SIZE
'// The size of the view port has changed.
local rAspect as double, rc as RECT
GetClientRect(BBP.ParentWindow, rc)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
rAspect = 0: if rc.nBottom then rAspect = rc.nRight / rc.nBottom
gluPerspective(50.0, rAspect, 0.01, 5000.0)
glMatrixMode(GL_MODELVIEW)
case %BBP_MOUSE
'// Handle all Windows mouse messages there
Msg = BBP.WinMsg: wParam = BBP.wParam: lParam = BBP.lParam
select case long Msg
case WM_MOUSEMOVE
x = LO(WORD, lParam): y = HI(WORD, lParam)
if MDown = MK_LBUTTON then
Cy = Cy + (x - Mx)
Cx = Cx + (y - My)
ELSEIF MDown = MK_RBUTTON then
Cy = Cy + (x - Mx)
Cz = Cz + (y - My)
end if
Mx = x: My = y
case WM_LBUTTONDOWN, WM_RBUTTONDOWN ', WM_MBUTTONDOWN, WM_XBUTTONDOWN
Mx = LO(WORD, lParam): My = HI(WORD, lParam)
if wParam = MK_LBUTTON or wParam = MK_RBUTTON then MDown = wParam
case WM_LBUTTONUP, WM_RBUTTONUP ', WM_MBUTTONUP, WM_XBUTTONUP
MDown = 0
'case WM_LBUTTONDBLCLK, WM_RBUTTONDBLCLK ', WM_MBUTTONDBLCLK, WM_XBUTTONDBLCLK
'case WM_MOUSEWHEEL
end select
case %BBP_KEYBOARD
'// Handle all Windows keyboard messages there
Msg = BBP.WinMsg: wParam = BBP.wParam: lParam = BBP.lParam
if (wParam = 32) then gosub ResetCXCYCZ
case %BBP_DESTROY
'// Save CX, CY, CZ to registry
if (CX or CY or CZ) then
sDataString = str$(cint(CX)) + "," + str$(cint(CY)) + "," + str$(cint(CZ))
BBP_SetReg(0, $RegistryKey, gzRegistryPluginCXYZ, (sDataString))
end if
'// Free up your resources there
DestroyTexture (byval varptr(mt(lbound(mt))), ubound(mt) - lbound(mt) + 1)
BBP_DeleteGLFont(UseFont) ' Free up the OpenGL font
case else
nRet = %BBP_ERROR
end select
function = nRet
exit function
ResetCXCYCZ:
Cx = -600: Cy = -900: Cz = -150
return
end function
sub MakeColorLUT()
local k, RGBColor as long
dim gsR(255), gsG(255), gsB(255) as single
for k = 0 TO 255
RGBColor = LevelColr(k)
gsR(k) = (BBP_GetRValue(RGBColor) + 1) / 256
gsG(k) = (BBP_GetGValue(RGBColor) + 1) / 256
gsB(k) = (BBP_GetBValue(RGBColor) + 1) / 256
next
end sub
sub MakeMultipleTexture (byval tp as BBPTEXTURE ptr, byval N as long)
local mtCount, k, nRet, xSize, ySize, OkDelete as long
dim mt(1 TO N) as BBPTEXTURE at tp
mtCount = ubound(mt()) - lbound(mt()) + 1
if (mtCount) then
dim Texture(1 TO mtCount) as long
for k = 1 TO mtCount
Texture(k) = mt(k).Texture: if Texture(k) then OkDelete = -1
next
if OkDelete then glDeleteTextures(mtCount, Texture(1))
glGenTextures(mtCount, Texture(1)): nRet = glGetError()
if (nRet = 0) then
for k = 1 TO mtCount
redim PixelArray(0) as byte
if (BBP_CreateGLTextureFromFile(mt(k).FullName, xSize, ySize, PixelArray(), mt(k).Square)) then
mt(k).Texture = Texture(k)
glBindTexture(GL_TEXTURE_2D, Texture(k)): nRet = glGetError
if (nRet = 0) then
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexImage2D(GL_TEXTURE_2D, 0, 4, xSize&, ySize&, 0, GL_RGBA, GL_UNSIGNED_BYTE, PixelArray(0))
end if
end if
next
end if
end if
end sub
sub DestroyTexture(byval tp as BBPTEXTURE ptr, byval N as long)
local k, mtCount, OkDelete as long
dim mt(1 TO N) as BBPTEXTURE at tp
mtCount = ubound(mt()) - lbound(mt()) + 1
if (mtCount) then
dim Texture(1 TO mtCount) as long
for k = 1 TO mtCount
Texture(k) = mt(k).Texture: if Texture(k) then OkDelete = -1
next
if (OkDelete) then glDeleteTextures(mtCount, Texture(1))
end if
end sub
-
LaserBeam
Use it as a template to create your own BassBox compatible 64-bit visual plugins.
1 - The common BBplugin.h inlude file.
The attached file comprise the common API to be used with every plugin.
2 - The specific LaserBeam.cpp plugin code.
//+--------------------------------------------------------------------------+
//| |
//| LaserBeam |
//| BassBox OpenGL plugin |
//| |
//| Version 2.00 |
//| |
//+--------------------------------------------------------------------------+
//| |
//| Author Patrice TERRIER |
//| |
//| copyright(c) 2007-2017 |
//| |
//| Patrice Terrier http://www.zapsolution.com |
//| |
//+--------------------------------------------------------------------------+
//| Project started on : 10-30-2007 (MM-DD-YYYY) |
//| Last revised : 02-08-2017 (MM-DD-YYYY) |
//+--------------------------------------------------------------------------+
#include <windows.h>
#include <mfapi.h>
#include <gl/GL.h>
#include <gl/GLU.h>
#include <shlwapi.h>
#include <math.h>
#include "gl2.h"
#include "BBplugin.h"
#define ExportC extern "C" _declspec (dllexport)
long g_color[34];
float gsR[255], gsG[255], gsB[255];
void bbp_ColorInit() {
g_color[0] = 0;
g_color[1] = bbpARGB(255, 32,32,32);
g_color[2] = bbpARGB(255, 0,44,233);
g_color[3] = bbpARGB(255, 0,67,210);
g_color[4] = bbpARGB(255, 0,89,187);
g_color[5] = bbpARGB(255, 0,112,164);
g_color[6] = bbpARGB(255, 0,135,142);
g_color[7] = bbpARGB(255, 0,159,117);
g_color[8] = bbpARGB(255, 0,183,88);
g_color[9] = bbpARGB(255, 0,207,58);
g_color[10] = bbpARGB(255, 0,231,29);
g_color[11] = bbpARGB(255, 26,234,26);
g_color[12] = bbpARGB(255, 52,237,23);
g_color[13] = bbpARGB(255, 79,240,20);
g_color[14] = bbpARGB(255, 105,243,17);
g_color[15] = bbpARGB(255, 126,245,14);
g_color[16] = bbpARGB(255, 147,248,11);
g_color[17] = bbpARGB(255, 168,250,8);
g_color[18] = bbpARGB(255, 189,253,5);
g_color[19] = bbpARGB(255, 210,255,2);
g_color[20] = bbpARGB(255, 233,255,0);
g_color[21] = bbpARGB(255, 255,255,0);
g_color[22] = bbpARGB(255, 255,251,0);
g_color[23] = bbpARGB(255, 255,235,0);
g_color[24] = bbpARGB(255, 255,215,0);
g_color[25] = bbpARGB(255, 255,196,0);
g_color[26] = bbpARGB(255, 255,176,0);
g_color[27] = bbpARGB(255, 255,156,0);
g_color[28] = bbpARGB(255, 253,137,0);
g_color[29] = bbpARGB(255, 255,117,0);
g_color[30] = bbpARGB(255, 255,97,0);
g_color[31] = bbpARGB(255, 255,78,0);
g_color[32] = bbpARGB(255, 255,58,0);
g_color[33] = bbpARGB(255, 255,0,0);
}
long bbp_LevelColor(IN long nLevel) {
long nColor = 0;
nLevel += 1; if (nLevel > 33) { nLevel = 33; }
if (nLevel > 0) { nColor = g_color[nLevel]; }
return nColor;
}
void MakeColorLUT() {
long RGBColor = 0;
for (long K = 0; K < 256; K++) {
RGBColor = bbp_LevelColor(K);
gsR[K] = (float)(GetRValue(RGBColor) + 1) / 256.0f;
gsG[K] = (float)(GetGValue(RGBColor) + 1) / 256.0f;
gsB[K] = (float)(GetBValue(RGBColor) + 1) / 256.0f;
}
}
ExportC long BBProc (OUT BBPLUGIN &BBP) {
long nRet = BBP_SUCCESS;
const float SmoothValue = 0.8f, Cx = -515.0f, Cy = -180.0f, Cz = -23.0f;
float fft[256], SoundBuffer[256], rAspect;
static BBPTEXTURE mt;
nRet = BBP_SUCCESS;
switch (BBP.msg) {
case BBP_RENDER:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f, -5.0f, Cz);
glRotatef(Cx, 1.0f, 0.0f, 0.0f);
glRotatef(Cy, 0.0f, 1.0f, 0.0f);
// This is where the magic happens:
// BBP.fftdata returns a pointer to an area of memory containing an array of 256 singles.
//float* fft = new float[BBP.fftsize];
MoveMemory(&fft[0], BBP.fftdata, 256 * sizeof(float));
// Try and smooth out the buffer by averaging the last results:
for (long K = 0; K < 256; K++) {
// We use SQR to bring out the midtone of the music, otherwise the spectrum is very flat.
SoundBuffer[K] = (float) sqrt(fft[K]) * SmoothValue;
}
for (long Direction = -1; Direction < 2; Direction++) {
if (Direction) {
for (long K = 0; K < 256; K++) {
glPushMatrix();
// The iterator K goes from 0 (deepest bass) to 255 (highest treble pitch)
// Ax is the distance from the center. Ay & By are width and height of the flares.
float Ax = K / 255.0f * 100.0f * Direction;
float Ay = 2 + SoundBuffer[K] * (50.0f + K / 255.0f * 70.0f); // As K increases, the relative size of the signal
float By = 2 + SoundBuffer[K] * (50.0f + K / 255.0f * 70.0f) * 0.2f; // drops, so the (K / 255 * 20) compensates by boosting the signal at higher frequencies.
glColor4f(gsR[K] * SoundBuffer[K], gsG[K] * SoundBuffer[K], gsB[K] * SoundBuffer[K] + 0.1f, 0.7f * SmoothValue);
glTranslatef(Ax, 0.0f, 0.0f);
glRotatef(-Cx, 1.0f, 0.0f, 0.0f);
glRotatef(-Cy, 0.0f, 1.0f, 0.0f);
glBegin(GL_QUADS);
glTexCoord2f(0.0f,0.0f); glVertex3f(-By , Ay, 0.0f);
glTexCoord2f(1.0f,0.0f); glVertex3f( By , Ay, 0.0f);
glTexCoord2f(1.0f,1.0f); glVertex3f( By ,-Ay, 0.0f);
glTexCoord2f(0.0f,1.0f); glVertex3f(-By ,-Ay, 0.0f);
glEnd();
glPopMatrix();
}
}
}
// Very important we must reassign BBP.RC to the new BBP.DC
// Note: don't use permanent DC, this produce better and smoother display
wglMakeCurrent(BBP.dc, BBP.rc);
break;
case BBP_CREATE:
// Retrieve plugin details
strcpy_s(BBP.title, "Laser beam");
strcpy_s(BBP.author, "Patrice Terrier");
BBP.version = MAKEWORD(1, 0); // Version 1.0"
BBP.renderto = BBP_OPENGL; // or BBP_GDIPLUS, or BBP_DIRECTX
break;
case BBP_INIT:
// Do your code initialisation there
bbp_ColorInit();
glClearColor((GetRValue(BBP.backargb) + 1) / 256.0f, (GetGValue(BBP.backargb) + 1) / 256.0f, (GetBValue(BBP.backargb) + 1) / 256.0f, 1.0f);
glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
glClearDepth(1.0f); // Depth Buffer Setup
glDisable(GL_DEPTH_TEST); // Disable Depth Buffer
glBlendFunc(GL_ONE, GL_ONE);
glDepthFunc(GL_LESS); // The Type Of Depth Test To Do
glDisable(GL_LIGHTING);
glEnable(GL_BLEND);
glAlphaFunc(GL_GREATER, 0.01f);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glEnable(GL_TEXTURE_2D);
PathCombine(mt.FullName, TexturePath(), L"Beam.jpg"); mt.ID = 1; mt.Square = 4; // Use mipmapping
MakeMultipleTexture(&mt, 1);
MakeColorLUT();
break;
case BBP_SIZE:
// The size of the view port has changed.
RECT rc; GetClientRect(BBP.parent, &rc);
glViewport(0, 0, Width(rc), Height(rc));
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
rAspect = 0.0f;
if (rc.bottom) { rAspect = float(rc.right / (float)rc.bottom); }
gluPerspective(50.0f, rAspect, 0.01f, 5000.0f);;
glMatrixMode(GL_MODELVIEW);
break;
case BBP_DESTROY:
// Free up your resources there
DestroyTexture (&mt, 1);
break;
default:
nRet = BBP_ERROR;
break;
}
return nRet;
}
Screen shot
(http://www.objreader.com/download/demo/LaserBeam.png)
The full VS 2015 community project is attached to this post to show you how to create the DLL plugin.
Note: Every 64-bit plugin is meant to be used with the latest version of the MediaBox player.
-
Oscillo
Use it as a template to create your own BassBox compatible 64-bit visual plugins.
1 - The common BBplugin.h inlude file.
The attached file comprise the common API to be used with every plugin.
2 - The specific bbp_Oscillo.cpp plugin code.
//+--------------------------------------------------------------------------+
//| |
//| Oscillo |
//| BassBox OpenGL plugin |
//| |
//| Version 2.00 |
//| |
//+--------------------------------------------------------------------------+
//| |
//| Author Patrice TERRIER |
//| |
//| copyright(c) 2007-2017 |
//| |
//| Patrice Terrier http://www.zapsolution.com |
//| |
//+--------------------------------------------------------------------------+
//| Project started on : 10-30-2007 (MM-DD-YYYY) |
//| Last revised : 02-14-2017 (MM-DD-YYYY) |
//+--------------------------------------------------------------------------+
#include <windows.h>
#include <mfapi.h>
#include <gl/GL.h>
#include <gl/GLU.h>
#include <shlwapi.h>
#include <math.h>
#include "gl2.h"
#include "BBplugin.h"
#define ExportC extern "C" _declspec (dllexport)
long g_color[34];
GLubyte gnR[255], gnG[255], gnB[255];
void bbp_ColorInit() {
g_color[0] = bbpARGB(255, 32,32,32);
g_color[1] = bbpARGB(255, 0,22,253);
g_color[2] = bbpARGB(255, 0,44,233);
g_color[3] = bbpARGB(255, 0,67,210);
g_color[4] = bbpARGB(255, 0,89,187);
g_color[5] = bbpARGB(255, 0,112,164);
g_color[6] = bbpARGB(255, 0,135,142);
g_color[7] = bbpARGB(255, 0,159,117);
g_color[8] = bbpARGB(255, 0,183,88);
g_color[9] = bbpARGB(255, 0,207,58);
g_color[10] = bbpARGB(255, 0,231,29);
g_color[11] = bbpARGB(255, 26,234,26);
g_color[12] = bbpARGB(255, 52,237,23);
g_color[13] = bbpARGB(255, 79,240,20);
g_color[14] = bbpARGB(255, 105,243,17);
g_color[15] = bbpARGB(255, 126,245,14);
g_color[16] = bbpARGB(255, 147,248,11);
g_color[17] = bbpARGB(255, 168,250,8);
g_color[18] = bbpARGB(255, 189,253,5);
g_color[19] = bbpARGB(255, 210,255,2);
g_color[20] = bbpARGB(255, 233,255,0);
g_color[21] = bbpARGB(255, 255,255,0);
g_color[22] = bbpARGB(255, 255,251,0);
g_color[23] = bbpARGB(255, 255,235,0);
g_color[24] = bbpARGB(255, 255,215,0);
g_color[25] = bbpARGB(255, 255,196,0);
g_color[26] = bbpARGB(255, 255,176,0);
g_color[27] = bbpARGB(255, 255,156,0);
g_color[28] = bbpARGB(255, 253,137,0);
g_color[29] = bbpARGB(255, 255,117,0);
g_color[30] = bbpARGB(255, 255,97,0);
g_color[31] = bbpARGB(255, 255,78,0);
g_color[32] = bbpARGB(255, 255,58,0);
g_color[33] = bbpARGB(255, 255,0,0);
}
long bbp_LevelColor(IN long nLevel) {
long nColor = 0;
nLevel += 1; if (nLevel > 33) { nLevel = 33; }
if (nLevel > 0) { nColor = g_color[nLevel]; }
return nColor;
}
void MakeColorLUT() {
long RGBColor = 0;
for (long K = 0; K < 256; K++) {
RGBColor = bbp_LevelColor(K);
gnR[K] = GetRValue(RGBColor);
gnG[K] = GetGValue(RGBColor);
gnB[K] = GetBValue(RGBColor);
}
}
ExportC long BBProc (OUT BBPLUGIN &BBP) {
long percent, K, nRet = BBP_SUCCESS;
BYTE color = 0;
static BBPTEXTURE mt;
short ndata = 0;
static float MultiplanIndex[101];
static float vf[128][101][2]; // audio frames
static long stt; // index to most distant + 2
static float PulseAngle;
float pulse, rAspect;
switch (BBP.msg) {
case BBP_RENDER:
// Draw the scene
long I, J, ColorRange;
BYTE Fading;
// Velocity section
pulse = (float)fabs(max(BBP.lpeak / 700.0f, BBP.rpeak / 700.0f) / 28.0f);
PulseAngle = (float)fmod(PulseAngle + pulse, 360.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
GL_LookAt (0.0f, 0.0f, 19.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
glTranslatef(0.0f, 0.22f, 0.0f); // 02-18-2017
// CARTESIAN ARRAY
float UseSize, Multiplan, zS;
glPushMatrix();
J = 100;
I = J + 2;
while (TRUE) {
I -= 2; if (I < 0) { break; }
MultiplanIndex[I] += 1.0f; // 0.75 '0.5'0.2'02 ' speed
if (MultiplanIndex[I] > J) { MultiplanIndex[I] = 0; stt = I; } // recycle
}
I = J + 2;
while (TRUE) {
// Rendering from furthest to nearest (ascending Z order)
I -= 2; if (I < 0) { break; }
stt -= 2; if (stt < 0) { stt = J; } // loop round
Multiplan = MultiplanIndex[stt]; // furthest away first
if (Multiplan == 0) {
for (K = 0; K < 128; K++) {
// WIM MAGIC!
// BBP.WIMdata returns a pointer to an area of memory
// containing an array of 256 short integer.
// Warning, the Left and Right audio channels are mixed together
// thus we step 4, to consider only one channel.
MoveMemory(&ndata, BBP.wimdata + K * 4, 2);
vf[K][stt][0] = (float)((float)ndata / 32767.0f);
MoveMemory(&ndata, BBP.wimdata + 2 + K * 4, 2);
vf[K][stt][1] = (float)((float)ndata / 32767.0f);
}
}
UseSize = 2.0f; // Size
zS = -Multiplan * 0.03125f; // Z spacing
if (Multiplan < 30.0f) { // detail
glEnable(GL_LINE_SMOOTH);
Fading = (BYTE)(min(2.0f / Multiplan, 1.0f) * 255.0f);
glLineWidth(max(Multiplan / 2.0f, 2.0f));
// Draw left channel
glPushMatrix();
percent = (long)((BBP.mediapos * 100) / BBP.medialength);
if (percent > 99) { PulseAngle = 0; }
if ((percent < 33) || (percent > 66)) {
glRotatef(-PulseAngle, 1.0f, 0.0f, 0.0f);
} else {
glRotatef(-PulseAngle, 0.0f, 1.0f, 0.0f);
}
glTranslatef(0.0f, -0.25f, 0.0f);
glBegin(GL_LINES);
for (K = 0; K < 127; K++) {
// color range must fit between 0-32
ColorRange = (long) (17 + (vf[K][stt][0] / 0.09375f));
if (Multiplan > 0) { ColorRange = ColorRange / 2; }
glColor4ub(gnR[ColorRange], gnG[ColorRange], gnB[ColorRange], Fading);
glVertex3f(-UseSize + UseSize * K / 64.0f, vf[K][stt][0], zS);
glVertex3f(-UseSize + UseSize *(K + 1) / 64.0f, vf[K + 1][stt][0], zS);
}
glEnd();
glPopMatrix();
// Draw right channel
glPushMatrix();
if ((percent < 33) || (percent > 66)) {
glRotatef(PulseAngle, 1.0f, 0.0f, 0.0f);
} else {
glRotatef(PulseAngle, 0.0f, 1.0f, 0.0f);
}
glTranslatef(0.0f, 0.25f, 0.0f);
glBegin(GL_LINES);
for (K = 0; K < 127; K++) {
// color range must fit between 0-32
ColorRange = (long) (17 + (vf[K][stt][1] / 0.09375f));
glColor4ub(gnR[ColorRange], gnG[ColorRange], gnB[ColorRange], Fading);
glVertex3f(-UseSize + UseSize * K / 64.0f, vf[K][stt][1], zS);
glVertex3f(-UseSize + UseSize * (K + 1) / 64.0f, vf[K + 1][stt][1], zS);
}
glEnd();
glPopMatrix();
}
}
glPopMatrix();
glFlush();
// Very important we must reassign BBP.RC to the new BBP.DC
// Note: don't use permanent DC, this produce better and smoother display
wglMakeCurrent(BBP.dc, BBP.rc);
break;
case BBP_CREATE:
// Retrieve plugin details
strcpy_s(BBP.title, "Oscilloscope");
strcpy_s(BBP.author, "Patrice Terrier");
BBP.version = MAKEWORD(1, 0); // Version 1.0"
BBP.renderto = BBP_OPENGL; // or BBP_GDIPLUS, or BBP_DIRECTX
break;
case BBP_INIT:
// Do your code initialisation there
bbp_ColorInit();
glClearColor((GetRValue(BBP.backargb) + 1) / 256.0f, (GetGValue(BBP.backargb) + 1) / 256.0f, (GetBValue(BBP.backargb) + 1) / 256.0f, 1.0f);
for (K = 1; K < 101; K++) { MultiplanIndex[K] = (float) K; }
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearDepth((GLclampd) 1.0); // Depth Buffer Setup
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
glEnable(GL_COLOR_MATERIAL); // Enable Coloring Of Material
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Enable Alpha Blending
glEnable(GL_BLEND); // Enable Blending
glEnable(GL_ALPHA_TEST); // Enable Alpha Testing
glAlphaFunc(GL_ALWAYS, 0.0f) ; // Set Alpha Testing
MakeColorLUT();
break;
case BBP_SIZE:
// The size of the view port has changed.
RECT rc; GetClientRect(BBP.parent, &rc);
glViewport(0, 0, Width(rc), Height(rc));
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
rAspect = 0.0f;
if (Height(rc)) { rAspect = (float) Width(rc) / (float) Height(rc); }
GL_Perspective(7.0f, rAspect, 1.0f, 100.0f);
glMatrixMode(GL_MODELVIEW);
break;
case BBP_DESTROY:
// Free up your resources there
break;
default:
nRet = BBP_ERROR;
break;
}
return nRet;
}
Screen shot
(http://www.objreader.com/download/demo/bbp_Oscillo.png)
The full VS 2015 community project is attached to this post to show you how to create the DLL plugin.
Note: Every 64-bit plugin is meant to be used with the latest version of the MediaBox player.