#include <FFGL.h>
#include <FFGLLib.h>
#include "FFGLTile.h"
#define FFPARAM_TileX (0)
#define FFPARAM_TileY (1)
static CFFGLPluginInfo PluginInfo (
FFGLTile::CreateInstance, "GLTL", "FFGLTile", 1, 000, 1, 000, FF_EFFECT, "Sample FFGL Tile plugin", "by Edwin de Koning & Trey Harrison - www.resolume.com, www.harrisondigitalmedia.com" );
char *vertexShaderCode =
"void main()"
"{"
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;"
" gl_TexCoord[0] = gl_MultiTexCoord0;"
" gl_FrontColor = gl_Color;"
"}";
char *fragmentShaderCode =
"uniform sampler2D inputTexture;"
"uniform vec2 maxCoords;"
"uniform vec2 tileAmount;"
"void main(void)"
"{"
" vec2 texCoord = mod(tileAmount*gl_TexCoord[0].xy,maxCoords);"
" gl_FragColor = texture2D(inputTexture, texCoord);"
"}";
FFGLTile::FFGLTile()
:CFreeFrameGLPlugin(),
m_initResources(1),
m_inputTextureLocation(-1),
m_maxCoordsLocation(-1),
m_tileAmountLocation(-1)
{
SetMinInputs(1);
SetMaxInputs(1);
SetParamInfo(FFPARAM_TileX, "TileX", FF_TYPE_STANDARD, 0.5f);
m_TileX = 0.5f;
SetParamInfo(FFPARAM_TileY, "TileY", FF_TYPE_STANDARD, 0.5f);
m_TileY = 0.5f;
}
DWORD FFGLTile::InitGL(const FFGLViewportStruct *vp)
{
m_extensions.Initialize();
if (m_extensions.ARB_shader_objects==0)
return FF_FAIL;
m_shader.SetExtensions(&m_extensions);
m_shader.Compile(vertexShaderCode,fragmentShaderCode);
m_shader.BindShader();
m_inputTextureLocation = m_shader.FindUniform("inputTexture");
m_maxCoordsLocation = m_shader.FindUniform("maxCoords");
m_tileAmountLocation = m_shader.FindUniform("tileAmount");
m_extensions.glUniform1iARB(m_inputTextureLocation, 0);
m_shader.UnbindShader();
return FF_SUCCESS;
}
DWORD FFGLTile::DeInitGL()
{
m_shader.FreeGLResources();
return FF_SUCCESS;
}
DWORD FFGLTile::ProcessOpenGL(ProcessOpenGLStruct *pGL)
{
if (pGL->numInputTextures<1)
return FF_FAIL;
if (pGL->inputTextures[0]==NULL)
return FF_FAIL;
m_shader.BindShader();
FFGLTextureStruct &Texture = *(pGL->inputTextures[0]);
glBindTexture(GL_TEXTURE_2D, Texture.Handle);
FFGLTexCoords maxCoords = GetMaxGLTexCoords(Texture);
m_extensions.glUniform2fARB(m_maxCoordsLocation, maxCoords.s, maxCoords.t);
m_extensions.glUniform2fARB(m_tileAmountLocation, 20.0*m_TileX, 20.0*m_TileY);
glBegin(GL_QUADS);
glTexCoord2f(0,0);
glVertex2f(-1,-1);
glTexCoord2f(0, maxCoords.t);
glVertex2f(-1,1);
glTexCoord2f(maxCoords.s, maxCoords.t);
glVertex2f(1,1);
glTexCoord2f(maxCoords.s, 0);
glVertex2f(1,-1);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
m_shader.UnbindShader();
return FF_SUCCESS;
}
DWORD FFGLTile::GetParameter(DWORD dwIndex)
{
DWORD dwRet;
switch (dwIndex) {
case FFPARAM_TileX:
*((float *)(unsigned)&dwRet) = m_TileX;
return dwRet;
case FFPARAM_TileY:
*((float *)(unsigned)&dwRet) = m_TileY;
return dwRet;
default:
return FF_FAIL;
}
}
DWORD FFGLTile::SetParameter(const SetParameterStruct* pParam)
{
if (pParam != NULL) {
switch (pParam->ParameterNumber) {
case FFPARAM_TileX:
m_TileX = *((float *)(unsigned)&(pParam->NewParameterValue));
break;
case FFPARAM_TileY:
m_TileY = *((float *)(unsigned)&(pParam->NewParameterValue));
break;
default:
return FF_FAIL;
}
return FF_SUCCESS;
}
return FF_FAIL;
}