00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00023
00024
00025 #include "GL/glew.h"
00026 #include <stdio.h>
00027 #include <iostream>
00028 #include <fstream>
00029 #include <vector>
00030 #include <algorithm>
00031 #include <stdlib.h>
00032 #include <math.h>
00033 using namespace std;
00034
00035
00036
00037 #include "GlobalUtil.h"
00038
00039 #include "GLTexImage.h"
00040 #include "FrameBufferObject.h"
00041 #include "ShaderMan.h"
00042
00043
00044
00045
00046 #ifndef SIFTGPU_NO_DEVIL
00047 #include "IL/il.h"
00048 #if defined(_WIN64)
00049 #pragma comment(lib, "../../lib/DevIL64.lib")
00050 #elif defined(_WIN32)
00051 #pragma comment(lib, "../../lib/DevIL.lib")
00052 #endif
00053 #else
00054 #include <string.h>
00055 #endif
00056
00057
00059
00060
00061 GLTexImage::GLTexImage()
00062 {
00063 _imgWidth = _imgHeight = 0;
00064 _texWidth = _texHeight = 0;
00065 _drawWidth = _drawHeight = 0;
00066 _texID = 0;
00067
00068 }
00069
00070 GLTexImage::~GLTexImage()
00071 {
00072 if(_texID) glDeleteTextures(1, &_texID);
00073 }
00074
00075 int GLTexImage::CheckTexture()
00076 {
00077 if(_texID)
00078 {
00079 GLint tw, th;
00080 BindTex();
00081 glGetTexLevelParameteriv(_texTarget, 0, GL_TEXTURE_WIDTH , &tw);
00082 glGetTexLevelParameteriv(_texTarget, 0, GL_TEXTURE_HEIGHT , &th);
00083 UnbindTex();
00084 return tw == _texWidth && th == _texHeight;
00085 }else
00086 {
00087 return _texWidth == 0 && _texHeight ==0;
00088
00089 }
00090 }
00091
00092
00093 void GLTexImage::SetImageSize( int width, int height)
00094 {
00095 _drawWidth = _imgWidth = width;
00096 _drawHeight = _imgHeight = height;
00097 }
00098
00099 void GLTexImage::InitTexture( int width, int height, int clamp_to_edge)
00100 {
00101
00102 if(_texID && width == _texWidth && height == _texHeight ) return;
00103 if(_texID==0) glGenTextures(1, &_texID);
00104
00105 _texWidth = _imgWidth = _drawWidth = width;
00106 _texHeight = _imgHeight = _drawHeight = height;
00107
00108 BindTex();
00109
00110 if(clamp_to_edge)
00111 {
00112 glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
00113 glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00114 }else
00115 {
00116
00117 glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
00118 glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
00119 }
00120 glTexParameteri(_texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00121 glTexParameteri(_texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00122 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00123
00124 glTexImage2D(_texTarget, 0, _iTexFormat,
00125 _texWidth, _texHeight, 0, GL_RGBA, GL_FLOAT, NULL);
00126 CheckErrorsGL("glTexImage2D");
00127
00128
00129 UnbindTex();
00130
00131 }
00132
00133
00134 void GLTexImage::InitTexture( int width, int height, int clamp_to_edge, GLuint format)
00135 {
00136
00137 if(_texID && width == _texWidth && height == _texHeight ) return;
00138 if(_texID==0) glGenTextures(1, &_texID);
00139
00140 _texWidth = _imgWidth = _drawWidth = width;
00141 _texHeight = _imgHeight = _drawHeight = height;
00142
00143 BindTex();
00144
00145 if(clamp_to_edge)
00146 {
00147 glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
00148 glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00149 }else
00150 {
00151
00152 glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
00153 glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
00154 }
00155 glTexParameteri(_texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00156 glTexParameteri(_texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00157 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00158
00159 glTexImage2D(_texTarget, 0, format, _texWidth, _texHeight, 0, GL_RGBA, GL_FLOAT, NULL);
00160
00161 UnbindTex();
00162
00163 }
00164 void GLTexImage::BindTex()
00165 {
00166 glBindTexture(_texTarget, _texID);
00167 }
00168
00169 void GLTexImage::UnbindTex()
00170 {
00171 glBindTexture(_texTarget, 0);
00172 }
00173
00174
00175 void GLTexImage::DrawQuad()
00176 {
00177 glBegin (GL_QUADS);
00178 glTexCoord2i ( 0 , 0 ); glVertex2i ( 0 , 0 );
00179 glTexCoord2i ( 0 , _drawHeight ); glVertex2i ( 0 , _drawHeight );
00180 glTexCoord2i ( _drawWidth , _drawHeight ); glVertex2i ( _drawWidth , _drawHeight );
00181 glTexCoord2i ( _drawWidth , 0 ); glVertex2i ( _drawWidth , 0 );
00182 glEnd ();
00183 glFlush();
00184 }
00185
00186 void GLTexImage::FillMargin(int marginx, int marginy)
00187 {
00188
00189 marginx = min(marginx, _texWidth - _imgWidth);
00190 marginy = min(marginy, _texHeight - _imgHeight);
00191 if(marginx >0 || marginy > 0)
00192 {
00193 GlobalUtil::FitViewPort(_imgWidth + marginx, _imgHeight + marginy);
00194 AttachToFBO(0);
00195 BindTex();
00196 ShaderMan::UseShaderMarginCopy(_imgWidth, _imgHeight);
00197 DrawMargin(_imgWidth + marginx, _imgHeight + marginy);
00198 }
00199 }
00200
00201 void GLTexImage::ZeroHistoMargin()
00202 {
00203 ZeroHistoMargin(_imgWidth, _imgHeight);
00204 }
00205
00206 void GLTexImage::ZeroHistoMargin(int width, int height)
00207 {
00208 int marginx = width & 0x01;
00209 int marginy = height & 0x01;
00210 if(marginx >0 || marginy > 0)
00211 {
00212 int right = width + marginx;
00213 int bottom = height + marginy;
00214 GlobalUtil::FitViewPort(right, bottom);
00215 AttachToFBO(0);
00216 ShaderMan::UseShaderZeroPass();
00217 glBegin(GL_QUADS);
00218 if(right > width && _texWidth > width)
00219 {
00220 glTexCoord2i ( width , 0 ); glVertex2i ( width , 0 );
00221 glTexCoord2i ( width , bottom ); glVertex2i ( width , bottom );
00222 glTexCoord2i ( right , bottom ); glVertex2i ( right , bottom );
00223 glTexCoord2i ( right , 0 ); glVertex2i ( right , 0 );
00224 }
00225 if(bottom>height && _texHeight > height)
00226 {
00227 glTexCoord2i ( 0 , height ); glVertex2i ( 0 , height );
00228 glTexCoord2i ( 0 , bottom ); glVertex2i ( 0 , bottom );
00229 glTexCoord2i ( width , bottom ); glVertex2i ( width , bottom );
00230 glTexCoord2i ( width , height ); glVertex2i ( width , height );
00231 }
00232 glEnd();
00233 glFlush();
00234 }
00235
00236 }
00237
00238 void GLTexImage::DrawMargin(int right, int bottom)
00239 {
00240 glBegin(GL_QUADS);
00241 if(right > _drawWidth)
00242 {
00243 glTexCoord2i ( _drawWidth , 0 ); glVertex2i ( _drawWidth , 0 );
00244 glTexCoord2i ( _drawWidth , bottom ); glVertex2i ( _drawWidth , bottom );
00245 glTexCoord2i ( right , bottom ); glVertex2i ( right , bottom );
00246 glTexCoord2i ( right , 0 ); glVertex2i ( right , 0 );
00247 }
00248 if(bottom>_drawHeight)
00249 {
00250 glTexCoord2i ( 0 , _drawHeight ); glVertex2i ( 0 , _drawHeight );
00251 glTexCoord2i ( 0 , bottom ); glVertex2i ( 0 , bottom );
00252 glTexCoord2i ( _drawWidth , bottom ); glVertex2i ( _drawWidth , bottom );
00253 glTexCoord2i ( _drawWidth , _drawHeight ); glVertex2i ( _drawWidth , _drawHeight );
00254 }
00255 glEnd();
00256 glFlush();
00257
00258
00259 }
00260
00261
00262 void GLTexImage::DrawQuadMT4()
00263 {
00264 int w = _drawWidth, h = _drawHeight;
00265 glBegin (GL_QUADS);
00266 glMultiTexCoord2i( GL_TEXTURE0, 0 , 0 );
00267 glMultiTexCoord2i( GL_TEXTURE1, -1 , 0 );
00268 glMultiTexCoord2i( GL_TEXTURE2, 1 , 0 );
00269 glMultiTexCoord2i( GL_TEXTURE3, 0 , -1 );
00270 glMultiTexCoord2i( GL_TEXTURE4, 0 , 1 );
00271 glVertex2i ( 0 , 0 );
00272
00273 glMultiTexCoord2i( GL_TEXTURE0, 0 , h );
00274 glMultiTexCoord2i( GL_TEXTURE1, -1 , h );
00275 glMultiTexCoord2i( GL_TEXTURE2, 1 , h );
00276 glMultiTexCoord2i( GL_TEXTURE3, 0 , h -1 );
00277 glMultiTexCoord2i( GL_TEXTURE4, 0 , h +1 );
00278 glVertex2i ( 0 , h );
00279
00280
00281 glMultiTexCoord2i( GL_TEXTURE0, w , h );
00282 glMultiTexCoord2i( GL_TEXTURE1, w-1 , h );
00283 glMultiTexCoord2i( GL_TEXTURE2, w+1 , h );
00284 glMultiTexCoord2i( GL_TEXTURE3, w , h-1 );
00285 glMultiTexCoord2i( GL_TEXTURE4, w , h+1 );
00286 glVertex2i ( w , h );
00287
00288 glMultiTexCoord2i( GL_TEXTURE0, w , 0 );
00289 glMultiTexCoord2i( GL_TEXTURE1, w-1 , 0 );
00290 glMultiTexCoord2i( GL_TEXTURE2, w+1 , 0 );
00291 glMultiTexCoord2i( GL_TEXTURE3, w , -1 );
00292 glMultiTexCoord2i( GL_TEXTURE4, w , 1 );
00293 glVertex2i ( w , 0 );
00294 glEnd ();
00295 glFlush();
00296 }
00297
00298
00299 void GLTexImage::DrawQuadMT8()
00300 {
00301 int w = _drawWidth;
00302 int h = _drawHeight;
00303 glBegin (GL_QUADS);
00304 glMultiTexCoord2i( GL_TEXTURE0, 0 , 0 );
00305 glMultiTexCoord2i( GL_TEXTURE1, -1 , 0 );
00306 glMultiTexCoord2i( GL_TEXTURE2, 1 , 0 );
00307 glMultiTexCoord2i( GL_TEXTURE3, 0 , -1 );
00308 glMultiTexCoord2i( GL_TEXTURE4, 0 , 1 );
00309 glMultiTexCoord2i( GL_TEXTURE5, -1 , -1 );
00310 glMultiTexCoord2i( GL_TEXTURE6, -1 , 1 );
00311 glMultiTexCoord2i( GL_TEXTURE7, 1 , -1 );
00312 glVertex2i ( 0 , 0 );
00313
00314 glMultiTexCoord2i( GL_TEXTURE0, 0 , h );
00315 glMultiTexCoord2i( GL_TEXTURE1, -1 , h );
00316 glMultiTexCoord2i( GL_TEXTURE2, 1 , h );
00317 glMultiTexCoord2i( GL_TEXTURE3, 0 , h -1 );
00318 glMultiTexCoord2i( GL_TEXTURE4, 0 , h +1 );
00319 glMultiTexCoord2i( GL_TEXTURE5, -1 , h -1 );
00320 glMultiTexCoord2i( GL_TEXTURE6, -1 , h +1 );
00321 glMultiTexCoord2i( GL_TEXTURE7, 1 , h -1 );
00322 glVertex2i ( 0 , h );
00323
00324
00325 glMultiTexCoord2i( GL_TEXTURE0, w , h );
00326 glMultiTexCoord2i( GL_TEXTURE1, w-1 , h );
00327 glMultiTexCoord2i( GL_TEXTURE2, w+1 , h );
00328 glMultiTexCoord2i( GL_TEXTURE3, w , h -1 );
00329 glMultiTexCoord2i( GL_TEXTURE4, w , h +1 );
00330 glMultiTexCoord2i( GL_TEXTURE5, w-1 , h -1 );
00331 glMultiTexCoord2i( GL_TEXTURE6, w-1 , h +1 );
00332 glMultiTexCoord2i( GL_TEXTURE7, w+1 , h -1 );
00333 glVertex2i ( w , h );
00334
00335 glMultiTexCoord2i( GL_TEXTURE0, w , 0 );
00336 glMultiTexCoord2i( GL_TEXTURE1, w-1 , 0 );
00337 glMultiTexCoord2i( GL_TEXTURE2, w+1 , 0 );
00338 glMultiTexCoord2i( GL_TEXTURE3, w , -1 );
00339 glMultiTexCoord2i( GL_TEXTURE4, w , 1 );
00340 glMultiTexCoord2i( GL_TEXTURE5, w-1 , -1 );
00341 glMultiTexCoord2i( GL_TEXTURE6, w-1 , 1 );
00342 glMultiTexCoord2i( GL_TEXTURE7, w+1 , -1 );
00343 glVertex2i ( w , 0 );
00344 glEnd ();
00345 glFlush();
00346 }
00347
00348
00349
00350
00351 void GLTexImage::DrawImage()
00352 {
00353 DrawQuad();
00354 }
00355
00356
00357
00358 void GLTexImage::FitTexViewPort()
00359 {
00360 GlobalUtil::FitViewPort(_drawWidth, _drawHeight);
00361 }
00362
00363 void GLTexImage::FitRealTexViewPort()
00364 {
00365 GlobalUtil::FitViewPort(_texWidth, _texHeight);
00366 }
00367
00368 void GLTexImage::AttachToFBO(int i)
00369 {
00370 glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, i+GL_COLOR_ATTACHMENT0_EXT, _texTarget, _texID, 0 );
00371 }
00372
00373 void GLTexImage::DetachFBO(int i)
00374 {
00375 glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, i+GL_COLOR_ATTACHMENT0_EXT, _texTarget, 0, 0 );
00376 }
00377
00378
00379 void GLTexImage::DrawQuad(float x1, float x2, float y1, float y2)
00380 {
00381
00382 glBegin (GL_QUADS);
00383 glTexCoord2f ( x1 , y1 ); glVertex2f ( x1 , y1 );
00384 glTexCoord2f ( x1 , y2 ); glVertex2f ( x1 , y2 );
00385 glTexCoord2f ( x2 , y2 ); glVertex2f ( x2 , y2 );
00386 glTexCoord2f ( x2 , y1 ); glVertex2f ( x2 , y1 );
00387 glEnd ();
00388 glFlush();
00389 }
00390
00391 void GLTexImage::TexConvertRGB()
00392 {
00393
00394 FrameBufferObject fbo;
00395
00396 FitTexViewPort();
00397
00398 AttachToFBO(0);
00399 ShaderMan::UseShaderRGB2Gray();
00400 glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
00401 DrawQuad();
00402 ShaderMan::UnloadProgram();
00403 DetachFBO(0);
00404 }
00405
00406 void GLTexImage::DrawQuadDS(int scale)
00407 {
00408 DrawScaledQuad(float(scale));
00409 }
00410
00411 void GLTexImage::DrawQuadUS(int scale)
00412 {
00413 DrawScaledQuad(1.0f/scale);
00414 }
00415
00416 void GLTexImage::DrawScaledQuad(float texscale)
00417 {
00418
00420 float to = 0.5f -0.5f * texscale;
00421 float tx = _imgWidth*texscale +to;
00422 float ty = _imgHeight*texscale +to;
00423 glBegin (GL_QUADS);
00424 glTexCoord2f ( to , to ); glVertex2i ( 0 , 0 );
00425 glTexCoord2f ( to , ty ); glVertex2i ( 0 , _imgHeight );
00426 glTexCoord2f ( tx , ty ); glVertex2i ( _imgWidth , _imgHeight );
00427 glTexCoord2f ( tx , to ); glVertex2i ( _imgWidth , 0 );
00428 glEnd ();
00429 glFlush();
00430 }
00431
00432
00433 void GLTexImage::DrawQuadReduction(int w , int h)
00434 {
00435 float to = -0.5f;
00436 float tx = w*2 +to;
00437 float ty = h*2 +to;
00438 glBegin (GL_QUADS);
00439 glMultiTexCoord2f ( GL_TEXTURE0, to , to );
00440 glMultiTexCoord2f ( GL_TEXTURE1, to +1, to );
00441 glMultiTexCoord2f ( GL_TEXTURE2, to , to+1 );
00442 glMultiTexCoord2f ( GL_TEXTURE3, to +1, to+1 );
00443 glVertex2i ( 0 , 0 );
00444
00445 glMultiTexCoord2f ( GL_TEXTURE0, to , ty );
00446 glMultiTexCoord2f ( GL_TEXTURE1, to +1, ty );
00447 glMultiTexCoord2f ( GL_TEXTURE2, to , ty +1 );
00448 glMultiTexCoord2f ( GL_TEXTURE3, to +1, ty +1 );
00449 glVertex2i ( 0 , h );
00450
00451 glMultiTexCoord2f ( GL_TEXTURE0, tx , ty );
00452 glMultiTexCoord2f ( GL_TEXTURE1, tx +1, ty );
00453 glMultiTexCoord2f ( GL_TEXTURE2, tx , ty +1);
00454 glMultiTexCoord2f ( GL_TEXTURE3, tx +1, ty +1);
00455
00456 glVertex2i ( w , h );
00457
00458 glMultiTexCoord2f ( GL_TEXTURE0, tx , to );
00459 glMultiTexCoord2f ( GL_TEXTURE1, tx +1, to );
00460 glMultiTexCoord2f ( GL_TEXTURE2, tx , to +1 );
00461 glMultiTexCoord2f ( GL_TEXTURE3, tx +1, to +1 );
00462 glVertex2i ( w , 0 );
00463 glEnd ();
00464
00465 glFlush();
00466 }
00467
00468
00469 void GLTexImage::DrawQuadReduction()
00470 {
00471 float to = -0.5f;
00472 float tx = _drawWidth*2 +to;
00473 float ty = _drawHeight*2 +to;
00474 glBegin (GL_QUADS);
00475 glMultiTexCoord2f ( GL_TEXTURE0, to , to );
00476 glMultiTexCoord2f ( GL_TEXTURE1, to +1, to );
00477 glMultiTexCoord2f ( GL_TEXTURE2, to , to+1 );
00478 glMultiTexCoord2f ( GL_TEXTURE3, to +1, to+1 );
00479 glVertex2i ( 0 , 0 );
00480
00481 glMultiTexCoord2f ( GL_TEXTURE0, to , ty );
00482 glMultiTexCoord2f ( GL_TEXTURE1, to +1, ty );
00483 glMultiTexCoord2f ( GL_TEXTURE2, to , ty +1 );
00484 glMultiTexCoord2f ( GL_TEXTURE3, to +1, ty +1 );
00485 glVertex2i ( 0 , _drawHeight );
00486
00487 glMultiTexCoord2f ( GL_TEXTURE0, tx , ty );
00488 glMultiTexCoord2f ( GL_TEXTURE1, tx +1, ty );
00489 glMultiTexCoord2f ( GL_TEXTURE2, tx , ty +1);
00490 glMultiTexCoord2f ( GL_TEXTURE3, tx +1, ty +1);
00491
00492 glVertex2i ( _drawWidth , _drawHeight );
00493
00494 glMultiTexCoord2f ( GL_TEXTURE0, tx , to );
00495 glMultiTexCoord2f ( GL_TEXTURE1, tx +1, to );
00496 glMultiTexCoord2f ( GL_TEXTURE2, tx , to +1 );
00497 glMultiTexCoord2f ( GL_TEXTURE3, tx +1, to +1 );
00498 glVertex2i ( _drawWidth , 0 );
00499 glEnd ();
00500
00501 glFlush();
00502 }
00503
00504 void GLTexPacked::TexConvertRGB()
00505 {
00506
00507 _drawWidth = (1 + _imgWidth) >> 1;
00508 _drawHeight = (1 + _imgHeight) >> 1;
00510 FrameBufferObject fbo;
00511 GLuint oldTexID = _texID;
00512 glGenTextures(1, &_texID);
00513 glBindTexture(_texTarget, _texID);
00514 glTexImage2D(_texTarget, 0, _iTexFormat, _texWidth, _texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
00515
00516
00517 glBindTexture(_texTarget, oldTexID);
00518
00519 AttachToFBO(0);
00520
00521 ShaderMan::UseShaderRGB2Gray();
00522
00523 glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
00524
00525 DrawQuadDS(2);
00526 ShaderMan::UnloadProgram();
00527
00528 glDeleteTextures(1, &oldTexID);
00529 DetachFBO(0);
00530 }
00531
00532
00533 void GLTexPacked::SetImageSize( int width, int height)
00534 {
00535 _imgWidth = width; _drawWidth = (width + 1) >> 1;
00536 _imgHeight = height; _drawHeight = (height + 1) >> 1;
00537 }
00538
00539 void GLTexPacked::InitTexture( int width, int height, int clamp_to_edge)
00540 {
00541
00542 if(_texID && width == _imgWidth && height == _imgHeight ) return;
00543 if(_texID==0) glGenTextures(1, &_texID);
00544
00545 _imgWidth = width;
00546 _imgHeight = height;
00547 if(GlobalUtil::_PreciseBorder)
00548 {
00549 _texWidth = (width + 2) >> 1;
00550 _texHeight = (height + 2) >> 1;
00551 }else
00552 {
00553 _texWidth = (width + 1) >> 1;
00554 _texHeight = (height + 1) >> 1;
00555 }
00556 _drawWidth = (width + 1) >> 1;
00557 _drawHeight = (height + 1) >> 1;
00558
00559 BindTex();
00560
00561 if(clamp_to_edge)
00562 {
00563 glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
00564 glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00565 }else
00566 {
00567
00568 glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
00569 glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
00570 }
00571 glTexParameteri(_texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00572 glTexParameteri(_texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00573 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00574
00575 glTexImage2D(_texTarget, 0, _iTexFormat,
00576 _texWidth, _texHeight, 0, GL_RGBA, GL_FLOAT, NULL);
00577
00578 UnbindTex();
00579
00580 }
00581
00582
00583 void GLTexPacked::DrawImage()
00584 {
00585 float x1 =0, y1 = 0;
00586 float x2 = _imgWidth*0.5f +x1;
00587 float y2 = _imgHeight*0.5f + y1;
00588 glBegin (GL_QUADS);
00589 glTexCoord2f ( x1 , y1 ); glVertex2i ( 0 , 0 );
00590 glTexCoord2f ( x1 , y2 ); glVertex2i ( 0 , _imgHeight );
00591 glTexCoord2f ( x2 , y2 ); glVertex2i ( _imgWidth , _imgHeight );
00592 glTexCoord2f ( x2 , y1 ); glVertex2i ( _imgWidth , 0 );
00593 glEnd ();
00594 glFlush();
00595 }
00596
00597 void GLTexPacked::DrawQuadUS(int scale)
00598 {
00599 int tw =_drawWidth, th = _drawHeight;
00600 float texscale = 1.0f / scale;
00601 float x1 = 0.5f - 0.5f*scale, y1 = x1;
00602 float x2 = tw * texscale + x1;
00603 float y2 = th * texscale + y1;
00604 float step = texscale *0.5f;
00605 glBegin (GL_QUADS);
00606 glMultiTexCoord2f( GL_TEXTURE0, x1 , y1 );
00607 glMultiTexCoord2f( GL_TEXTURE1, x1+step , y1 );
00608 glMultiTexCoord2f( GL_TEXTURE2, x1 , y1 +step);
00609 glMultiTexCoord2f( GL_TEXTURE3, x1+step , y1 +step);
00610 glVertex2i ( 0 , 0 );
00611
00612 glMultiTexCoord2f( GL_TEXTURE0, x1 , y2 );
00613 glMultiTexCoord2f( GL_TEXTURE1, x1+step , y2 );
00614 glMultiTexCoord2f( GL_TEXTURE2, x1 , y2 +step);
00615 glMultiTexCoord2f( GL_TEXTURE3, x1+step , y2 +step);
00616 glVertex2i ( 0 , th );
00617
00618 glMultiTexCoord2f( GL_TEXTURE0, x2 , y2 );
00619 glMultiTexCoord2f( GL_TEXTURE1, x2+step , y2 );
00620 glMultiTexCoord2f( GL_TEXTURE2, x2 , y2 +step);
00621 glMultiTexCoord2f( GL_TEXTURE3, x2+step , y2 +step);
00622 glVertex2i ( tw , th );
00623
00624 glMultiTexCoord2f( GL_TEXTURE0, x2 , y1 );
00625 glMultiTexCoord2f( GL_TEXTURE1, x2+step , y1 );
00626 glMultiTexCoord2f( GL_TEXTURE2, x2 , y1 +step);
00627 glMultiTexCoord2f( GL_TEXTURE3, x2+step , y1 +step);
00628 glVertex2i ( tw , 0 );
00629 glEnd ();
00630 }
00631
00632 void GLTexPacked::DrawQuadDS(int scale)
00633 {
00634 int tw = _drawWidth;
00635 int th = _drawHeight;
00636 float x1 = 0.5f - 0.5f*scale;
00637 float x2 = tw * scale + x1;
00638 float y1 = 0.5f - 0.5f * scale;
00639 float y2 = th * scale + y1;
00640 int step = scale / 2;
00641
00642 glBegin (GL_QUADS);
00643 glMultiTexCoord2f( GL_TEXTURE0, x1 , y1 );
00644 glMultiTexCoord2f( GL_TEXTURE1, x1+step , y1 );
00645 glMultiTexCoord2f( GL_TEXTURE2, x1 , y1 +step);
00646 glMultiTexCoord2f( GL_TEXTURE3, x1+step , y1 +step);
00647 glVertex2i ( 0 , 0 );
00648
00649 glMultiTexCoord2f( GL_TEXTURE0, x1 , y2 );
00650 glMultiTexCoord2f( GL_TEXTURE1, x1+step , y2 );
00651 glMultiTexCoord2f( GL_TEXTURE2, x1 , y2 +step);
00652 glMultiTexCoord2f( GL_TEXTURE3, x1+step , y2 +step);
00653 glVertex2i ( 0 , th );
00654
00655 glMultiTexCoord2f( GL_TEXTURE0, x2 , y2 );
00656 glMultiTexCoord2f( GL_TEXTURE1, x2+step , y2 );
00657 glMultiTexCoord2f( GL_TEXTURE2, x2 , y2 +step);
00658 glMultiTexCoord2f( GL_TEXTURE3, x2+step , y2 +step);
00659 glVertex2i ( tw , th );
00660
00661 glMultiTexCoord2f( GL_TEXTURE0, x2 , y1 );
00662 glMultiTexCoord2f( GL_TEXTURE1, x2+step , y1 );
00663 glMultiTexCoord2f( GL_TEXTURE2, x2 , y1 +step);
00664 glMultiTexCoord2f( GL_TEXTURE3, x2+step , y1 +step);
00665 glVertex2i ( tw , 0 );
00666 glEnd ();
00667 }
00668
00669 void GLTexPacked::ZeroHistoMargin()
00670 {
00671 int marginx = (((_imgWidth + 3) /4)*4) - _imgWidth;
00672 int marginy = (((-_imgHeight + 3)/4)*4) - _imgHeight;
00673 if(marginx >0 || marginy > 0)
00674 {
00675 int tw = (_imgWidth + marginx ) >> 1;
00676 int th = (_imgHeight + marginy ) >> 1;
00677 tw = min(_texWidth, tw );
00678 th = min(_texHeight, th);
00679 GlobalUtil::FitViewPort(tw, th);
00680 AttachToFBO(0);
00681 BindTex();
00682 ShaderMan::UseShaderZeroPass();
00683 DrawMargin(tw, th, 1, 1);
00684 }
00685 }
00686
00687
00688 void GLTexPacked::FillMargin(int marginx, int marginy)
00689 {
00690
00691 marginx = min(marginx, _texWidth * 2 - _imgWidth);
00692 marginy = min(marginy, _texHeight * 2 - _imgHeight);
00693 if(marginx >0 || marginy > 0)
00694 {
00695 int tw = (_imgWidth + marginx + 1) >> 1;
00696 int th = (_imgHeight + marginy + 1) >> 1;
00697 GlobalUtil::FitViewPort(tw, th);
00698 BindTex();
00699 AttachToFBO(0);
00700 ShaderMan::UseShaderMarginCopy(_imgWidth , _imgHeight);
00701 DrawMargin(tw, th, marginx, marginy);
00702 }
00703 }
00704 void GLTexPacked::DrawMargin(int right, int bottom, int mx, int my)
00705 {
00706 int tw = (_imgWidth >>1);
00707 int th = (_imgHeight >>1);
00708 glBegin(GL_QUADS);
00709 if(right>tw && mx)
00710 {
00711 glTexCoord2i ( tw , 0 ); glVertex2i ( tw , 0 );
00712 glTexCoord2i ( tw , bottom ); glVertex2i ( tw , bottom );
00713 glTexCoord2i ( right, bottom ); glVertex2i ( right, bottom );
00714 glTexCoord2i ( right, 0 ); glVertex2i ( right, 0 );
00715 }
00716 if(bottom>th && my)
00717 {
00718 glTexCoord2i ( 0 , th ); glVertex2i ( 0 , th );
00719 glTexCoord2i ( 0 , bottom ); glVertex2i ( 0 , bottom );
00720 glTexCoord2i ( tw , bottom ); glVertex2i ( tw , bottom );
00721 glTexCoord2i ( tw , th ); glVertex2i ( tw , th );
00722 }
00723 glEnd();
00724 glFlush();
00725
00726 }
00727
00728
00729 void GLTexImage::UnbindMultiTex(int n)
00730 {
00731 for(int i = n-1; i>=0; i--)
00732 {
00733 glActiveTexture(GL_TEXTURE0+i);
00734 glBindTexture(_texTarget, 0);
00735 }
00736 }
00737
00738 template <class Uint> int
00739
00740 #if !defined(_MSC_VER) || _MSC_VER > 1200
00741 GLTexInput::
00742 #endif
00743
00744 DownSamplePixelDataI(unsigned int gl_format, int width, int height, int ds,
00745 const Uint * pin, Uint * pout)
00746 {
00747 int step, linestep;
00748 int i, j;
00749 int ws = width/ds;
00750 int hs = height/ds;
00751 const Uint * line = pin, * p;
00752 Uint *po = pout;
00753 switch(gl_format)
00754 {
00755 case GL_LUMINANCE:
00756 case GL_LUMINANCE_ALPHA:
00757 step = ds * (gl_format == GL_LUMINANCE? 1: 2);
00758 linestep = width * step;
00759 for(i = 0 ; i < hs; i++, line+=linestep)
00760 {
00761 for(j = 0, p = line; j < ws; j++, p+=step)
00762 {
00763 *po++ = *p;
00764 }
00765 }
00766 break;
00767 case GL_RGB:
00768 case GL_RGBA:
00769 step = ds * (gl_format == GL_RGB? 3: 4);
00770 linestep = width * step;
00771
00772 for(i = 0 ; i < hs; i++, line+=linestep)
00773 {
00774 for(j = 0, p = line; j < ws; j++, p+=step)
00775 {
00776
00777 *po++ = ((19595*p[0] + 38470*p[1] + 7471*p[2]+ 32768)>>16);
00778 }
00779 }
00780 break;
00781 case GL_BGR:
00782 case GL_BGRA:
00783 step = ds * (gl_format == GL_BGR? 3: 4);
00784 linestep = width * step;
00785 for(i = 0 ; i < hs; i++, line+=linestep)
00786 {
00787 for(j = 0, p = line; j < ws; j++, p+=step)
00788 {
00789 *po++ = ((7471*p[0] + 38470*p[1] + 19595*p[2]+ 32768)>>16);
00790 }
00791 }
00792 break;
00793 default:
00794 return 0;
00795 }
00796
00797 return 1;
00798
00799 }
00800
00801
00802 template <class Uint> int
00803
00804 #if !defined(_MSC_VER) || _MSC_VER > 1200
00805 GLTexInput::
00806 #endif
00807
00808 DownSamplePixelDataI2F(unsigned int gl_format, int width, int height, int ds,
00809 const Uint * pin, float * pout, int skip)
00810 {
00811 int step, linestep;
00812 int i, j;
00813 int ws = width/ds - skip;
00814 int hs = height/ds;
00815 const Uint * line = pin, * p;
00816 float *po = pout;
00817 const float factor = (sizeof(Uint) == 1? 255.0f : 65535.0f);
00818 switch(gl_format)
00819 {
00820 case GL_LUMINANCE:
00821 case GL_LUMINANCE_ALPHA:
00822 step = ds * (gl_format == GL_LUMINANCE? 1: 2);
00823 linestep = width * step;
00824 for(i = 0 ; i < hs; i++, line+=linestep)
00825 {
00826 for(j = 0, p = line; j < ws; j++, p+=step)
00827 {
00828 *po++ = (*p) / factor;
00829 }
00830 }
00831 break;
00832 case GL_RGB:
00833 case GL_RGBA:
00834 step = ds * (gl_format == GL_RGB? 3: 4);
00835 linestep = width * step;
00836
00837 for(i = 0 ; i < hs; i++, line+=linestep)
00838 {
00839 for(j = 0, p = line; j < ws; j++, p+=step)
00840 {
00841
00842 *po++ = ((19595*p[0] + 38470*p[1] + 7471*p[2]) / (65535.0f * factor));
00843 }
00844 }
00845 break;
00846 case GL_BGR:
00847 case GL_BGRA:
00848 step = ds * (gl_format == GL_BGR? 3: 4);
00849 linestep = width * step;
00850 for(i = 0 ; i < hs; i++, line+=linestep)
00851 {
00852 for(j = 0, p = line; j < ws; j++, p+=step)
00853 {
00854 *po++ = ((7471*p[0] + 38470*p[1] + 19595*p[2]) / (65535.0f * factor));
00855 }
00856 }
00857 break;
00858 default:
00859 return 0;
00860 }
00861 return 1;
00862 }
00863
00864 int GLTexInput::DownSamplePixelDataF(unsigned int gl_format, int width, int height, int ds, const float * pin, float * pout, int skip)
00865 {
00866 int step, linestep;
00867 int i, j;
00868 int ws = width/ds - skip;
00869 int hs = height/ds;
00870 const float * line = pin, * p;
00871 float *po = pout;
00872 switch(gl_format)
00873 {
00874 case GL_LUMINANCE:
00875 case GL_LUMINANCE_ALPHA:
00876 step = ds * (gl_format == GL_LUMINANCE? 1: 2);
00877 linestep = width * step;
00878 for(i = 0 ; i < hs; i++, line+=linestep)
00879 {
00880 for(j = 0, p = line; j < ws; j++, p+=step)
00881 {
00882 *po++ = *p;
00883 }
00884 }
00885 break;
00886 case GL_RGB:
00887 case GL_RGBA:
00888 step = ds * (gl_format == GL_RGB? 3: 4);
00889 linestep = width * step;
00890 for(i = 0 ; i < hs; i++, line+=linestep)
00891 {
00892 for(j = 0, p = line; j < ws; j++, p+=step)
00893 {
00894 *po++ = (0.299f*p[0] + 0.587f*p[1] + 0.114f*p[2]);
00895 }
00896 }
00897 break;
00898 case GL_BGR:
00899 case GL_BGRA:
00900 step = ds * (gl_format == GL_BGR? 3: 4);
00901 linestep = width * step;
00902 for(i = 0 ; i < hs; i++, line+=linestep)
00903 {
00904 for(j = 0, p = line; j < ws; j++, p+=step)
00905 {
00906 *po++ = (0.114f*p[0] + 0.587f*p[1] + 0.299f * p[2]);
00907 }
00908 }
00909 break;
00910 default:
00911 return 0;
00912 }
00913
00914 return 1;
00915
00916 }
00917
00918 int GLTexInput::SetImageData( int width, int height, const void * data,
00919 unsigned int gl_format, unsigned int gl_type )
00920 {
00921 int simple_format = IsSimpleGlFormat(gl_format, gl_type);
00922 int ws, hs, done = 1;
00923
00924 if(_converted_data) {delete [] _converted_data; _converted_data = NULL; }
00925
00926 _rgb_converted = 1;
00927 _data_modified = 0;
00928
00929 if( simple_format
00930 && ( width > _texMaxDim || height > _texMaxDim || GlobalUtil::_PreProcessOnCPU)
00931 && GlobalUtil::_octave_min_default >0 )
00932 {
00933 _down_sampled = GlobalUtil::_octave_min_default;
00934 ws = width >> GlobalUtil::_octave_min_default;
00935 hs = height >> GlobalUtil::_octave_min_default;
00936 }else
00937 {
00938 _down_sampled = 0;
00939 ws = width;
00940 hs = height;
00941 }
00942
00943 if ( ws > _texMaxDim || hs > _texMaxDim)
00944 {
00945 if(simple_format)
00946 {
00947 if(GlobalUtil::_verbose) std::cout<<"Automatic down-sampling is used\n";
00948 do
00949 {
00950 _down_sampled ++;
00951 ws >>= 1;
00952 hs >>= 1;
00953 }while(ws > _texMaxDim || hs > _texMaxDim);
00954 }else
00955 {
00956 std::cerr<<"Input images is too big to fit into a texture\n";
00957 return 0;
00958 }
00959 }
00960
00961 _texWidth = _imgWidth = _drawWidth = ws;
00962 _texHeight = _imgHeight = _drawHeight = hs;
00963
00964 if(GlobalUtil::_verbose)
00965 {
00966 std::cout<<"Image size :\t"<<width<<"x"<<height<<"\n";
00967 if(_down_sampled >0) std::cout<<"Down sample to \t"<<ws<<"x"<<hs<<"\n";
00968 }
00969
00970
00971 if(GlobalUtil::_UseCUDA || GlobalUtil::_UseOpenCL)
00972 {
00974 int tWidth = TruncateWidthCU(_imgWidth);
00975 int skip = _imgWidth - tWidth;
00976
00977 if(!simple_format)
00978 {
00979 std::cerr << "Input format not supported under current settings.\n";
00980 return 0;
00981 }else if(_down_sampled > 0 || gl_format != GL_LUMINANCE || gl_type != GL_FLOAT)
00982 {
00983 _converted_data = new float [_imgWidth * _imgHeight];
00984 if(gl_type == GL_UNSIGNED_BYTE)
00985 DownSamplePixelDataI2F(gl_format, width, height, 1<<_down_sampled,
00986 ((const unsigned char*) data), _converted_data, skip);
00987 else if(gl_type == GL_UNSIGNED_SHORT)
00988 DownSamplePixelDataI2F(gl_format, width, height, 1<<_down_sampled,
00989 ((const unsigned short*) data), _converted_data, skip);
00990 else
00991 DownSamplePixelDataF(gl_format, width, height, 1<<_down_sampled, (float*)data, _converted_data, skip);
00992 _rgb_converted = 2;
00993 _pixel_data = _converted_data;
00994 }else
00995 {
00996
00997 _rgb_converted = 1;
00998 _pixel_data = data;
00999 if(skip > 0)
01000 {
01001 for(int i = 1; i < _imgHeight; ++i)
01002 {
01003 float * dst = ((float*)data) + i * tWidth, * src = ((float*)data) + i * _imgWidth;
01004 for(int j = 0; j < tWidth; ++j) *dst++ = * src++;
01005 }
01006 }
01007 }
01008 _texWidth = _imgWidth = _drawWidth = tWidth;
01009 _data_modified = 1;
01010 }else
01011 {
01012 if(_texID ==0) glGenTextures(1, &_texID);
01013 glBindTexture(_texTarget, _texID);
01014 CheckErrorsGL("glBindTexture");
01015 glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
01016 glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
01017 glPixelStorei(GL_UNPACK_ALIGNMENT , 1);
01018
01019 if(simple_format && ( _down_sampled> 0 || (gl_format != GL_LUMINANCE && GlobalUtil::_PreProcessOnCPU) ))
01020 {
01021
01022 if(gl_type == GL_UNSIGNED_BYTE)
01023 {
01024 unsigned char * newdata = new unsigned char [_imgWidth * _imgHeight];
01025 DownSamplePixelDataI(gl_format, width, height, 1<<_down_sampled, ((const unsigned char*) data), newdata);
01026 glTexImage2D(_texTarget, 0, GL_LUMINANCE32F_ARB,
01027 _imgWidth, _imgHeight, 0,
01028 GL_LUMINANCE, GL_UNSIGNED_BYTE, newdata);
01029 delete[] newdata;
01030 }else if(gl_type == GL_UNSIGNED_SHORT)
01031 {
01032 unsigned short * newdata = new unsigned short [_imgWidth * _imgHeight];
01033 DownSamplePixelDataI(gl_format, width, height, 1<<_down_sampled, ((const unsigned short*) data), newdata);
01034
01035 glTexImage2D(_texTarget, 0, GL_LUMINANCE32F_ARB,
01036 _imgWidth, _imgHeight, 0,
01037 GL_LUMINANCE, GL_UNSIGNED_SHORT, newdata);
01038 delete[] newdata;
01039 }else if(gl_type == GL_FLOAT)
01040 {
01041 float * newdata = new float [_imgWidth * _imgHeight];
01042 DownSamplePixelDataF(gl_format, width, height, 1<<_down_sampled, (float*)data, newdata);
01043 glTexImage2D(_texTarget, 0, GL_LUMINANCE32F_ARB,
01044 _imgWidth, _imgHeight, 0,
01045 GL_LUMINANCE, GL_FLOAT, newdata);
01046 delete[] newdata;
01047 }else
01048 {
01049
01050 done = 0;
01051 _rgb_converted = 0;
01052 }
01053 GlobalUtil::FitViewPort(1, 1);
01054 }else
01055 {
01056
01057 if(gl_format == GL_LUMINANCE || gl_format == GL_LUMINANCE_ALPHA)
01058 {
01059
01060 glTexImage2D(_texTarget, 0, GL_LUMINANCE32F_ARB,
01061 _imgWidth, _imgHeight, 0, gl_format, gl_type, data);
01062 GlobalUtil::FitViewPort(1, 1);
01063 }
01064 else
01065 {
01066
01067 glTexImage2D(_texTarget, 0, _iTexFormat, _imgWidth, _imgHeight, 0, gl_format, gl_type, data);
01068 if(ShaderMan::HaveShaderMan())
01069 TexConvertRGB();
01070 else
01071 _rgb_converted = 0;
01072 }
01073 }
01074 UnbindTex();
01075 }
01076 return done;
01077 }
01078
01079
01080 GLTexInput::~GLTexInput()
01081 {
01082 if(_converted_data) delete [] _converted_data;
01083 }
01084
01085
01086 int GLTexInput::LoadImageFile(char *imagepath, int &w, int &h )
01087 {
01088 #ifndef SIFTGPU_NO_DEVIL
01089 static int devil_loaded = 0;
01090 unsigned int imID;
01091 int done = 1;
01092
01093 if(devil_loaded == 0)
01094 {
01095 ilInit();
01096 ilOriginFunc(IL_ORIGIN_UPPER_LEFT);
01097 ilEnable(IL_ORIGIN_SET);
01098 devil_loaded = 1;
01099 }
01100
01102 ilGenImages(1, &imID);
01103 ilBindImage(imID);
01104
01105 if(ilLoadImage(imagepath))
01106 {
01107 w = ilGetInteger(IL_IMAGE_WIDTH);
01108 h = ilGetInteger(IL_IMAGE_HEIGHT);
01109 int ilformat = ilGetInteger(IL_IMAGE_FORMAT);
01110
01111 if(SetImageData(w, h, ilGetData(), ilformat, GL_UNSIGNED_BYTE)==0)
01112 {
01113 done =0;
01114 }else if(GlobalUtil::_verbose)
01115 {
01116 std::cout<<"Image loaded :\t"<<imagepath<<"\n";
01117 }
01118
01119 }else
01120 {
01121 std::cerr<<"Unable to open image [code = "<<ilGetError()<<"]\n";
01122 done = 0;
01123 }
01124
01125 ilDeleteImages(1, &imID);
01126
01127 return done;
01128 #else
01129 FILE * file = fopen(imagepath, "rb"); if (file ==NULL) return 0;
01130
01131 char buf[8]; int width, height, cn, g, done = 1;
01132
01133 if(fscanf(file, "%s %d %d %d", buf, &width, &height, &cn )<4 || cn > 255 || width < 0 || height < 0)
01134 {
01135 fclose(file);
01136 std::cerr << "ERROR: fileformat not supported\n";
01137 return 0;
01138 }else
01139 {
01140 w = width;
01141 h = height;
01142 }
01143 unsigned char * data = new unsigned char[width * height];
01144 unsigned char * pixels = data;
01145 if (strcmp(buf, "P5")==0 )
01146 {
01147 fscanf(file, "%c",buf);
01148 fread(pixels, 1, width*height, file);
01149 }else if (strcmp(buf, "P2")==0 )
01150 {
01151 for (int i = 0 ; i< height; i++)
01152 {
01153 for ( int j = 0; j < width; j++)
01154 {
01155 fscanf(file, "%d", &g);
01156 *pixels++ = (unsigned char) g;
01157 }
01158 }
01159 }else if (strcmp(buf, "P6")==0 )
01160 {
01161 fscanf(file, "%c", buf);
01162 int j, num = height*width;
01163 unsigned char buf[3];
01164 for ( j =0 ; j< num; j++)
01165 {
01166 fread(buf,1,3, file);
01167 *pixels++=int(0.10454f* buf[2]+0.60581f* buf[1]+0.28965f* buf[0]);
01168 }
01169 }else if (strcmp(buf, "P3")==0 )
01170 {
01171 int r, g, b;
01172 int i , num =height*width;
01173 for ( i = 0 ; i< num; i++)
01174 {
01175 fscanf(file, "%d %d %d", &r, &g, &b);
01176 *pixels++ = int(0.10454f* b+0.60581f* g+0.28965f* r);
01177 }
01178
01179 }else
01180 {
01181 std::cerr << "ERROR: fileformat not supported\n";
01182 done = 0;
01183 }
01184 if(done) SetImageData(width, height, data, GL_LUMINANCE, GL_UNSIGNED_BYTE);
01185 fclose(file);
01186 delete[] data;
01187 if(GlobalUtil::_verbose && done) std::cout<< "Image loaded :\t" << imagepath << "\n";
01188 return 1;
01189 #endif
01190 }
01191
01192 int GLTexImage::CopyToPBO(GLuint pbo, int width, int height, GLenum format)
01193 {
01195 if(format != GL_RGBA && format != GL_LUMINANCE) return 0;
01196
01197 FrameBufferObject fbo;
01198 GLint bsize, esize = width * height * sizeof(float) * (format == GL_RGBA ? 4 : 1);
01199 AttachToFBO(0);
01200 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, pbo);
01201 glGetBufferParameteriv(GL_PIXEL_PACK_BUFFER_ARB, GL_BUFFER_SIZE, &bsize);
01202 if(bsize < esize)
01203 {
01204 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, esize, NULL, GL_STATIC_DRAW_ARB);
01205 glGetBufferParameteriv(GL_PIXEL_PACK_BUFFER_ARB, GL_BUFFER_SIZE, &bsize);
01206 }
01207 if(bsize >= esize)
01208 {
01209 glReadPixels(0, 0, width, height, format, GL_FLOAT, 0);
01210 }
01211 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
01212 DetachFBO(0);
01213
01214 return bsize >= esize;
01215 }
01216
01217 void GLTexImage::SaveToASCII(const char* path)
01218 {
01219 vector<float> buf(GetImgWidth() * GetImgHeight() * 4);
01220 FrameBufferObject fbo;
01221 AttachToFBO(0);
01222 glReadPixels(0, 0, GetImgWidth(), GetImgHeight(), GL_RGBA, GL_FLOAT, &buf[0]);
01223 ofstream out(path);
01224
01225 for(int i = 0, idx = 0; i < GetImgHeight(); ++i)
01226 {
01227 for(int j = 0; j < GetImgWidth(); ++j, idx += 4)
01228 {
01229 out << i << " " << j << " " << buf[idx] << " " << buf[idx + 1] << " "
01230 << buf[idx + 2] << " " << buf[idx + 3] << "\n";
01231 }
01232 }
01233 }
01234
01235
01236 void GLTexInput::VerifyTexture()
01237 {
01238
01239 if(!_data_modified) return;
01240 if(_pixel_data== NULL) return;
01241 InitTexture(_imgWidth, _imgHeight);
01242 BindTex();
01243 glTexImage2D( _texTarget, 0, GL_LUMINANCE32F_ARB,
01244 _imgWidth, _imgHeight, 0,
01245 GL_LUMINANCE, GL_FLOAT, _pixel_data);
01246 UnbindTex();
01247 _data_modified = 0;
01248 }
01249
01250 void GLTexImage::CopyFromPBO(GLuint pbo, int width, int height, GLenum format)
01251 {
01252 InitTexture(max(width, _texWidth), max(height, _texHeight));
01253 SetImageSize(width, height);
01254 if(width > 0 && height > 0)
01255 {
01256 BindTex();
01257 glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
01258 glTexSubImage2D(GlobalUtil::_texTarget, 0, 0, 0, width, height, format, GL_FLOAT, 0);
01259 GlobalUtil::CheckErrorsGL("GLTexImage::CopyFromPBO->glTexSubImage2D");
01260 glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
01261 UnbindTex();
01262 }
01263 }
01264