#include <FFGLFBO.h>
#include "../FFGLPluginInstance.h"
#include "../Timer.h"
#include "../FFDebugMessage.h"
#include "AVIReader.h"
#include <math.h>
HINSTANCE g_hinst; HWND g_hwnd; HGLRC g_glrc;
int g_wantToClose = 0;
float mouseX = 0.5;
float mouseY = 0.5;
BOOL CreateOpenGLWindow();
FFGLTextureStruct CreateOpenGLTexture(int textureWidth, int textureHeight);
#ifdef _DEBUG
const char *FFGLBrightnessFile = "FFGLBrightness_debug.dll";
const char *FFGLMirrorFile = "FFGLMirror_debug.dll";
const char *FFGLTileFile = "FFGLTile_debug.dll";
const char *FFGLHeatFile = "FFGLHeat_debug.dll";
const char *FFGLLumaKeyFile = "FFGLLumaKey_debug.dll";
#else
const char *FFGLBrightnessFile = "FFGLBrightness.dll";
const char *FFGLMirrorFile = "FFGLMirror.dll";
const char *FFGLTileFile = "FFGLTile.dll";
const char *FFGLHeatFile = "FFGLHeat.dll";
const char *FFGLLumaKeyFile = "FFGLLumaKey.dll";
#endif
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
g_hinst = hInstance;
WORD wVer = HIWORD(VideoForWindowsVersion());
if (wVer>=0x010A)
AVIFileInit();
else
return 0;
Win32AVIFile aviFile;
if (!aviFile.LoadAVI("FFGLTest.avi"))
{
FFDebugMessage("AVI Init Failed");
return 0;
}
const char *pluginFile1 = FFGLBrightnessFile;
const char *pluginFile2 = FFGLTileFile;
int usingCustomPlugin = 0;
if (szCmdLine!=NULL && szCmdLine[0]!=0 &&
strstr(szCmdLine,".dll")!=NULL)
{
if (szCmdLine[0]=='"')
szCmdLine++;
if (szCmdLine[strlen(szCmdLine)-1]=='"')
szCmdLine[strlen(szCmdLine)-1] = 0;
pluginFile2 = szCmdLine;
usingCustomPlugin = 1;
}
FFGLPluginInstance *plugin1 = FFGLPluginInstance::New();
if (plugin1->Load(pluginFile1)==FF_FAIL)
{
FFDebugMessage("Couldn't open Brightness plugin .dll");
return 0;
}
FFGLPluginInstance *plugin2 = FFGLPluginInstance::New();
if (plugin2->Load(pluginFile2)==FF_FAIL)
{
FFDebugMessage("Couldn't open plugin .dll #2");
return 0;
}
if (!CreateOpenGLWindow())
{
FFDebugMessage("Window Open Failed");
return 0;
}
HDC hdc = GetDC(g_hwnd);
wglMakeCurrent(hdc, g_glrc);
FFGLExtensions glExtensions;
glExtensions.Initialize();
if (glExtensions.EXT_framebuffer_object==0)
{
FFDebugMessage("FBO not detected, cannot continue");
return 0;
}
if (glExtensions.WGL_EXT_swap_control)
glExtensions.wglSwapIntervalEXT(1);
RECT clientRect;
GetClientRect(g_hwnd, &clientRect);
int fboWidth = clientRect.right - clientRect.left;
int fboHeight = clientRect.bottom - clientRect.top;
FFGLFBO fbo;
if (!fbo.Create(fboWidth, fboHeight, glExtensions))
{
FFDebugMessage("Framebuffer Object Init Failed");
return 0;
}
FFGLViewportStruct fboViewport;
fboViewport.x = 0;
fboViewport.y = 0;
fboViewport.width = fboWidth;
fboViewport.height = fboHeight;
if (plugin1->InstantiateGL(&fboViewport)!=FF_SUCCESS)
{
FFDebugMessage("Plugin1 instantiate failed");
return 0;
}
FFGLViewportStruct windowViewport;
windowViewport.x = 0;
windowViewport.y = 0;
windowViewport.width = clientRect.right - clientRect.left;
windowViewport.height = clientRect.bottom - clientRect.top;
if (plugin2->InstantiateGL(&windowViewport)!=FF_SUCCESS)
{
FFDebugMessage("Plugin2 instantiate failed");
return 0;
}
FFGLTextureStruct aviTexture;
aviTexture = CreateOpenGLTexture(aviFile.GetWidth(),aviFile.GetHeight());
if (aviTexture.Handle==0)
{
FFDebugMessage("Texture allocation failed");
return 0;
}
wglMakeCurrent(NULL,NULL);
ReleaseDC(g_hwnd, hdc);
int keepRunning = 1;
Timer *time = Timer::New();
while (keepRunning)
{
if (g_hwnd!=NULL && g_glrc!=NULL)
{
HDC hdc = GetDC(g_hwnd);
wglMakeCurrent(hdc, g_glrc);
double curFrameTime = time->GetElapsedTime();
int curFrame = (int)(curFrameTime * aviFile.GetFramerate());
void *bitmapData = aviFile.GetFrameData(curFrame);
glBindTexture(GL_TEXTURE_2D, aviTexture.Handle);
glTexSubImage2D(GL_TEXTURE_2D, 0,
0, 0,
aviFile.GetWidth(),
aviFile.GetHeight(),
GL_BGR_EXT,
GL_UNSIGNED_BYTE,
bitmapData);
glBindTexture(GL_TEXTURE_2D, 0);
if (!fbo.BindAsRenderTarget(glExtensions))
{
FFDebugMessage("FBO Bind As Render Target Failed");
return 0;
}
glViewport(
fboViewport.x,
fboViewport.y,
fboViewport.width,
fboViewport.height);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0,0,0,0);
glClearDepth(1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
plugin1->SetTime(curFrameTime);
plugin1->SetFloatParameter(0, mouseX);
ProcessOpenGLStructTag processStruct;
FFGLTextureStruct *inputTextures[1];
inputTextures[0] = &aviTexture;
processStruct.numInputTextures = 1;
processStruct.inputTextures = inputTextures;
processStruct.HostFBO = fbo.GetFBOHandle();
if (plugin1->CallProcessOpenGL(processStruct)==FF_SUCCESS)
{
}
else
{
FFDebugMessage("Plugin 1's ProcessOpenGL failed");
return 0;
}
fbo.UnbindAsRenderTarget(glExtensions);
glViewport(
windowViewport.x,
windowViewport.y,
windowViewport.width,
windowViewport.height);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0,0,0,0);
glClearDepth(1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
FFGLTextureStruct fboTexture = fbo.GetTextureInfo();
inputTextures[0] = &fboTexture;
processStruct.HostFBO = 0;
plugin2->SetTime(curFrameTime);
plugin2->SetFloatParameter(0, mouseY);
if (plugin2->CallProcessOpenGL(processStruct)==FF_SUCCESS)
{
}
else
{
FFDebugMessage("Plugin 2's ProcessOpenGL failed");
return 0;
}
SwapBuffers(hdc);
if (g_wantToClose==1)
{
plugin1->DeInstantiateGL();
plugin2->DeInstantiateGL();
fbo.FreeResources(glExtensions);
glDeleteTextures(1,&aviTexture.Handle);
}
wglMakeCurrent(NULL,NULL);
ReleaseDC(g_hwnd, hdc);
}
if (g_hwnd!=NULL && g_wantToClose==1)
{
DestroyWindow(g_hwnd);
g_hwnd = NULL;
}
MSG msg;
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
if (msg.message != WM_QUIT &&
msg.message != WM_NULL)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
keepRunning = 0;
break;
}
}
}
wglDeleteContext(g_glrc);
aviFile.ReleaseAVI();
plugin1->Unload();
delete plugin1;
plugin2->Unload();
delete plugin2;
delete time;
AVIFileExit();
return 0;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
RECT r;
signed short mx,my;
switch (message)
{
case WM_PAINT:
GetUpdateRect(hWnd, &r, 0);
ValidateRect(hWnd, NULL);
break;
case WM_CLOSE:
g_wantToClose = 1;
return 0;
case WM_MOUSEMOVE:
mx = LOWORD(lParam);
my = HIWORD(lParam);
GetClientRect(hWnd, &r);
if (mx<r.left) mx=r.left;
else
if (mx>r.right) mx = r.right;
if (my<r.top) my=r.top;
else
if (my>r.bottom) mx = r.bottom;
mouseX = (double)(mx - r.left) / (double)((r.right - r.left)-1);
mouseY = 1.0 - ((double)(my - r.top) / (double)((r.bottom - r.top)-1));
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
void RegisterOpenGLWindowClass()
{
static int alreadyRegistered = 0;
if (alreadyRegistered)
return;
else
alreadyRegistered = 1;
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_OWNDC;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = g_hinst;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL,IDC_ARROW);
wcex.hbrBackground = NULL;
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "FFGLHostWindowClass";
wcex.hIconSm = NULL;
RegisterClassEx(&wcex);
}
BOOL CreateOpenGLWindow()
{
RegisterOpenGLWindowClass();
DWORD winFlags = WS_CAPTION | WS_SYSMENU | WS_DLGFRAME;
g_hwnd = CreateWindow("FFGLHostWindowClass", "FFGL Host Sample", winFlags,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, g_hinst, NULL);
if (!g_hwnd)
return FALSE;
HDC hdc = GetDC(g_hwnd);
int hdc_bpp = GetDeviceCaps(hdc, BITSPIXEL);
int zBufferDepth = 16;
PIXELFORMATDESCRIPTOR pfd;
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DOUBLEBUFFER |
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = hdc_bpp;
pfd.cDepthBits = zBufferDepth;
pfd.cAccumBits = 0;
pfd.cStencilBits = 0;
pfd.iLayerType = PFD_MAIN_PLANE;
if (hdc_bpp==32)
pfd.cAlphaBits = 8;
else
pfd.cAlphaBits = 0;
int iPixelFormat = ChoosePixelFormat(hdc, &pfd);
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
if (DescribePixelFormat(hdc,
iPixelFormat,
sizeof(PIXELFORMATDESCRIPTOR),
&pfd))
{
if ((pfd.dwFlags & PFD_SUPPORT_OPENGL)==0)
{
FFDebugMessage("Can't support OpenGL");
return FALSE;
}
}
DWORD result = SetPixelFormat(hdc, iPixelFormat, &pfd);
if (!result)
return FALSE;
g_glrc = wglCreateContext(hdc);
if (g_glrc==NULL)
return FALSE;
ReleaseDC(g_hwnd,hdc);
ShowWindow(g_hwnd, SW_SHOWNORMAL);
UpdateWindow(g_hwnd);
return TRUE;
}
FFGLTextureStruct CreateOpenGLTexture(int textureWidth, int textureHeight)
{
int glTextureWidth = 1;
while (glTextureWidth<textureWidth) glTextureWidth *= 2;
int glTextureHeight = 1;
while (glTextureHeight<textureHeight) glTextureHeight *= 2;
GLuint glTextureHandle = 0;
glGenTextures(1, &glTextureHandle);
glBindTexture(GL_TEXTURE_2D, glTextureHandle);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D,
0, 3, glTextureWidth,
glTextureHeight,
0, GL_BGR_EXT,
GL_UNSIGNED_BYTE,
NULL);
glBindTexture(GL_TEXTURE_2D, 0);
FFGLTextureStruct t;
t.Handle = glTextureHandle;
t.Width = textureWidth;
t.Height = textureHeight;
t.HardwareWidth = glTextureWidth;
t.HardwareHeight = glTextureHeight;
return t;
}