📄 glteximage.cpp
字号:
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 + -