You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1260 lines
34 KiB
1260 lines
34 KiB
////////////////////////////////////////////////////////////////////////////
|
|
// 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 <stdio.h>
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <vector>
|
|
#include <algorithm>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
using namespace std;
|
|
|
|
|
|
|
|
#include "GlobalUtil.h"
|
|
|
|
#include "GLTexImage.h"
|
|
#include "FrameBufferObject.h"
|
|
#include "ShaderMan.h"
|
|
|
|
|
|
//#define SIFTGPU_NO_DEVIL
|
|
|
|
#ifndef SIFTGPU_NO_DEVIL
|
|
#include "IL/il.h"
|
|
#else
|
|
#include <string.h>
|
|
#endif
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
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);
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
template <class Uint> int
|
|
|
|
#if !defined(_MSC_VER) || _MSC_VER > 1200
|
|
GLTexInput::
|
|
#endif
|
|
|
|
DownSamplePixelDataI2F(unsigned int gl_format, int width, int height, int ds,
|
|
const Uint * pin, float * pout, int skip)
|
|
{
|
|
int step, linestep;
|
|
int i, j;
|
|
int ws = width/ds - skip;
|
|
int hs = height/ds;
|
|
const Uint * line = pin, * p;
|
|
float *po = pout;
|
|
const float factor = (sizeof(Uint) == 1? 255.0f : 65535.0f);
|
|
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) / factor;
|
|
}
|
|
}
|
|
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]) / (65535.0f * factor));
|
|
}
|
|
}
|
|
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]) / (65535.0f * factor));
|
|
}
|
|
}
|
|
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 skip)
|
|
{
|
|
int step, linestep;
|
|
int i, j;
|
|
int ws = width/ds - skip;
|
|
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;
|
|
|
|
if(_converted_data) {delete [] _converted_data; _converted_data = NULL; }
|
|
|
|
_rgb_converted = 1;
|
|
_data_modified = 0;
|
|
|
|
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(GlobalUtil::_UseCUDA || GlobalUtil::_UseOpenCL)
|
|
{
|
|
//////////////////////////////////////
|
|
int tWidth = TruncateWidthCU(_imgWidth);
|
|
int skip = _imgWidth - tWidth;
|
|
//skip = 0;
|
|
if(!simple_format)
|
|
{
|
|
std::cerr << "Input format not supported under current settings.\n";
|
|
return 0;
|
|
}else if(_down_sampled > 0 || gl_format != GL_LUMINANCE || gl_type != GL_FLOAT)
|
|
{
|
|
_converted_data = new float [_imgWidth * _imgHeight];
|
|
if(gl_type == GL_UNSIGNED_BYTE)
|
|
DownSamplePixelDataI2F(gl_format, width, height, 1<<_down_sampled,
|
|
((const unsigned char*) data), _converted_data, skip);
|
|
else if(gl_type == GL_UNSIGNED_SHORT)
|
|
DownSamplePixelDataI2F(gl_format, width, height, 1<<_down_sampled,
|
|
((const unsigned short*) data), _converted_data, skip);
|
|
else
|
|
DownSamplePixelDataF(gl_format, width, height, 1<<_down_sampled, (float*)data, _converted_data, skip);
|
|
_rgb_converted = 2; //indidates a new data copy
|
|
_pixel_data = _converted_data;
|
|
}else
|
|
{
|
|
//Luminance data that doesn't need to down sample
|
|
_rgb_converted = 1;
|
|
_pixel_data = data;
|
|
if(skip > 0)
|
|
{
|
|
for(int i = 1; i < _imgHeight; ++i)
|
|
{
|
|
float * dst = ((float*)data) + i * tWidth, * src = ((float*)data) + i * _imgWidth;
|
|
for(int j = 0; j < tWidth; ++j) *dst++ = * src++;
|
|
}
|
|
}
|
|
}
|
|
_texWidth = _imgWidth = _drawWidth = tWidth;
|
|
_data_modified = 1;
|
|
}else
|
|
{
|
|
if(_texID ==0) glGenTextures(1, &_texID);
|
|
glBindTexture(_texTarget, _texID);
|
|
CheckErrorsGL("glBindTexture");
|
|
glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
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, GL_LUMINANCE32F_ARB, //internal format changed
|
|
_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, GL_LUMINANCE32F_ARB, //internal format changed
|
|
_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, GL_LUMINANCE32F_ARB, //internal format changed
|
|
_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
|
|
if(gl_format == GL_LUMINANCE || gl_format == GL_LUMINANCE_ALPHA)
|
|
{
|
|
//use one channel internal format if data is intensity image
|
|
glTexImage2D(_texTarget, 0, GL_LUMINANCE32F_ARB,
|
|
_imgWidth, _imgHeight, 0, gl_format, gl_type, data);
|
|
GlobalUtil::FitViewPort(1, 1); //this used to be necessary
|
|
}
|
|
else
|
|
{
|
|
//convert RGB 2 GRAY if needed
|
|
glTexImage2D(_texTarget, 0, _iTexFormat, _imgWidth, _imgHeight, 0, gl_format, gl_type, data);
|
|
if(ShaderMan::HaveShaderMan())
|
|
TexConvertRGB();
|
|
else
|
|
_rgb_converted = 0; //In CUDA mode, the conversion will be done by CUDA kernel
|
|
}
|
|
}
|
|
UnbindTex();
|
|
}
|
|
return done;
|
|
}
|
|
|
|
|
|
GLTexInput::~GLTexInput()
|
|
{
|
|
if(_converted_data) delete [] _converted_data;
|
|
}
|
|
|
|
|
|
int GLTexInput::LoadImageFile(char *imagepath, int &w, int &h )
|
|
{
|
|
#ifndef SIFTGPU_NO_DEVIL
|
|
static int devil_loaded = 0;
|
|
unsigned int imID;
|
|
int done = 1;
|
|
|
|
if(devil_loaded == 0)
|
|
{
|
|
ilInit();
|
|
ilOriginFunc(IL_ORIGIN_UPPER_LEFT);
|
|
ilEnable(IL_ORIGIN_SET);
|
|
devil_loaded = 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;
|
|
#else
|
|
FILE * file = fopen(imagepath, "rb"); if (file ==NULL) return 0;
|
|
|
|
char buf[8]; int width, height, cn, g, done = 1;
|
|
|
|
if(fscanf(file, "%s %d %d %d", buf, &width, &height, &cn )<4 || cn > 255 || width < 0 || height < 0)
|
|
{
|
|
fclose(file);
|
|
std::cerr << "ERROR: fileformat not supported\n";
|
|
return 0;
|
|
}else
|
|
{
|
|
w = width;
|
|
h = height;
|
|
}
|
|
unsigned char * data = new unsigned char[width * height];
|
|
unsigned char * pixels = data;
|
|
if (strcmp(buf, "P5")==0 )
|
|
{
|
|
fscanf(file, "%c",buf);//skip one byte
|
|
fread(pixels, 1, width*height, file);
|
|
}else if (strcmp(buf, "P2")==0 )
|
|
{
|
|
for (int i = 0 ; i< height; i++)
|
|
{
|
|
for ( int j = 0; j < width; j++)
|
|
{
|
|
fscanf(file, "%d", &g);
|
|
*pixels++ = (unsigned char) g;
|
|
}
|
|
}
|
|
}else if (strcmp(buf, "P6")==0 )
|
|
{
|
|
fscanf(file, "%c", buf);//skip one byte
|
|
int j, num = height*width;
|
|
unsigned char buf[3];
|
|
for ( j =0 ; j< num; j++)
|
|
{
|
|
fread(buf,1,3, file);
|
|
*pixels++=int(0.10454f* buf[2]+0.60581f* buf[1]+0.28965f* buf[0]);
|
|
}
|
|
}else if (strcmp(buf, "P3")==0 )
|
|
{
|
|
int r, g, b;
|
|
int i , num =height*width;
|
|
for ( i = 0 ; i< num; i++)
|
|
{
|
|
fscanf(file, "%d %d %d", &r, &g, &b);
|
|
*pixels++ = int(0.10454f* b+0.60581f* g+0.28965f* r);
|
|
}
|
|
|
|
}else
|
|
{
|
|
std::cerr << "ERROR: fileformat not supported\n";
|
|
done = 0;
|
|
}
|
|
if(done) SetImageData(width, height, data, GL_LUMINANCE, GL_UNSIGNED_BYTE);
|
|
fclose(file);
|
|
delete data;
|
|
if(GlobalUtil::_verbose && done) std::cout<< "Image loaded :\t" << imagepath << "\n";
|
|
return 1;
|
|
#endif
|
|
}
|
|
|
|
int GLTexImage::CopyToPBO(GLuint pbo, int width, int height, GLenum format)
|
|
{
|
|
/////////
|
|
if(format != GL_RGBA && format != GL_LUMINANCE) return 0;
|
|
|
|
FrameBufferObject fbo;
|
|
GLint bsize, esize = width * height * sizeof(float) * (format == GL_RGBA ? 4 : 1);
|
|
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, format, GL_FLOAT, 0);
|
|
}
|
|
glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
|
|
DetachFBO(0);
|
|
|
|
return bsize >= esize;
|
|
}
|
|
|
|
void GLTexImage::SaveToASCII(const char* path)
|
|
{
|
|
vector<float> buf(GetImgWidth() * GetImgHeight() * 4);
|
|
FrameBufferObject fbo;
|
|
AttachToFBO(0);
|
|
glReadPixels(0, 0, GetImgWidth(), GetImgHeight(), GL_RGBA, GL_FLOAT, &buf[0]);
|
|
ofstream out(path);
|
|
|
|
for(int i = 0, idx = 0; i < GetImgHeight(); ++i)
|
|
{
|
|
for(int j = 0; j < GetImgWidth(); ++j, idx += 4)
|
|
{
|
|
out << i << " " << j << " " << buf[idx] << " " << buf[idx + 1] << " "
|
|
<< buf[idx + 2] << " " << buf[idx + 3] << "\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void GLTexInput::VerifyTexture()
|
|
{
|
|
//for CUDA or OpenCL the texture is not generated by default
|
|
if(!_data_modified) return;
|
|
if(_pixel_data== NULL) return;
|
|
InitTexture(_imgWidth, _imgHeight);
|
|
BindTex();
|
|
glTexImage2D( _texTarget, 0, GL_LUMINANCE32F_ARB, //internal format changed
|
|
_imgWidth, _imgHeight, 0,
|
|
GL_LUMINANCE, GL_FLOAT, _pixel_data);
|
|
UnbindTex();
|
|
_data_modified = 0;
|
|
}
|
|
|
|
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);
|
|
GlobalUtil::CheckErrorsGL("GLTexImage::CopyFromPBO->glTexSubImage2D");
|
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
|
|
UnbindTex();
|
|
}
|
|
}
|
|
|