⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 programglsl.cpp

📁 SiftGPU is an implementation of SIFT [1] for GPU. SiftGPU processes pixels parallely to build Gaussi
💻 CPP
📖 第 1 页 / 共 5 页
字号:
////////////////////////////////////////////////////////////////////////////
//	File:		ProgramGLSL.cpp
//	Author:		Changchang Wu
//	Description : GLSL related classes
//		class ProgramGLSL		A simple wrapper of GLSL programs
//		class ShaderBagGLSL		GLSL shaders for SIFT
//		class FilterGLSL		GLSL gaussian filters for SIFT
//
//	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 <iomanip>
#include <iostream>
#include <strstream>
#include <vector>
#include <algorithm>
#include <math.h>
using namespace std;

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

ProgramGLSL::ShaderObject::ShaderObject(int shadertype, const char * source, int filesource)
{


	_type = shadertype; 
	_compiled = 0;


	_shaderID = glCreateShader(shadertype);
	if(_shaderID == 0) return;
	
	if(source)
	{

		GLint				code_length;
		if(filesource ==0)
		{
			const char* code  = source;
			code_length = strlen(code);
			glShaderSource(_shaderID, 1, (const char **) &code, &code_length);
		}else
		{
			char * code;
			if((code_length= ReadShaderFile(source, code)) ==0) return;
			glShaderSource(_shaderID, 1, (const char **) &code, &code_length);
			delete code;
		}

		glCompileShader(_shaderID);

		CheckCompileLog();

		if(!_compiled) 		std::cout << source;
	}




}

int ProgramGLSL::ShaderObject::ReadShaderFile(const char *sourcefile,  char*& code )
{
	code = NULL;
	FILE * file;
	int    len=0;

	if(sourcefile == NULL) return 0;

	file = fopen(sourcefile,"rt");
	if(file == NULL) return 0;

	
	fseek(file, 0, SEEK_END);
	len = ftell(file);
	rewind(file);
	if(len >1)
	{
		code = new  char[len+1];
		fread(code, sizeof( char), len, file);
		code[len] = 0;
	}else
	{
		len = 0;
	}

	fclose(file);

	return len;
	
}

void ProgramGLSL::ShaderObject::CheckCompileLog()
{

	GLint status;
	glGetShaderiv(_shaderID, GL_COMPILE_STATUS, &status);
	_compiled = (status ==GL_TRUE);

	if(_compiled == 0)	PrintCompileLog(std::cout);


}

ProgramGLSL::ShaderObject::~ShaderObject()
{
	if(_shaderID)	glDeleteShader(_shaderID);

}

int ProgramGLSL::ShaderObject::IsValidFragmentShader()
{
	return _type == GL_FRAGMENT_SHADER && _shaderID && _compiled;
}

int  ProgramGLSL::ShaderObject::IsValidVertexShader()
{
	return _type == GL_VERTEX_SHADER && _shaderID && _compiled;
}


void ProgramGLSL::ShaderObject::PrintCompileLog(ostream&os)
{
	GLint len = 0;	

	glGetShaderiv(_shaderID, GL_INFO_LOG_LENGTH , &len);
	if(len <=1) return;
	
	char * compileLog = new char[len+1];
	if(compileLog == NULL) return;

	glGetShaderInfoLog(_shaderID, len, &len, compileLog);
	

	os<<"Compile Log\n"<<compileLog<<"\n";

	delete compileLog;
}


ProgramGLSL::ProgramGLSL()
{
	_linked = 0;
	_programID = glCreateProgram();
}
ProgramGLSL::~ProgramGLSL()
{
	if(_programID)glDeleteProgram(_programID);
}
void ProgramGLSL::AttachShaderObject(ShaderObject &shader)
{
	if(_programID  && shader.IsValidShaderObject()) 
		glAttachShader(_programID, shader.GetShaderID());
}
void ProgramGLSL::DetachShaderObject(ShaderObject &shader)
{
	if(_programID  && shader.IsValidShaderObject()) 
		glDetachShader(_programID, shader.GetShaderID());
}
int ProgramGLSL::LinkProgram()
{
	_linked = 0;

	if(_programID==0) return 0;

	glLinkProgram(_programID);

	CheckLinkLog();

//	GlobalUtil::StartTimer("100 link test");
//	for(int i = 0; i<100; i++) glLinkProgram(_programID);
//	GlobalUtil::StopTimer();

	return _linked;
}

void ProgramGLSL::CheckLinkLog()
{
	GLint status;
	glGetProgramiv(_programID, GL_LINK_STATUS, &status);

	_linked = (status == GL_TRUE);

}


int ProgramGLSL::ValidateProgram()
{
	if(_programID && _linked)
	{
///		GLint status;
//		glValidateProgram(_programID);
//		glGetProgramiv(_programID, GL_VALIDATE_STATUS, &status);
//		return status == GL_TRUE;
		return 1;
	}
	else
		return 0;
}

