ObjReader Community
Programming Art => Eye Candies => Topic started by: Patrice Terrier on September 19, 2024, 06:23:34 pm
-
The purpose of this VS2022 application is to switch easily from one plugin to another to check the OpenGL FPO effects transposed to 64-bit.
Most of them inherit from the original 32-bit version written long ago in PowerBASIC.
(http://www.objreader.com/download/images/plugin64.jpg)
To navigate from one plugin to another move the cursor to the left or right edge of the window, and click on the auto/hide arrow.
Use drag & drop to play a specific audio file, and see how the effects interact with it.
Here is the BBP API to use to communicate with the plugin DLL.
See in the WM_TIMER message the gl_DrawScene() code using BBP_RenderOpenGL to pass the wimdata pointer to the DLL.
#pragma once
typedef ULONGLONG QWORD;
const int BBP_RENDER = 1; // Render the scene.
const int BBP_CREATE = 2; // Retrieve Title, Name, Version, Render mode.
const int BBP_INIT = 3; // Init the OpenGL.
const int BBP_SIZE = 4; // The size of the control has changed.
const int BBP_KEYBOARD = 5; // All keyborad message.
const int BBP_MOUSE = 6; // All mouse messages.
const int BBP_DESTROY = 7; // Free Up resources.
const int BBP_NEWSOUND = 8; // We are playing a new sound file.
const int BBP_GDIPLUS = 0; // GDImage GDIPLUS compatible mode.
const int BBP_OPENGL = 1; // OpenGL mode.
const int BBP_DIRECTX = 2; // DirectX mode (for future extension).
const int BBP_SUCCESS = 0;
const int BBP_ERROR = -1;
typedef struct {
UINT msg; // The plugin's message (see above constant list).
HWND parent; // The parent window handle.
HDC dc; // The parent window DC (while in play mode).
HGLRC rc; // The parent OpenGL RC (while in play mode).
WORD lpeak; // The left audio channel peak value (while in play mode).
WORD rpeak; // The right audio channel peak value (while in play mode).
char title[32]; // Plugin's name or title.
char author[64]; // Plugin's author name.
DWORD version; // LOWRD major, HIWRD minor.
long renderto; // BBP_GDIPLUS, BBP_OPENGL, BBP_DIRECTX.
long backargb; // Default ARGB color background.
float* fftdata; // dword pointer to the FFT() as single array.
WORD fftsize; // Size of the FFT array.
UINT winmsg; // True Windows message.
WPARAM wparam; // wParam
LPARAM lparam; // lParam
short* wimdata; // dword pointer to the wave MM_WIM_DATA.
QWORD medialength; // Media length.
QWORD mediapos; // Media pos.
char reserved[50]; // Reserved for future extension.
} BBPLUGIN;
static FARPROC BBP_ProcHandle(IN FARPROC hProc, IN long RW) {
static FARPROC WasHproc;
if (RW) WasHproc = hProc;
return WasHproc;
}
static long BBP_Plugin(OUT BBPLUGIN &BBP) {
long nRet = BBP_ERROR;
if (IsWindow(gP.hGL)) {
HGLRC glRC = (HGLRC) (ZI_GetProperty(gP.hGL, ZI_GLRC));
if (glRC) {
long_proc (BBPLUGIN*);
zProc hProc = (zProc) BBP_ProcHandle(0, 0);
if (hProc) { nRet = hProc(&BBP); }
}
}
return nRet;
}
static WCHAR* BBP_ActivePlugin(IN WCHAR* sPluginName, IN long RW) {
static WCHAR sWasPluginName[MAX_PATH];
if (RW) { wcscopy(sWasPluginName, sPluginName); }
return sWasPluginName;
}
static void MarqueeUpdate() {
WCHAR drive[_MAX_DRIVE]; ClearMemory(drive, sizeof(drive));
WCHAR dir[_MAX_DIR]; ClearMemory(dir, sizeof(dir));
WCHAR fname[_MAX_FNAME]; ClearMemory(fname, sizeof(fname));
WCHAR ext[_MAX_EXT]; ClearMemory(ext, sizeof(ext));
wsplitpath(gB.audiofile, drive, dir, fname, ext);
ClearMemory(gP.plugintitle, sizeof(gP.plugintitle));
wcscopy(gP.plugintitle, gP.title, MAX_PATH * 2);
Add_Str(gP.plugintitle, gP.version);
Add_Str(gP.plugintitle, L" by "); Add_Str(gP.plugintitle, gP.author);
Add_Str(gP.plugintitle, L", playing \""); Add_Str(gP.plugintitle, fname); Add_Str(gP.plugintitle, ext); Add_Str(gP.plugintitle, L"\"");
ZD_SetObjectText(ID_COPYRIGHT, gP.plugintitle);
}
static void BBP_Reset() {
BBPLUGIN BBP; ClearMemory(&BBP, sizeof(BBP));
BBP.msg = BBP_CREATE;
BBP_Plugin(BBP);
ClearMemory(gP.title, sizeof(gP.title));
wcscopy(gP.title, cswconv(BBP.title), strSize(gP.title));// C string to WCHAR
ClearMemory(gP.author, sizeof(gP.author));
wcscopy(gP.author, cswconv(BBP.author), strSize(gP.author));// C string to WCHAR
BYTE majorVersion = (BYTE)(BBP.version & 0xFF);
BYTE minorVersion = (BYTE)((BBP.version >> 8) & 0xFF);
ClearMemory(gP.version, sizeof(gP.version));
swprintf(gP.version, strSize(gP.version), L" (%d.%d)", majorVersion, minorVersion);
MarqueeUpdate();
//BBProc(BBP);
if (BBP.renderto == BBP_OPENGL) {
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHT0);
glDisable(GL_LIGHT1);
glDisable(GL_LIGHT2);
glDisable(GL_LIGHT3);
glDisable(GL_LIGHT4);
glDisable(GL_LIGHT5);
glDisable(GL_LIGHT6);
glDisable(GL_LIGHT7);
glDisable(GL_LIGHTING);
glDisable(GL_COLOR_MATERIAL);
glDisable(GL_ALPHA_TEST);
glDisable(GL_NORMALIZE);
glDisable(GL_LINE_SMOOTH);
glGetError();
}
}
//long BBProc (OUT BBPLUGIN &BBP);
static void BBP_Detached(IN HWND hWnd, OUT HMODULE &hLib) {
BBPLUGIN BBP; ClearMemory(&BBP, sizeof(BBP));
if (hLib) {
BBP.msg = BBP_DESTROY;
BBP.parent = hWnd;
BBP_Plugin(BBP);
//BBProc(BBP);
// use brute force to delete any existing texture
long Tmax = 64;
long* DT = new long[Tmax]; memset(DT, 0, Tmax);
for (long K = 0; K < Tmax; K++) { DT[K] = K; }
glDeleteTextures(Tmax, (GLuint*)&DT[0]);
delete[] DT;
BBP_ProcHandle(0, 1); FreeLibrary(hLib); hLib = 0;
}
}
static void BBP_ResizeOpenGL() {
if (IsWindow(gP.hGL)) {
BBPLUGIN BBP; ClearMemory(&BBP, sizeof(BBP));
BBP.msg = BBP_SIZE;
BBP.parent = gP.hGL;
BBP_Plugin(BBP);
//BBProc(BBP);
}
}
// Load/unload plugin DLL to/from memory
static long BBP_LoadPlugin(IN HWND hWnd, IN WCHAR* zPlugin) {
long nDone = BBP_ERROR;
long nLen = lstrlen(zPlugin);
if ((nLen) && (_wcsicmp(zPlugin, BBP_ActivePlugin(0,0)) != 0)) {
if (FileExist(zPlugin)) {
if (gP.hLib) BBP_Detached(hWnd, gP.hLib);
gP.hLib = LoadLibrary(zPlugin);
if (gP.hLib) {
FARPROC hProc = GetProcAddress(gP.hLib, "BBProc");
if (hProc) {
BBP_ProcHandle(hProc, 1);
BBP_ActivePlugin(zPlugin, 1);
// Reset plugin to default
BBP_Reset();
nDone = BBP_SUCCESS;
}
}
}
} else if (nLen == 0) {
if (gP.hLib) BBP_Detached(hWnd, gP.hLib);
}
return nDone;
}
static long BBP_AttachPlugin(WCHAR* zPlugin) {
gP.pluginloaded = 0;
if (IsWindow(gP.hGL)) {
if (BBP_LoadPlugin(gP.hGL, zPlugin) == BBP_SUCCESS) {
gP.pluginloaded = -1;
BBPLUGIN BBP; ClearMemory(&BBP, sizeof(BBP));
BBP.msg = BBP_INIT;
BBP.parent = gP.hGL;
BBP.dc = (HDC) ZI_GetProperty(gP.hGL, ZI_GLDC);
BBP.rc = (HGLRC) ZI_GetProperty(gP.hGL, ZI_GLRC);
BBP.backargb = 0;
BBP_Plugin(BBP);
//if (IsWindowVisible(gP.hGL)) { SetMetadataText(ID_VIDEO_SIZE, gB.plugintitle); }
BBP.msg = BBP_SIZE;
BBP_Plugin(BBP);
wcscopy(gP.bin.lastplugin, zPlugin);
gP.pluginloaded = -1;
}
}
return gP.pluginloaded;
}
static void BBP_RenderOpenGL(IN DWORD nLevel, IN short* pInt) {
BBPLUGIN BBP; ClearMemory(&BBP, sizeof(BBP));
HDC glDC = (HDC) (ZI_GetProperty(gP.hGL, ZI_GLDC));
HGLRC glRC = (HGLRC) (ZI_GetProperty(gP.hGL, ZI_GLRC));
if (glRC) {
BBP.msg = BBP_RENDER;
BBP.parent = gP.hGL;
BBP.dc = glDC;
BBP.rc = glRC;
BBP.lpeak = SolvePeak(LOWORD(nLevel), 128);
BBP.rpeak = SolvePeak(HIWORD(nLevel), 128);
BBP.backargb = 0;
BBP.fftdata = (float*) BassChannelGetData();
BBP.fftsize = 256;
BBP.medialength = gB.medialength;
BBP.mediapos = gB.mediapos;
BBP.wimdata = pInt;
BBP_Plugin(BBP);
//BBProc(BBP);
// Refresh display
SwapBuffers(glDC);
InvalidateRect(gP.hGL, NULL, 0);
UpdateWindow(gP.hGL);
}
ReleaseDC(gP.hGL, glDC);
}
static void BBP_NewSound() {
BBPLUGIN BBP; ClearMemory(&BBP, sizeof(BBP));
BBP.msg = BBP_NEWSOUND;
BBP_Plugin(BBP);
}
If you are familiar with OpenGL programming, the VS2022 source code of each plugin is also attached in the Plugins_dll.7z
-
The whole project has been updated with new plugins.