ffgl-core 0.2.6

FFGL plugin framework
Documentation
#include <FFGL.h>
#include <FFGLLib.h>

#include "FFGLTile.h"

#define FFPARAM_TileX (0)
#define FFPARAM_TileY (1)

////////////////////////////////////////////////////////////////////////////////////////////////////
//  Plugin information
////////////////////////////////////////////////////////////////////////////////////////////////////

static CFFGLPluginInfo PluginInfo (
	FFGLTile::CreateInstance,	// Create method
	"GLTL",								// Plugin unique ID
	"FFGLTile",					// Plugin name
	1,									// API major version number
	000,								  // API minor version number
	1,										// Plugin major version number
	000,									// Plugin minor version number
	FF_EFFECT,						// Plugin type
	"Sample FFGL Tile plugin",	// Plugin description
	"by Edwin de Koning & Trey Harrison - www.resolume.com, www.harrisondigitalmedia.com" // About
);

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);"
"}";


////////////////////////////////////////////////////////////////////////////////////////////////////
//  Constructor and destructor
////////////////////////////////////////////////////////////////////////////////////////////////////

FFGLTile::FFGLTile()
:CFreeFrameGLPlugin(),
 m_initResources(1),
 m_inputTextureLocation(-1),
 m_maxCoordsLocation(-1),
 m_tileAmountLocation(-1)
{
	// Input properties
	SetMinInputs(1);
	SetMaxInputs(1);

	// Parameters
	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;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
//  Methods
////////////////////////////////////////////////////////////////////////////////////////////////////

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);

  //activate our shader
  m_shader.BindShader();

  //to assign values to parameters in the shader, we have to lookup
  //the "location" of each value.. then call one of the glUniform* methods
  //to assign a value
  m_inputTextureLocation = m_shader.FindUniform("inputTexture");
  m_maxCoordsLocation = m_shader.FindUniform("maxCoords");
  m_tileAmountLocation = m_shader.FindUniform("tileAmount");

  //the 0 means that the 'inputTexture' in
  //the shader will use the texture bound to GL texture unit 0
  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;

  //activate our shader
  m_shader.BindShader();

  FFGLTextureStruct &Texture = *(pGL->inputTextures[0]);

  //activate rendering with the input texture
  //note that when using shaders, no glEnable(Texture.Target) is required
  glBindTexture(GL_TEXTURE_2D, Texture.Handle);

  //get the max s,t that correspond to the
  //width,height of the used portion of the allocated texture space
  FFGLTexCoords maxCoords = GetMaxGLTexCoords(Texture);

  //assign the maxCoords value in the shader
  //(glUniform2f assigns to a vec2)
  m_extensions.glUniform2fARB(m_maxCoordsLocation, maxCoords.s, maxCoords.t);

  //assign the tileAmount
  m_extensions.glUniform2fARB(m_tileAmountLocation, 20.0*m_TileX, 20.0*m_TileY);
  
  //draw the quad that will be painted by the shader/texture
  glBegin(GL_QUADS);

  //lower left
  glTexCoord2f(0,0);
  glVertex2f(-1,-1);

  //upper left
  glTexCoord2f(0, maxCoords.t);
  glVertex2f(-1,1);

  //upper right
  glTexCoord2f(maxCoords.s, maxCoords.t);
  glVertex2f(1,1);

  //lower right
  glTexCoord2f(maxCoords.s, 0);
  glVertex2f(1,-1);
  glEnd();

  //unbind the shader and texture
  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;
}