void ProgramGLSL::PrintLinkLog(std::ostream &os)
{
	GLint len = 0;	

	glGetProgramiv(_programID, GL_INFO_LOG_LENGTH , &len);
	if(len <=1) return;
	
	char* linkLog = new char[len+1];
	if(linkLog == NULL) return;

	glGetProgramInfoLog(_programID, len, &len, linkLog);
	
	linkLog[len] = 0;

	if(strstr(linkLog, "failed"))
	{
		os<<linkLog + (linkLog[0] == ' '? 1:0)<<"\n";
		_linked = 0;
	}

	delete linkLog;
}

int ProgramGLSL::UseProgram()
{
	if(ValidateProgram())
	{
		glUseProgram(_programID);
		return true;
	}
	else
	{
		return false;
	}
}


ProgramGLSL::ProgramGLSL(const char *frag_source)
{
	_linked = 0;
	_programID = glCreateProgram();
	ShaderObject shader(GL_FRAGMENT_SHADER, frag_source);

	if(shader.IsValidFragmentShader())
	{
		AttachShaderObject(shader);
		LinkProgram();

		if(!_linked)
		{
			//shader.PrintCompileLog(std::cout);
			PrintLinkLog(std::cout);
		}
	}else
	{
		_linked = 0;
	}
	
}

/*
ProgramGLSL::ProgramGLSL(char*frag_source, char * vert_source)
{
	_used = 0;
	_linked = 0;
	_programID = glCreateProgram();
	ShaderObject shader(GL_FRAGMENT_SHADER, frag_source);
	ShaderObject vertex_shader(GL_VERTEX_SHADER, vert_source);
	AttachShaderObject(shader);
	AttachShaderObject(vertex_shader);
	LinkProgram();
	if(!_linked)
	{
		shader.PrintCompileLog(std::cout);
		vertex_shader.PrintCompileLog(std::cout);
		PrintLinkLog(std::cout);
		std::cout<<vert_source;
		std::cout<<frag_source;
	}

}
*/



void ProgramGLSL::ReLink()
{
	glLinkProgram(_programID);
}

int ProgramGLSL::IsNative()
{
	return _linked;
}


ProgramGPU* FilterGLSL::CreateFilterH(float kernel[], float offset[], int width)
{

	char buffer[10240];
	ostrstream out(buffer, 10240);
	out<<setprecision(8);

	out<<  "uniform sampler2DRect tex;";
	out<< "\nvoid main(void){ float intensity = 0.0 ;  vec2 pos;\n";


	for(int i = 0; i< width; i++)
	{
		if(offset[i]==0.0)
		{

			out<<"float or = texture2DRect(tex, gl_TexCoord[0].st).r;\n";
			out<<"intensity+= or * "<<kernel[i]<<";\n";
		}else
		{
			out<<"pos = gl_TexCoord[0].st + vec2(float("<<offset[i] <<") , 0);\n";
			out<<"intensity+= "<<kernel[i]<<"*texture2DRect(tex, pos).r;\n";
		}
	}

	//copy original data to red channel
	out<<"gl_FragColor.r = or;\n"; 
	out<<"gl_FragColor.b  = intensity;}\n"<<'\0';

	return new ProgramGLSL( buffer);
}


ProgramGPU* FilterGLSL::CreateFilterV(float kernel[], float offset[], int height)
{

	char buffer[10240];
	ostrstream out(buffer, 10240);
	out<<setprecision(8);

	out<<  "uniform sampler2DRect tex;";
	out<< "\nvoid main(void){ float intensity = 0.0;vec2 pos; \n";

	for(int i = 0; i< height; i++)
	{

		if(offset[i]==0.0)
		{
			out<<"vec2 orb = texture2DRect(tex, gl_TexCoord[0].st).rb;\n";
			out<<"intensity+= orb.y * "<<kernel[i]<<";\n";

		}else
		{
			out<<"pos = gl_TexCoord[0].st + vec2(0, float("<<offset[i] <<") );\n";
			out<<"intensity+= texture2DRect(tex, pos).b * "<<kernel[i]<<";\n";
		}
		
	}

	out<<"gl_FragColor.b = orb.y;\n";
	out<<"gl_FragColor.g = intensity - orb.x;\n"; // difference of gaussian..
	out<<"gl_FragColor.r = intensity;}\n"<<'\0';
	
//	std::cout<<buffer<<endl;
	return new ProgramGLSL( buffer);
}



ProgramGPU* FilterGLSL::CreateFilterHPK(float kernel[], float offset[], int width)
{
	//both h and v are packed...
	int i, j , xw, xwn;

	int halfwidth  = width >>1;
	float * pf = kernel + halfwidth;
	int nhpixel = (halfwidth+1)>>1;	//how many neighbour pixels need to be looked up
	int npixel  = (nhpixel<<1)+1;//
	char buffer[10240];
	float weight[3];
	ostrstream out(buffer, 10240);
	out<<setprecision(8);

	out<<  "uniform sampler2DRect tex;";
	out<< "\nvoid main(void){ vec4 result = vec4(0, 0, 0, 0);\n";
	///use multi texture coordinate because nhpixels can be at most 3
	out<<"vec4 pc; vec2 coord; \n";
	for( i = 0 ; i < npixel ; i++)
	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -