RemoteSensingFrank/UAVProduct

View on GitHub
UAVProduct/SiftGPU/ShaderMan.cpp

Summary

Maintainability
Test Coverage
////////////////////////////////////////////////////////////////////////////
//    File:        ShaderMan.cpp
//    Author:        Changchang Wu
//    Description :    implementation of the ShaderMan class.
//                A Shader Manager that calls different implementation of shaders
//
//
//    Copyright (c) 2007 University of North Carolina at Chapel Hill
//    All Rights Reserved
//
//    Permission to use, copy, modify and distribute this software and its
//    documentation for educational, research and non-profit purposes, without
//    fee, and without a written agreement is hereby granted, provided that the
//    above copyright notice and the following paragraph appear in all copies.
//    
//    The University of North Carolina at Chapel Hill make no representations
//    about the suitability of this software for any purpose. It is provided
//    'as is' without express or implied warranty. 
//
//    Please send BUG REPORTS to ccwu@cs.unc.edu
//
////////////////////////////////////////////////////////////////////////////


#include "GL/glew.h"
#include <vector>
#include <iostream>
#include <stdlib.h>
#include <math.h>
using std::vector;
using std::ostream;
using std::endl;


#include "ProgramGLSL.h"
#include "GlobalUtil.h"
#include "GLTexImage.h"
#include "SiftGPU.h"
#include "ShaderMan.h"

///
ShaderBag   * ShaderMan::s_bag = NULL;

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

void ShaderMan::InitShaderMan(SiftParam&param)
{
    if(s_bag) return;

    if(GlobalUtil::_usePackedTex )    s_bag = new ShaderBagPKSL;
    else                            s_bag =new ShaderBagGLSL;    

    GlobalUtil::StartTimer("Load Programs");
    s_bag->LoadFixedShaders();
    s_bag->LoadDynamicShaders(param);
    if(GlobalUtil::_UseSiftGPUEX)     s_bag->LoadDisplayShaders();
    GlobalUtil::StopTimer();

    GlobalUtil::CheckErrorsGL("InitShaderMan");
}


void ShaderMan::DestroyShaders()
{
    if(s_bag) delete s_bag;
    s_bag   =   NULL; 
}

void ShaderMan::UnloadProgram()
{
    if(s_bag) s_bag->UnloadProgram();
}

void ShaderMan::FilterImage(FilterProgram* filter, GLTexImage *dst, GLTexImage *src, GLTexImage*tmp)
{
    if(filter == NULL) return; 

    //////////////////////////////
    src->FillMargin(filter->_size, 0);

    //output parameter
    if(tmp) tmp->AttachToFBO(0);
    else dst->AttachToFBO(0);


    //input parameter
    src->BindTex();
    dst->FitTexViewPort();

    //horizontal filter
    filter->s_shader_h->UseProgram();
    dst->DrawQuad();

    //parameters
    if(tmp)
    {
        // fill margin for out-of-boundary lookup
        tmp->DetachFBO(0);
        tmp->AttachToFBO(0);
        tmp->FillMargin(0, filter->_size);
        tmp->DetachFBO(0);
        dst->AttachToFBO(0);
        tmp->BindTex();
    }
    else
    {
        glFinish();
        // fill margin for out-of-boundary lookup
        dst->FillMargin(0, filter->_size);
        dst->BindTex();
    }

    //vertical filter
    filter->s_shader_v->UseProgram();
    dst->DrawQuad();


    //clean up
    dst->UnbindTex();
    dst->DetachFBO(0);

    //
    ShaderMan::UnloadProgram();
}


void ShaderMan::FilterInitialImage(GLTexImage* tex, GLTexImage* buf)
{
    if(s_bag->f_gaussian_skip0) FilterImage(s_bag->f_gaussian_skip0, tex, tex, buf);
}

void ShaderMan::FilterSampledImage(GLTexImage* tex, GLTexImage* buf)
{
    if(s_bag->f_gaussian_skip1) FilterImage(s_bag->f_gaussian_skip1, tex, tex, buf);
}

void ShaderMan::TextureCopy(GLTexImage*dst, GLTexImage*src)
{

    dst->AttachToFBO(0);

    src->BindTex();

    dst->FitTexViewPort();

    dst->DrawQuad();

    dst->UnbindTex();
//    ShaderMan::UnloadProgram();
    dst->DetachFBO(0);
    return;
}
void ShaderMan::TextureDownSample(GLTexImage *dst, GLTexImage *src, int scale)
{
    //output parameter
    
    dst->AttachToFBO(0);

    //input parameter
    src->BindTex();

    //
    dst->FitTexViewPort();

    s_bag->s_sampling->UseProgram();

    dst->DrawQuadDS(scale);
    src->UnbindTex();

    UnloadProgram();

    dst->DetachFBO(0); 
}

