📄 glteximage.cpp
字号:
////////////////////////////////////////////////////////////////////////////
// File: GLTexImage.cpp
// Author: Changchang Wu
// Description : implementation of the GLTexImage class.
//
//
//
// 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 <iostream>
#include <vector>
#include <algorithm>
#include <stdlib.h>
#include <math.h>
using namespace std;
#include "GlobalUtil.h"
#include "IL/il.h"
#include "GLTexImage.h"
#include "FrameBufferObject.h"
#include "ShaderMan.h"
#if defined(_WIN32)
#pragma comment(lib, "../lib/DevIL.lib")
#pragma comment(lib, "../lib/glew32.lib")
#pragma comment(lib, "../lib/glew32s.lib")
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
void GLTexImage::ShowDEBUG()
{
}
GLTexImage::GLTexImage()
{
_imgWidth = _imgHeight = 0;
_texWidth = _texHeight = 0;
_drawWidth = _drawHeight = 0;
_texID = 0;
}
GLTexImage::~GLTexImage()
{
if(_texID) glDeleteTextures(1, &_texID);
}
int GLTexImage::CheckTexture()
{
if(_texID)
{
GLint tw, th;
BindTex();
glGetTexLevelParameteriv(_texTarget, 0, GL_TEXTURE_WIDTH , &tw);
glGetTexLevelParameteriv(_texTarget, 0, GL_TEXTURE_HEIGHT , &th);
UnbindTex();
return tw == _texWidth && th == _texHeight;
}else
{
return _texWidth == 0 && _texHeight ==0;
}
}
//set a dimension that is smaller than the actuall size
//for drawQuad
void GLTexImage::SetImageSize( int width, int height)
{
_drawWidth = _imgWidth = width;
_drawHeight = _imgHeight = height;
}
void GLTexImage::InitTexture( int width, int height, int clamp_to_edge)
{
if(_texID && width == _texWidth && height == _texHeight ) return;
if(_texID==0) glGenTextures(1, &_texID);
_texWidth = _imgWidth = _drawWidth = width;
_texHeight = _imgHeight = _drawHeight = height;
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);
CheckErrorsGL("glTexImage2D");
UnbindTex();
}
void GLTexImage::InitTexture( int width, int height, int clamp_to_edge, GLuint format)
{
if(_texID && width == _texWidth && height == _texHeight ) return;
if(_texID==0) glGenTextures(1, &_texID);
_texWidth = _imgWidth = _drawWidth = width;
_texHeight = _imgHeight = _drawHeight = height;
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, format, _texWidth, _texHeight, 0, GL_RGBA, GL_FLOAT, NULL);
UnbindTex();
}
void GLTexImage::BindTex()
{
glBindTexture(_texTarget, _texID);
}
void GLTexImage::UnbindTex()
{
glBindTexture(_texTarget, 0);
}
void GLTexImage::DrawQuad()
{
glBegin (GL_QUADS);
glTexCoord2i ( 0 , 0 ); glVertex2i ( 0 , 0 );
glTexCoord2i ( 0 , _drawHeight ); glVertex2i ( 0 , _drawHeight );
glTexCoord2i ( _drawWidth , _drawHeight ); glVertex2i ( _drawWidth , _drawHeight );
glTexCoord2i ( _drawWidth , 0 ); glVertex2i ( _drawWidth , 0 );
glEnd ();
glFlush();
}
void GLTexImage::FillMargin(int marginx, int marginy)
{
//
marginx = min(marginx, _texWidth - _imgWidth);
marginy = min(marginy, _texHeight - _imgHeight);
if(marginx >0 || marginy > 0)
{
GlobalUtil::FitViewPort(_imgWidth + marginx, _imgHeight + marginy);
AttachToFBO(0);
BindTex();
ShaderMan::UseShaderMarginCopy(_imgWidth, _imgHeight);
DrawMargin(_imgWidth + marginx, _imgHeight + marginy);
}
}
void GLTexImage::ZeroHistoMargin()
{
ZeroHistoMargin(_imgWidth, _imgHeight);
}
void GLTexImage::ZeroHistoMargin(int width, int height)
{
int marginx = width & 0x01;
int marginy = height & 0x01;
if(marginx >0 || marginy > 0)
{
int right = width + marginx;
int bottom = height + marginy;
GlobalUtil::FitViewPort(right, bottom);
AttachToFBO(0);
ShaderMan::UseShaderZeroPass();
glBegin(GL_QUADS);
if(right > width && _texWidth > width)
{
glTexCoord2i ( width , 0 ); glVertex2i ( width , 0 );
glTexCoord2i ( width , bottom ); glVertex2i ( width , bottom );
glTexCoord2i ( right , bottom ); glVertex2i ( right , bottom );
glTexCoord2i ( right , 0 ); glVertex2i ( right , 0 );
}
if(bottom>height && _texHeight > height)
{
glTexCoord2i ( 0 , height ); glVertex2i ( 0 , height );
glTexCoord2i ( 0 , bottom ); glVertex2i ( 0 , bottom );
glTexCoord2i ( width , bottom ); glVertex2i ( width , bottom );
glTexCoord2i ( width , height ); glVertex2i ( width , height );
}
glEnd();
glFlush();
}
}
void GLTexImage::DrawMargin(int right, int bottom)
{
glBegin(GL_QUADS);
if(right > _drawWidth)
{
glTexCoord2i ( _drawWidth , 0 ); glVertex2i ( _drawWidth , 0 );
glTexCoord2i ( _drawWidth , bottom ); glVertex2i ( _drawWidth , bottom );
glTexCoord2i ( right , bottom ); glVertex2i ( right , bottom );
glTexCoord2i ( right , 0 ); glVertex2i ( right , 0 );
}
if(bottom>_drawHeight)
{
glTexCoord2i ( 0 , _drawHeight ); glVertex2i ( 0 , _drawHeight );
glTexCoord2i ( 0 , bottom ); glVertex2i ( 0 , bottom );
glTexCoord2i ( _drawWidth , bottom ); glVertex2i ( _drawWidth , bottom );
glTexCoord2i ( _drawWidth , _drawHeight ); glVertex2i ( _drawWidth , _drawHeight );
}
glEnd();
glFlush();
}
void GLTexImage::DrawQuadMT4()
{
int w = _drawWidth, h = _drawHeight;
glBegin (GL_QUADS);
glMultiTexCoord2i( GL_TEXTURE0, 0 , 0 );
glMultiTexCoord2i( GL_TEXTURE1, -1 , 0 );
glMultiTexCoord2i( GL_TEXTURE2, 1 , 0 );
glMultiTexCoord2i( GL_TEXTURE3, 0 , -1 );
glMultiTexCoord2i( GL_TEXTURE4, 0 , 1 );
glVertex2i ( 0 , 0 );
glMultiTexCoord2i( GL_TEXTURE0, 0 , h );
glMultiTexCoord2i( GL_TEXTURE1, -1 , h );
glMultiTexCoord2i( GL_TEXTURE2, 1 , h );
glMultiTexCoord2i( GL_TEXTURE3, 0 , h -1 );
glMultiTexCoord2i( GL_TEXTURE4, 0 , h +1 );
glVertex2i ( 0 , h );
glMultiTexCoord2i( GL_TEXTURE0, w , h );
glMultiTexCoord2i( GL_TEXTURE1, w-1 , h );
glMultiTexCoord2i( GL_TEXTURE2, w+1 , h );
glMultiTexCoord2i( GL_TEXTURE3, w , h-1 );
glMultiTexCoord2i( GL_TEXTURE4, w , h+1 );
glVertex2i ( w , h );
glMultiTexCoord2i( GL_TEXTURE0, w , 0 );
glMultiTexCoord2i( GL_TEXTURE1, w-1 , 0 );
glMultiTexCoord2i( GL_TEXTURE2, w+1 , 0 );
glMultiTexCoord2i( GL_TEXTURE3, w , -1 );
glMultiTexCoord2i( GL_TEXTURE4, w , 1 );
glVertex2i ( w , 0 );
glEnd ();
glFlush();
}
void GLTexImage::DrawQuadMT8()
{
int w = _drawWidth;
int h = _drawHeight;
glBegin (GL_QUADS);
glMultiTexCoord2i( GL_TEXTURE0, 0 , 0 );
glMultiTexCoord2i( GL_TEXTURE1, -1 , 0 );
glMultiTexCoord2i( GL_TEXTURE2, 1 , 0 );
glMultiTexCoord2i( GL_TEXTURE3, 0 , -1 );
glMultiTexCoord2i( GL_TEXTURE4, 0 , 1 );
glMultiTexCoord2i( GL_TEXTURE5, -1 , -1 );
glMultiTexCoord2i( GL_TEXTURE6, -1 , 1 );
glMultiTexCoord2i( GL_TEXTURE7, 1 , -1 );
glVertex2i ( 0 , 0 );
glMultiTexCoord2i( GL_TEXTURE0, 0 , h );
glMultiTexCoord2i( GL_TEXTURE1, -1 , h );
glMultiTexCoord2i( GL_TEXTURE2, 1 , h );
glMultiTexCoord2i( GL_TEXTURE3, 0 , h -1 );
glMultiTexCoord2i( GL_TEXTURE4, 0 , h +1 );
glMultiTexCoord2i( GL_TEXTURE5, -1 , h -1 );
glMultiTexCoord2i( GL_TEXTURE6, -1 , h +1 );
glMultiTexCoord2i( GL_TEXTURE7, 1 , h -1 );
glVertex2i ( 0 , h );
glMultiTexCoord2i( GL_TEXTURE0, w , h );
glMultiTexCoord2i( GL_TEXTURE1, w-1 , h );
glMultiTexCoord2i( GL_TEXTURE2, w+1 , h );
glMultiTexCoord2i( GL_TEXTURE3, w , h -1 );
glMultiTexCoord2i( GL_TEXTURE4, w , h +1 );
glMultiTexCoord2i( GL_TEXTURE5, w-1 , h -1 );
glMultiTexCoord2i( GL_TEXTURE6, w-1 , h +1 );
glMultiTexCoord2i( GL_TEXTURE7, w+1 , h -1 );
glVertex2i ( w , h );
glMultiTexCoord2i( GL_TEXTURE0, w , 0 );
glMultiTexCoord2i( GL_TEXTURE1, w-1 , 0 );
glMultiTexCoord2i( GL_TEXTURE2, w+1 , 0 );
glMultiTexCoord2i( GL_TEXTURE3, w , -1 );
glMultiTexCoord2i( GL_TEXTURE4, w , 1 );
glMultiTexCoord2i( GL_TEXTURE5, w-1 , -1 );
glMultiTexCoord2i( GL_TEXTURE6, w-1 , 1 );
glMultiTexCoord2i( GL_TEXTURE7, w+1 , -1 );
glVertex2i ( w , 0 );
glEnd ();
glFlush();
}
void GLTexImage::DrawImage()
{
DrawQuad();
}
void GLTexImage::FitTexViewPort()
{
GlobalUtil::FitViewPort(_drawWidth, _drawHeight);
}
void GLTexImage::FitRealTexViewPort()
{
GlobalUtil::FitViewPort(_texWidth, _texHeight);
}
void GLTexImage::AttachToFBO(int i)
{
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, i+GL_COLOR_ATTACHMENT0_EXT, _texTarget, _texID, 0 );
}
void GLTexImage::DetachFBO(int i)
{
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, i+GL_COLOR_ATTACHMENT0_EXT, _texTarget, 0, 0 );
}
void GLTexImage::DrawQuad(float x1, float x2, float y1, float y2)
{
glBegin (GL_QUADS);
glTexCoord2f ( x1 , y1 ); glVertex2f ( x1 , y1 );
glTexCoord2f ( x1 , y2 ); glVertex2f ( x1 , y2 );
glTexCoord2f ( x2 , y2 ); glVertex2f ( x2 , y2 );
glTexCoord2f ( x2 , y1 ); glVertex2f ( x2 , y1 );
glEnd ();
glFlush();
}
void GLTexImage::TexConvertRGB()
{
//change 3/22/09
FrameBufferObject fbo;
//GlobalUtil::FitViewPort(1, 1);
FitTexViewPort();
AttachToFBO(0);
ShaderMan::UseShaderRGB2Gray();
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
DrawQuad();
ShaderMan::UnloadProgram();
DetachFBO(0);
}
void GLTexImage::DrawQuadDS(int scale)
{
DrawScaledQuad(float(scale));
}
void GLTexImage::DrawQuadUS(int scale)
{
DrawScaledQuad(1.0f/scale);
}
void GLTexImage::DrawScaledQuad(float texscale)
{
////the texture coordinate for 0.5 is to + 0.5*texscale
float to = 0.5f -0.5f * texscale;
float tx = _imgWidth*texscale +to;
float ty = _imgHeight*texscale +to;
glBegin (GL_QUADS);
glTexCoord2f ( to , to ); glVertex2i ( 0 , 0 );
glTexCoord2f ( to , ty ); glVertex2i ( 0 , _imgHeight );
glTexCoord2f ( tx , ty ); glVertex2i ( _imgWidth , _imgHeight );
glTexCoord2f ( tx , to ); glVertex2i ( _imgWidth , 0 );
glEnd ();
glFlush();
}
void GLTexImage::DrawQuadReduction(int w , int h)
{
float to = -0.5f;
float tx = w*2 +to;
float ty = h*2 +to;
glBegin (GL_QUADS);
glMultiTexCoord2f ( GL_TEXTURE0, to , to );
glMultiTexCoord2f ( GL_TEXTURE1, to +1, to );
glMultiTexCoord2f ( GL_TEXTURE2, to , to+1 );
glMultiTexCoord2f ( GL_TEXTURE3, to +1, to+1 );
glVertex2i ( 0 , 0 );
glMultiTexCoord2f ( GL_TEXTURE0, to , ty );
glMultiTexCoord2f ( GL_TEXTURE1, to +1, ty );
glMultiTexCoord2f ( GL_TEXTURE2, to , ty +1 );
glMultiTexCoord2f ( GL_TEXTURE3, to +1, ty +1 );
glVertex2i ( 0 , h );
glMultiTexCoord2f ( GL_TEXTURE0, tx , ty );
glMultiTexCoord2f ( GL_TEXTURE1, tx +1, ty );
glMultiTexCoord2f ( GL_TEXTURE2, tx , ty +1);
glMultiTexCoord2f ( GL_TEXTURE3, tx +1, ty +1);
glVertex2i ( w , h );
glMultiTexCoord2f ( GL_TEXTURE0, tx , to );
glMultiTexCoord2f ( GL_TEXTURE1, tx +1, to );
glMultiTexCoord2f ( GL_TEXTURE2, tx , to +1 );
glMultiTexCoord2f ( GL_TEXTURE3, tx +1, to +1 );
glVertex2i ( w , 0 );
glEnd ();
glFlush();
}
void GLTexImage::DrawQuadReduction()
{
float to = -0.5f;
float tx = _drawWidth*2 +to;
float ty = _drawHeight*2 +to;
glBegin (GL_QUADS);
glMultiTexCoord2f ( GL_TEXTURE0, to , to );
glMultiTexCoord2f ( GL_TEXTURE1, to +1, to );
glMultiTexCoord2f ( GL_TEXTURE2, to , to+1 );
glMultiTexCoord2f ( GL_TEXTURE3, to +1, to+1 );
glVertex2i ( 0 , 0 );
glMultiTexCoord2f ( GL_TEXTURE0, to , ty );
glMultiTexCoord2f ( GL_TEXTURE1, to +1, ty );
glMultiTexCoord2f ( GL_TEXTURE2, to , ty +1 );
glMultiTexCoord2f ( GL_TEXTURE3, to +1, ty +1 );
glVertex2i ( 0 , _drawHeight );
glMultiTexCoord2f ( GL_TEXTURE0, tx , ty );
glMultiTexCoord2f ( GL_TEXTURE1, tx +1, ty );
glMultiTexCoord2f ( GL_TEXTURE2, tx , ty +1);
glMultiTexCoord2f ( GL_TEXTURE3, tx +1, ty +1);
glVertex2i ( _drawWidth , _drawHeight );
glMultiTexCoord2f ( GL_TEXTURE0, tx , to );
glMultiTexCoord2f ( GL_TEXTURE1, tx +1, to );
glMultiTexCoord2f ( GL_TEXTURE2, tx , to +1 );
glMultiTexCoord2f ( GL_TEXTURE3, tx +1, to +1 );
glVertex2i ( _drawWidth , 0 );
glEnd ();
glFlush();
}
void GLTexPacked::TexConvertRGB()
{
//update the actual size of daw area
_drawWidth = (1 + _imgWidth) >> 1;
_drawHeight = (1 + _imgHeight) >> 1;
///
FrameBufferObject fbo;
GLuint oldTexID = _texID;
glGenTextures(1, &_texID);
glBindTexture(_texTarget, _texID);
glTexImage2D(_texTarget, 0, _iTexFormat, _texWidth, _texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
//input
glBindTexture(_texTarget, oldTexID);
//output
AttachToFBO(0);
//program
ShaderMan::UseShaderRGB2Gray();
//draw buffer
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
//run
DrawQuadDS(2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -