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

📄 glteximage.cpp

📁 SiftGPU is an implementation of SIFT [1] for GPU. SiftGPU processes pixels parallely to build Gaussi
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	ShaderMan::UnloadProgram();

	glDeleteTextures(1, &oldTexID);
	DetachFBO(0);
}


void GLTexPacked::SetImageSize( int width,  int height)
{
	_imgWidth =  width;		_drawWidth = (width + 1) >> 1;
	_imgHeight =  height;	_drawHeight = (height + 1) >> 1;
}

void GLTexPacked::InitTexture( int width,  int height, int clamp_to_edge)
{

	if(_texID && width == _imgWidth && height == _imgHeight ) return;
	if(_texID==0)	glGenTextures(1, &_texID); 

	_imgWidth = width;
	_imgHeight = height;
	if(GlobalUtil::_PreciseBorder)
	{
		_texWidth = (width + 2) >> 1;
		_texHeight = (height + 2) >> 1;
	}else
	{
		_texWidth = (width + 1) >> 1;
		_texHeight = (height + 1) >> 1;
	}
	_drawWidth = (width + 1) >> 1;
	_drawHeight = (height + 1) >> 1;

	BindTex();

	if(clamp_to_edge)
	{
		glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
		glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
	}else
	{
		//out of bound tex read returns 0??
		glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); 
		glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); 
	}
	glTexParameteri(_texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
	glTexParameteri(_texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

	glTexImage2D(_texTarget, 0, _iTexFormat, 
		_texWidth, _texHeight, 0, GL_RGBA, GL_FLOAT, NULL); 

	UnbindTex();

}


void  GLTexPacked::DrawImage()
{
	float x1 =0,  y1 = 0; //border..
	float x2 = _imgWidth*0.5f +x1;
	float y2 = _imgHeight*0.5f + y1; 
	glBegin (GL_QUADS);
		glTexCoord2f ( x1	,   y1  ); 			glVertex2i   ( 0			,		0   ); 
		glTexCoord2f ( x1	,   y2 );			glVertex2i   ( 0			,		_imgHeight   ); 
 		glTexCoord2f ( x2   ,   y2  ); 			glVertex2i   ( _imgWidth	,		_imgHeight   ); 
		glTexCoord2f ( x2	,   y1   ); 		glVertex2i   ( _imgWidth	,		0   ); 
	glEnd ();
	glFlush();
}

void GLTexPacked::DrawQuadUS(int scale)
{
	int tw =_drawWidth, th = _drawHeight;
	float texscale = 1.0f / scale;
	float x1 = 0.5f - 0.5f*scale, y1 = x1;
	float x2 = tw * texscale + x1;
	float y2 = th * texscale + y1;
	float step = texscale *0.5f;
	glBegin (GL_QUADS);
		glMultiTexCoord2f( GL_TEXTURE0, x1		,   y1      ); 	
		glMultiTexCoord2f( GL_TEXTURE1, x1+step	,   y1      ); 	
		glMultiTexCoord2f( GL_TEXTURE2, x1   	,   y1 +step); 	
		glMultiTexCoord2f( GL_TEXTURE3, x1+step	,   y1 +step); 	
		glVertex2i   ( 0			,		0   ); 

		glMultiTexCoord2f( GL_TEXTURE0, x1		,	y2      );	
		glMultiTexCoord2f( GL_TEXTURE1, x1+step	,   y2      );
		glMultiTexCoord2f( GL_TEXTURE2, x1   	,   y2 +step);	
		glMultiTexCoord2f( GL_TEXTURE3, x1+step	,   y2 +step);	
		glVertex2i   ( 0			,	th   ); 

		glMultiTexCoord2f( GL_TEXTURE0, x2		,   y2      );
		glMultiTexCoord2f( GL_TEXTURE1, x2+step	,   y2      );
		glMultiTexCoord2f( GL_TEXTURE2, x2   	,   y2 +step);
		glMultiTexCoord2f( GL_TEXTURE3, x2+step	,   y2 +step);
		glVertex2i   ( tw	,	th   ); 

		glMultiTexCoord2f( GL_TEXTURE0, x2		,   y1      );	
		glMultiTexCoord2f( GL_TEXTURE1, x2+step	,   y1      );
		glMultiTexCoord2f( GL_TEXTURE2, x2   	,   y1 +step);	
		glMultiTexCoord2f( GL_TEXTURE3, x2+step	,   y1 +step);		
		glVertex2i   ( tw	,	0   ); 
	glEnd ();
}

void GLTexPacked::DrawQuadDS(int scale)
{
	int tw = _drawWidth;
	int th = _drawHeight;
	float x1 = 0.5f - 0.5f*scale;
	float x2 = tw * scale + x1;
	float y1 = 0.5f - 0.5f * scale;
	float y2 = th * scale + y1;
	int step = scale / 2;

	glBegin (GL_QUADS);
		glMultiTexCoord2f( GL_TEXTURE0, x1		,   y1      ); 	
		glMultiTexCoord2f( GL_TEXTURE1, x1+step	,   y1      ); 	
		glMultiTexCoord2f( GL_TEXTURE2, x1   	,   y1 +step); 	
		glMultiTexCoord2f( GL_TEXTURE3, x1+step	,   y1 +step); 	
		glVertex2i   ( 0			,		0   ); 

		glMultiTexCoord2f( GL_TEXTURE0, x1		,	y2      );	
		glMultiTexCoord2f( GL_TEXTURE1, x1+step	,   y2      );
		glMultiTexCoord2f( GL_TEXTURE2, x1   	,   y2 +step);	
		glMultiTexCoord2f( GL_TEXTURE3, x1+step	,   y2 +step);	
		glVertex2i   ( 0			,	th   ); 

		glMultiTexCoord2f( GL_TEXTURE0, x2		,   y2      );
		glMultiTexCoord2f( GL_TEXTURE1, x2+step	,   y2      );
		glMultiTexCoord2f( GL_TEXTURE2, x2   	,   y2 +step);
		glMultiTexCoord2f( GL_TEXTURE3, x2+step	,   y2 +step);
		glVertex2i   ( tw	,	th   ); 

		glMultiTexCoord2f( GL_TEXTURE0, x2		,   y1      );	
		glMultiTexCoord2f( GL_TEXTURE1, x2+step	,   y1      );
		glMultiTexCoord2f( GL_TEXTURE2, x2   	,   y1 +step);	
		glMultiTexCoord2f( GL_TEXTURE3, x2+step	,   y1 +step);		
		glVertex2i   ( tw	,	0   ); 
	glEnd ();
}

void GLTexPacked::ZeroHistoMargin()
{
	int marginx = (((_imgWidth  + 3) /4)*4) - _imgWidth;
	int marginy = (((-_imgHeight + 3)/4)*4) - _imgHeight;
	if(marginx >0 || marginy > 0)
	{
		int tw = (_imgWidth + marginx ) >> 1;	
		int th = (_imgHeight + marginy ) >> 1;	
		tw = min(_texWidth, tw );
		th = min(_texHeight, th);
		GlobalUtil::FitViewPort(tw, th);
		AttachToFBO(0);
		BindTex();
		ShaderMan::UseShaderZeroPass();
		DrawMargin(tw, th, 1, 1);
	}
}


void GLTexPacked::FillMargin(int marginx, int marginy)
{
	//
	marginx = min(marginx, _texWidth * 2 - _imgWidth);
	marginy = min(marginy, _texHeight * 2 - _imgHeight);
	if(marginx >0 || marginy > 0)
	{

	
		int tw = (_imgWidth + marginx + 1) >> 1;
		int th = (_imgHeight + marginy + 1) >> 1;
		GlobalUtil::FitViewPort(tw, th);
		BindTex();
		AttachToFBO(0);
		ShaderMan::UseShaderMarginCopy(_imgWidth , _imgHeight);
		DrawMargin(tw, th, marginx, marginy);
	}
}
void GLTexPacked::DrawMargin(int right, int bottom, int mx, int my)
{
	int tw = (_imgWidth >>1);
	int th = (_imgHeight >>1);
	glBegin(GL_QUADS);
	if(right>tw && mx)
	{
		glTexCoord2i ( tw	,   0   ); 				glVertex2i   ( tw	,		0   ); 
		glTexCoord2i ( tw	,   bottom  );			glVertex2i   ( tw	,		bottom   ); 
		glTexCoord2i ( right,   bottom  ); 			glVertex2i   ( right,		bottom   ); 
		glTexCoord2i ( right,   0   ); 				glVertex2i   ( right,		0   ); 	
	}
	if(bottom>th && my)
	{
		glTexCoord2i ( 0	,   th  ); 		glVertex2i   ( 0	,		th   ); 
		glTexCoord2i ( 0	,   bottom	);	glVertex2i   ( 0	,		bottom	 ); 
		glTexCoord2i ( tw	,   bottom	); 	glVertex2i   ( tw	,		bottom	 ); 
		glTexCoord2i ( tw	,   th	); 		glVertex2i   ( tw	,		th	 ); 
	}
	glEnd();
	glFlush();

}


void GLTexImage::UnbindMultiTex(int n)
{
	for(int i = n-1; i>=0; i--)
	{
		glActiveTexture(GL_TEXTURE0+i);
		glBindTexture(_texTarget, 0);
	}
}

template <class Uint> int 

#if !defined(_MSC_VER) || _MSC_VER > 1200
GLTexInput::
#endif

DownSamplePixelDataI(unsigned int gl_format, int width, int height, int ds, 
									const Uint * pin, Uint * pout)	
{
	int step, linestep;
	int i, j; 
	int ws = width/ds;
	int hs = height/ds;
	const Uint * line = pin, * p;
	Uint *po = pout;
	switch(gl_format)
	{
	case GL_LUMINANCE:
	case GL_LUMINANCE_ALPHA:
		step = ds * (gl_format == GL_LUMINANCE? 1: 2); 
		linestep = width * step; 
		for(i = 0 ; i < hs; i++, line+=linestep)
		{
			for(j = 0, p = line; j < ws; j++, p+=step)
			{
				*po++ = *p;
			}
		}
		break;
	case GL_RGB:
	case GL_RGBA:
		step = ds * (gl_format == GL_RGB? 3: 4); 
		linestep = width * step; 

		for(i = 0 ; i < hs; i++, line+=linestep)
		{
			for(j = 0, p = line; j < ws; j++, p+=step)
			{
				//*po++ = int(p[0]*0.299 + p[1] * 0.587 + p[2]* 0.114 + 0.5);
				*po++ = ((19595*p[0] + 38470*p[1] + 7471*p[2]+ 32768)>>16);
			}
		}
		break;
	case GL_BGR:
	case GL_BGRA:
		step = ds * (gl_format == GL_BGR? 3: 4); 
		linestep = width * step; 
		for(i = 0 ; i < hs; i++, line+=linestep)
		{
			for(j = 0, p = line; j < ws; j++, p+=step)
			{
				*po++ = ((7471*p[0] + 38470*p[1] + 19595*p[2]+ 32768)>>16);
			}
		}
		break;
	default:
		return 0;
	}

	return 1;

}


int GLTexInput::DownSamplePixelDataF(unsigned int gl_format, int width, int height, int ds, const float * pin, float * pout)	
{
	int step, linestep;
	int i, j; 
	int ws = width/ds;
	int hs = height/ds;
	const float * line = pin, * p;
	float *po = pout;
	switch(gl_format)
	{
	case GL_LUMINANCE:
	case GL_LUMINANCE_ALPHA:
		step = ds * (gl_format == GL_LUMINANCE? 1: 2); 
		linestep = width * step; 
		for(i = 0 ; i < hs; i++, line+=linestep)
		{
			for(j = 0, p = line; j < ws; j++, p+=step)
			{
				*po++ = *p;
			}
		}
		break;
	case GL_RGB:
	case GL_RGBA:
		step = ds * (gl_format == GL_RGB? 3: 4); 
		linestep = width * step; 
		for(i = 0 ; i < hs; i++, line+=linestep)
		{
			for(j = 0, p = line; j < ws; j++, p+=step)
			{
				*po++ = (0.299f*p[0] + 0.587f*p[1] + 0.114f*p[2]);
			}
		}
		break;
	case GL_BGR:
	case GL_BGRA:
		step = ds * (gl_format == GL_BGR? 3: 4); 
		linestep = width * step; 
		for(i = 0 ; i < hs; i++, line+=linestep)
		{
			for(j = 0, p = line; j < ws; j++, p+=step)
			{
				*po++ = (0.114f*p[0] + 0.587f*p[1] + 0.299f * p[2]); 
			}
		}
		break;
	default:
		return 0;
	}

	return 1;

}

int GLTexInput::SetImageData( int width,  int height, const void * data, 
							 unsigned int gl_format, unsigned int gl_type )
{


	int simple_format = IsSimpleGlFormat(gl_format, gl_type);//no cpu code to handle other formats
	int ws, hs, done = 1;
	
	_rgb_converted = 1; 

	if( simple_format 
		&& ( width > _texMaxDim || height > _texMaxDim || GlobalUtil::_PreProcessOnCPU) 
		&& GlobalUtil::_octave_min_default >0   )
	{
		_down_sampled = GlobalUtil::_octave_min_default; 
		ws = width >> GlobalUtil::_octave_min_default;
		hs = height >> GlobalUtil::_octave_min_default;
	}else
	{
		_down_sampled = 0; 
		ws = width;
		hs = height;
	}
	
	if ( ws > _texMaxDim || hs > _texMaxDim)
	{
		if(simple_format)
		{
			if(GlobalUtil::_verbose) std::cout<<"Automatic down-sampling is used\n";
			do
			{
				_down_sampled ++;
				ws >>= 1;
				hs >>= 1;
			}while(ws > _texMaxDim || hs > _texMaxDim);
		}else
		{
			std::cerr<<"Input images is too big to fit into a texture\n";
			return 0;
		}
	}

	_texWidth = _imgWidth = _drawWidth = ws;	
	_texHeight = _imgHeight = _drawHeight = hs;

	if(GlobalUtil::_verbose)
	{
		std::cout<<"Image size :\t"<<width<<"x"<<height<<"\n";
		if(_down_sampled >0) 	std::cout<<"Down sample to \t"<<ws<<"x"<<hs<<"\n";
	}

	if(_texID ==0)		glGenTextures(1, &_texID); 
	glBindTexture(_texTarget, _texID); 
	CheckErrorsGL("glBindTexture");

	glPixelStorei(GL_UNPACK_ALIGNMENT , 1); 

	if(simple_format && ( _down_sampled> 0 || (gl_format != GL_LUMINANCE && GlobalUtil::_PreProcessOnCPU) ))
	{

		if(gl_type == GL_UNSIGNED_BYTE)
		{
			unsigned char * newdata = new unsigned char [_imgWidth * _imgHeight];
			DownSamplePixelDataI(gl_format, width, height, 1<<_down_sampled, ((const unsigned char*) data), newdata);
			
			glTexImage2D(_texTarget, 0, _iTexFormat, _imgWidth, _imgHeight, 0,
					GL_LUMINANCE, GL_UNSIGNED_BYTE, newdata);
			delete newdata;
		}else if(gl_type == GL_UNSIGNED_SHORT)
		{
			unsigned short * newdata = new unsigned short [_imgWidth * _imgHeight];
			DownSamplePixelDataI(gl_format, width, height, 1<<_down_sampled, ((const unsigned short*) data), newdata);
			
			glTexImage2D(_texTarget, 0, _iTexFormat, _imgWidth, _imgHeight, 0,
					GL_LUMINANCE, GL_UNSIGNED_SHORT, newdata);
			delete newdata;
		}else if(gl_type == GL_FLOAT)
		{
			float * newdata = new float [_imgWidth * _imgHeight];
			DownSamplePixelDataF(gl_format, width, height, 1<<_down_sampled, (float*)data, newdata);
			glTexImage2D(_texTarget, 0, _iTexFormat, _imgWidth, _imgHeight, 0,
					GL_LUMINANCE, GL_FLOAT, newdata);
			delete newdata;
		}else
		{
			//impossible
			done = 0;
			_rgb_converted = 0;
		}
		GlobalUtil::FitViewPort(1, 1);  //this used to be necessary
	}else
	{
		//ds must be 0 here if not simpleformat
		glTexImage2D(_texTarget, 0, _iTexFormat, _imgWidth, _imgHeight, 0, 
			gl_format,	gl_type, data); 

		//convert RGB 2 GRAY if needed
		if(gl_format == GL_LUMINANCE || gl_format == GL_LUMINANCE_ALPHA)
			GlobalUtil::FitViewPort(1, 1); //this used to be necessary
		else if(ShaderMan::HaveShaderMan())
			TexConvertRGB();
		else
			_rgb_converted = 0;
	}
	UnbindTex();
	return done;
}

void GLTexInput::DeleteTexture()
{
	glDeleteTextures(1, &_texID);
	_texID = 0;
}

int GLTexInput::LoadImageFile(char *imagepath, int &w, int &h )
{

	unsigned int imID;
	int done = 1;


	ilGenImages(1, &imID);
	ilBindImage(imID); 

	if(ilLoadImage(imagepath))
	{

		w = ilGetInteger(IL_IMAGE_WIDTH);
		h = ilGetInteger(IL_IMAGE_HEIGHT);
		int ilformat = ilGetInteger(IL_IMAGE_FORMAT);

		if(SetImageData(w, h, ilGetData(), ilformat, GL_UNSIGNED_BYTE)==0)
		{
			done =0;
		}else 	if(GlobalUtil::_verbose)
		{
			std::cout<<"Image loaded :\t"<<imagepath<<"\n";
		}

	}else
	{
		std::cerr<<"Unable to open image [code = "<<ilGetError()<<"]\n";
		done = 0;
	}

	ilDeleteImages(1, &imID); 
	return done;
}

int GLTexImage::CopyToPBO(GLuint pbo, int width, int height)
{

	FrameBufferObject fbo;
	GLint bsize, esize = width * height * sizeof(float) * 4;
	AttachToFBO(0);
	glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, pbo);
	glGetBufferParameteriv(GL_PIXEL_PACK_BUFFER_ARB, GL_BUFFER_SIZE, &bsize);
	if(bsize < esize) 
	{
		glBufferData(GL_PIXEL_PACK_BUFFER_ARB, esize,	NULL, GL_STATIC_DRAW_ARB);
		glGetBufferParameteriv(GL_PIXEL_PACK_BUFFER_ARB, GL_BUFFER_SIZE, &bsize);
	}
	if(bsize >= esize)
	{
		glReadPixels(0, 0, width, height, GL_RGBA, GL_FLOAT, 0);
	}
	glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
	DetachFBO(0);

	return bsize >= esize;
}


void GLTexImage::CopyFromPBO(GLuint pbo, int width, int height, GLenum format)
{
	InitTexture(max(width, _texWidth), max(height, _texHeight));
	SetImageSize(width, height);
	if(width > 0 && height > 0)
	{
		BindTex();
		glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
		glTexSubImage2D(GlobalUtil::_texTarget, 0, 0, 0, width, height, format, GL_FLOAT, 0);
		glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
		UnbindTex();
	}
}

⌨️ 快捷键说明

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