void ShaderMan::TextureUpSample(GLTexImage *dst, GLTexImage *src, int scale)
{

    //output parameter
    dst->AttachToFBO(0);
    //input parameter
    src->BindTex();

    dst->FitTexViewPort();

    GlobalUtil::SetTextureParameterUS();

    if(GlobalUtil::_usePackedTex)
    {
        s_bag->s_sampling->UseProgram();
    }

    dst->DrawQuadUS(scale);
    src->UnbindTex();

    UnloadProgram();

    dst->DetachFBO(0);

    GlobalUtil::SetTextureParameter();
}



void ShaderMan::UseShaderDisplayGaussian()
{
    if(s_bag && s_bag->s_display_gaussian) s_bag->s_display_gaussian->UseProgram();
}

void ShaderMan::UseShaderDisplayDOG()
{
    if(s_bag && s_bag->s_display_dog) s_bag->s_display_dog->UseProgram();
}



void ShaderMan::UseShaderRGB2Gray()
{
    if(s_bag && s_bag->s_gray)s_bag->s_gray->UseProgram();
}


void ShaderMan::UseShaderDisplayGrad()
{
    if(s_bag && s_bag->s_display_grad) s_bag->s_display_grad->UseProgram();
}


void ShaderMan::UseShaderDisplayKeypoints()
{
    if(s_bag && s_bag->s_display_keys) s_bag->s_display_keys->UseProgram();
}





void ShaderMan::UseShaderGradientPass(int texP)
{
    s_bag->s_grad_pass->UseProgram();
    s_bag->SetGradPassParam(texP);    
}


void ShaderMan::UseShaderKeypoint(int texU, int texD)
{
    s_bag->s_keypoint->UseProgram();
    s_bag->SetDogTexParam(texU, texD);
}



void ShaderMan::UseShaderGenListInit(int w, int h, int tight)
{
    if(tight)
    {
        s_bag->s_genlist_init_tight->UseProgram();
    }else
    {
        s_bag->s_genlist_init_ex->UseProgram();
        s_bag->SetGenListInitParam(w, h);
    }
}

void ShaderMan::UseShaderGenListHisto()
{
    s_bag->s_genlist_histo->UseProgram();

}




void ShaderMan::UseShaderGenListStart(float fw, int tex0)
{
    s_bag->s_genlist_start->UseProgram();
    s_bag->SetGenListStartParam(fw, tex0);
}

void ShaderMan::UseShaderGenListStep(int tex, int tex0)
{
    s_bag->s_genlist_step->UseProgram();
    s_bag->SetGenListStepParam( tex,  tex0);
}

void ShaderMan::UseShaderGenListEnd(int ktex)
{
    s_bag->s_genlist_end->UseProgram();
    s_bag->SetGenListEndParam(ktex);
}

void ShaderMan::UseShaderDebug()
{
    if(s_bag->s_debug)    s_bag->s_debug->UseProgram();
}

void ShaderMan::UseShaderZeroPass()
{
    if(s_bag->s_zero_pass) s_bag->s_zero_pass->UseProgram();
}

void ShaderMan::UseShaderGenVBO( float width, float fwidth, float size)
{
    s_bag->s_vertex_list->UseProgram();
    s_bag->SetGenVBOParam(width, fwidth, size);
}
void ShaderMan::UseShaderMarginCopy(int xmax, int ymax)
{
    s_bag->s_margin_copy->UseProgram();
    s_bag->SetMarginCopyParam(xmax, ymax);
    
}
void ShaderMan::UseShaderCopyKeypoint()
{
    s_bag->s_copy_key->UseProgram();
}

void ShaderMan::UseShaderSimpleOrientation(int oTex, float sigma, float sigma_step)
{
    s_bag->s_orientation->UseProgram();
    s_bag->SetSimpleOrientationInput(oTex, sigma, sigma_step);
}



void ShaderMan::UseShaderOrientation(int gtex, int width, int height, float sigma, int auxtex, float step, int keypoint_list)
{
    s_bag->s_orientation->UseProgram();

    //changes in v345. 
    //set sigma to 0 to identify keypoit list mode
    //set sigma to negative to identify fixed_orientation
    if(keypoint_list) sigma = 0.0f;
    else if(GlobalUtil::_FixedOrientation) sigma = - sigma;

    s_bag->SetFeatureOrientationParam(gtex, width, height, sigma, auxtex, step);
}

void ShaderMan::UseShaderDescriptor(int gtex, int otex, int dwidth, int fwidth,  int width, int height, float sigma)
{
    s_bag->s_descriptor_fp->UseProgram();
    s_bag->SetFeatureDescirptorParam(gtex, otex, (float)dwidth,  (float)fwidth, (float)width, (float)height, sigma);
}

void ShaderMan::SelectInitialSmoothingFilter(int octave_min, SiftParam&param)
{
    s_bag->SelectInitialSmoothingFilter(octave_min, param);
}