#include <math.h>
#include <GL/glut.h>
#include "FFGLFBO.h"
#include "../FFDebugMessage.h"
#include "../FFGLPluginInstance.h"
#include "../Timer.h"
int WINDOWWIDTH = 640;
int WINDOWHEIGHT = 480;
FFGLPluginInstance *plugin1 = NULL;
FFGLPluginInstance *plugin2 = NULL;
const char *FFGLBrightnessFile = "../../FFGLPlugins/Linux/FFGLBrightness.so";
const char *FFGLLumaKeyFile = "../../FFGLPlugins/Linux/FFGLLumaKey.so";
const char *FFGLTileFile = "../../FFGLPlugins/Linux/FFGLTile.so";
const char *FFGLHeatFile = "../../FFGLPlugins/Linux/FFGLHeat.so";
unsigned char *inputImage = NULL;
FFGLTextureStruct inputTexture;
void AllocateInputTexture(int textureWidth, int textureHeight);
void UpdateInputTexture(double time);
FFGLExtensions glExtensions;
FFGLFBO fbo;
Timer *timer = NULL;
void FFGLHostDisplay();
void FFGLHostReshape(int width, int height);
void FFGLHostMouseMove(int x, int y);
float mouseX = 0.5;
float mouseY = 0.5;
int main(int argc, char **argv)
{
plugin1 = FFGLPluginInstance::New();
if (plugin1->Load(FFGLBrightnessFile)==FF_FAIL)
{
FFDebugMessage("Couldn't open plugin 1");
return 0;
}
plugin2 = FFGLPluginInstance::New();
if (plugin2->Load(FFGLTileFile)==FF_FAIL)
{
FFDebugMessage("Couldn't open plugin 2");
return 0;
}
glutInit(&argc, argv);
glutInitWindowSize(WINDOWWIDTH, WINDOWHEIGHT);
glutInitDisplayString("double rgb depth");
glutCreateWindow("FFGLHost");
glutReshapeFunc(FFGLHostReshape);
glutPassiveMotionFunc(FFGLHostMouseMove);
AllocateInputTexture(320,240);
if (inputTexture.Handle==0 || inputImage==NULL)
{
FFDebugMessage("Texture allocation failed");
return 0;
}
glExtensions.Initialize();
if (glExtensions.EXT_framebuffer_object==0)
{
FFDebugMessage("FBO not detected, cannot continue");
return 0;
}
if (!fbo.Create(WINDOWWIDTH, WINDOWHEIGHT, glExtensions))
{
FFDebugMessage("Framebuffer Object Init Failed");
return 0;
}
glutDisplayFunc(FFGLHostDisplay);
timer = Timer::New();
glutMainLoop();
plugin1->Unload();
delete plugin1;
plugin2->Unload();
delete plugin2;
delete [] inputImage;
delete timer;
return 0;
}
void FFGLHostDisplay()
{
double curFrameTime = timer->GetElapsedTime();
UpdateInputTexture(curFrameTime);
if (!fbo.BindAsRenderTarget(glExtensions))
{
FFDebugMessage("FBO Bind As Render Target Failed");
return;
}
glViewport(0,0, fbo.GetWidth(), fbo.GetHeight());
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->SetFloatParameter(0, mouseX);
ProcessOpenGLStructTag processStruct;
processStruct.numInputTextures = 1;
FFGLTextureStruct *inputTextures[1];
inputTextures[0] = &inputTexture;
processStruct.inputTextures = inputTextures;
if (plugin1->CallProcessOpenGL(processStruct)==FF_SUCCESS)
{
}
else
{
FFDebugMessage("Plugin 1's ProcessOpenGL failed");
return;
}
fbo.UnbindAsRenderTarget(glExtensions);
glViewport(0, 0, WINDOWWIDTH, WINDOWHEIGHT);
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;
plugin2->SetFloatParameter(0, mouseY);
if (plugin2->CallProcessOpenGL(processStruct)==FF_SUCCESS)
{
}
else
{
FFDebugMessage("Plugin 2's ProcessOpenGL failed");
}
glutSwapBuffers();
glutPostRedisplay();
}
void FFGLHostMouseMove(int x, int y)
{
if (x<0) x=0;
else
if (x>WINDOWWIDTH) x = WINDOWWIDTH;
if (y<0) y = 0;
else
if (y>WINDOWHEIGHT) y = WINDOWHEIGHT;
mouseX = ((double)x) / (double)WINDOWWIDTH;
mouseY = 1.0 - ((double)y) / (double)WINDOWHEIGHT;
}
void FFGLHostReshape(int width, int height)
{
WINDOWWIDTH = width;
WINDOWHEIGHT = height;
glViewport(0, 0, width, height);
}
void UpdateInputTexture(double timeInSeconds)
{
int time = (int)(timeInSeconds*160.0);
unsigned char *p = inputImage;
for (unsigned y=0; y<inputTexture.Height; y++)
{
for (unsigned x=0; x<inputTexture.Width; x++)
{
int r = ((x^(y+time)) & 0xFF);
int g = (((x+time)^y) & 0xFF);
int b = ((x^y) & 0xFF);
*p = b;
*(p+1) = g;
*(p+2) = r;
p += 4;
}
}
glBindTexture(inputTexture.Target, inputTexture.Handle);
glTexSubImage2D(
inputTexture.Target,
0,
0, 0,
inputTexture.Width,
inputTexture.Height,
GL_RGBA,
GL_UNSIGNED_BYTE,
inputImage);
glBindTexture(inputTexture.Target, 0);
}
void AllocateInputTexture(int textureWidth, int textureHeight)
{
inputImage = new unsigned char[textureWidth*textureHeight*4];
if (inputImage==NULL)
return;
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, 4, glTextureWidth,
glTextureHeight,
0, GL_RGBA,
GL_UNSIGNED_BYTE,
NULL);
glBindTexture(GL_TEXTURE_2D, 0);
FFGLTextureStruct &t = inputTexture;
t.Handle = glTextureHandle;
t.Target = GL_TEXTURE_2D;
t.Width = textureWidth;
t.Height = textureHeight;
t.HardwareWidth = glTextureWidth;
t.HardwareHeight = glTextureHeight;
t.Depth = 1;
t.HardwareDepth = 1;
}