ObjReader Community

WIP => WIP => Topic started by: Patrice Terrier on December 13, 2016, 11:12:59 pm

Title: BassBox Plugin interface definition
Post 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
Title: Woofer (OpenGL visual plugin)
Post by: Patrice Terrier on December 14, 2016, 08:45:02 am
Here is a very simple example to show you how to create a Visual BBplugin with OpenGL.

Code: [Select]
'+--------------------------------------------------------------------------+
'|                                                                          |
'|                                 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
Title: LaserBeam 64-bit (BassBox OpenGL visual plugin)
Post by: Patrice Terrier on February 12, 2017, 11:21:16 am
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.

Code: [Select]
//+--------------------------------------------------------------------------+
//|                                                                          |
//|                                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.
Title: Re: BassBox Plugin interface definition
Post by: Patrice Terrier on February 18, 2017, 07:25:12 pm
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.

Code: [Select]
//+--------------------------------------------------------------------------+
//|                                                                          |
//|                                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.