root / rgbdslam / external / siftgpu / src / SiftGPU / GLTexImage.cpp @ 9240aaa3
History | View | Annotate | Download (34.4 KB)
1 | 9240aaa3 | Alex | ////////////////////////////////////////////////////////////////////////////
|
---|---|---|---|
2 | // File: GLTexImage.cpp
|
||
3 | // Author: Changchang Wu
|
||
4 | // Description : implementation of the GLTexImage class.
|
||
5 | //
|
||
6 | //
|
||
7 | //
|
||
8 | // Copyright (c) 2007 University of North Carolina at Chapel Hill
|
||
9 | // All Rights Reserved
|
||
10 | //
|
||
11 | // Permission to use, copy, modify and distribute this software and its
|
||
12 | // documentation for educational, research and non-profit purposes, without
|
||
13 | // fee, and without a written agreement is hereby granted, provided that the
|
||
14 | // above copyright notice and the following paragraph appear in all copies.
|
||
15 | //
|
||
16 | // The University of North Carolina at Chapel Hill make no representations
|
||
17 | // about the suitability of this software for any purpose. It is provided
|
||
18 | // 'as is' without express or implied warranty.
|
||
19 | //
|
||
20 | // Please send BUG REPORTS to ccwu@cs.unc.edu
|
||
21 | //
|
||
22 | ////////////////////////////////////////////////////////////////////////////
|
||
23 | |||
24 | |||
25 | #include "GL/glew.h" |
||
26 | #include <stdio.h> |
||
27 | #include <iostream> |
||
28 | #include <vector> |
||
29 | #include <algorithm> |
||
30 | #include <stdlib.h> |
||
31 | #include <math.h> |
||
32 | using namespace std; |
||
33 | |||
34 | |||
35 | |||
36 | #include "GlobalUtil.h" |
||
37 | |||
38 | #include "GLTexImage.h" |
||
39 | #include "FrameBufferObject.h" |
||
40 | #include "ShaderMan.h" |
||
41 | |||
42 | #ifndef SIFTGPU_NO_DEVIL
|
||
43 | #include "IL/il.h" |
||
44 | #if defined(_WIN64)
|
||
45 | #pragma comment(lib, "../../lib/DevIL64.lib") |
||
46 | #elif defined(_WIN32)
|
||
47 | #pragma comment(lib, "../../lib/DevIL.lib") |
||
48 | #endif
|
||
49 | #endif
|
||
50 | //////////////////////////////////////////////////////////////////////
|
||
51 | // Construction/Destruction
|
||
52 | //////////////////////////////////////////////////////////////////////
|
||
53 | |||
54 | |||
55 | GLTexImage::GLTexImage() |
||
56 | { |
||
57 | _imgWidth = _imgHeight = 0;
|
||
58 | _texWidth = _texHeight = 0;
|
||
59 | _drawWidth = _drawHeight = 0;
|
||
60 | _texID = 0;
|
||
61 | |||
62 | } |
||
63 | |||
64 | GLTexImage::~GLTexImage() |
||
65 | { |
||
66 | if(_texID) glDeleteTextures(1, &_texID); |
||
67 | } |
||
68 | |||
69 | int GLTexImage::CheckTexture()
|
||
70 | { |
||
71 | if(_texID)
|
||
72 | { |
||
73 | GLint tw, th; |
||
74 | BindTex(); |
||
75 | glGetTexLevelParameteriv(_texTarget, 0, GL_TEXTURE_WIDTH , &tw);
|
||
76 | glGetTexLevelParameteriv(_texTarget, 0, GL_TEXTURE_HEIGHT , &th);
|
||
77 | UnbindTex(); |
||
78 | return tw == _texWidth && th == _texHeight;
|
||
79 | }else
|
||
80 | { |
||
81 | return _texWidth == 0 && _texHeight ==0; |
||
82 | |||
83 | } |
||
84 | } |
||
85 | //set a dimension that is smaller than the actuall size
|
||
86 | //for drawQuad
|
||
87 | void GLTexImage::SetImageSize( int width, int height) |
||
88 | { |
||
89 | _drawWidth = _imgWidth = width; |
||
90 | _drawHeight = _imgHeight = height; |
||
91 | } |
||
92 | |||
93 | void GLTexImage::InitTexture( int width, int height, int clamp_to_edge) |
||
94 | { |
||
95 | |||
96 | if(_texID && width == _texWidth && height == _texHeight ) return; |
||
97 | if(_texID==0) glGenTextures(1, &_texID); |
||
98 | |||
99 | _texWidth = _imgWidth = _drawWidth = width; |
||
100 | _texHeight = _imgHeight = _drawHeight = height; |
||
101 | |||
102 | BindTex(); |
||
103 | |||
104 | if(clamp_to_edge)
|
||
105 | { |
||
106 | glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
||
107 | glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
||
108 | }else
|
||
109 | { |
||
110 | //out of bound tex read returns 0??
|
||
111 | glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); |
||
112 | glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); |
||
113 | } |
||
114 | glTexParameteri(_texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
||
115 | glTexParameteri(_texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
||
116 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); |
||
117 | |||
118 | glTexImage2D(_texTarget, 0, _iTexFormat,
|
||
119 | _texWidth, _texHeight, 0, GL_RGBA, GL_FLOAT, NULL); |
||
120 | CheckErrorsGL("glTexImage2D");
|
||
121 | |||
122 | |||
123 | UnbindTex(); |
||
124 | |||
125 | } |
||
126 | |||
127 | |||
128 | void GLTexImage::InitTexture( int width, int height, int clamp_to_edge, GLuint format) |
||
129 | { |
||
130 | |||
131 | if(_texID && width == _texWidth && height == _texHeight ) return; |
||
132 | if(_texID==0) glGenTextures(1, &_texID); |
||
133 | |||
134 | _texWidth = _imgWidth = _drawWidth = width; |
||
135 | _texHeight = _imgHeight = _drawHeight = height; |
||
136 | |||
137 | BindTex(); |
||
138 | |||
139 | if(clamp_to_edge)
|
||
140 | { |
||
141 | glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
||
142 | glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
||
143 | }else
|
||
144 | { |
||
145 | //out of bound tex read returns 0??
|
||
146 | glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); |
||
147 | glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); |
||
148 | } |
||
149 | glTexParameteri(_texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
||
150 | glTexParameteri(_texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
||
151 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); |
||
152 | |||
153 | glTexImage2D(_texTarget, 0, format, _texWidth, _texHeight, 0, GL_RGBA, GL_FLOAT, NULL); |
||
154 | |||
155 | UnbindTex(); |
||
156 | |||
157 | } |
||
158 | void GLTexImage::BindTex()
|
||
159 | { |
||
160 | glBindTexture(_texTarget, _texID); |
||
161 | } |
||
162 | |||
163 | void GLTexImage::UnbindTex()
|
||
164 | { |
||
165 | glBindTexture(_texTarget, 0);
|
||
166 | } |
||
167 | |||
168 | |||
169 | void GLTexImage::DrawQuad()
|
||
170 | { |
||
171 | glBegin (GL_QUADS); |
||
172 | glTexCoord2i ( 0 , 0 ); glVertex2i ( 0 , 0 ); |
||
173 | glTexCoord2i ( 0 , _drawHeight ); glVertex2i ( 0 , _drawHeight ); |
||
174 | glTexCoord2i ( _drawWidth , _drawHeight ); glVertex2i ( _drawWidth , _drawHeight ); |
||
175 | glTexCoord2i ( _drawWidth , 0 ); glVertex2i ( _drawWidth , 0 ); |
||
176 | glEnd (); |
||
177 | glFlush(); |
||
178 | } |
||
179 | |||
180 | void GLTexImage::FillMargin(int marginx, int marginy) |
||
181 | { |
||
182 | //
|
||
183 | marginx = min(marginx, _texWidth - _imgWidth); |
||
184 | marginy = min(marginy, _texHeight - _imgHeight); |
||
185 | if(marginx >0 || marginy > 0) |
||
186 | { |
||
187 | GlobalUtil::FitViewPort(_imgWidth + marginx, _imgHeight + marginy); |
||
188 | AttachToFBO(0);
|
||
189 | BindTex(); |
||
190 | ShaderMan::UseShaderMarginCopy(_imgWidth, _imgHeight); |
||
191 | DrawMargin(_imgWidth + marginx, _imgHeight + marginy); |
||
192 | } |
||
193 | } |
||
194 | |||
195 | void GLTexImage::ZeroHistoMargin()
|
||
196 | { |
||
197 | ZeroHistoMargin(_imgWidth, _imgHeight); |
||
198 | } |
||
199 | |||
200 | void GLTexImage::ZeroHistoMargin(int width, int height) |
||
201 | { |
||
202 | int marginx = width & 0x01; |
||
203 | int marginy = height & 0x01; |
||
204 | if(marginx >0 || marginy > 0) |
||
205 | { |
||
206 | int right = width + marginx;
|
||
207 | int bottom = height + marginy;
|
||
208 | GlobalUtil::FitViewPort(right, bottom); |
||
209 | AttachToFBO(0);
|
||
210 | ShaderMan::UseShaderZeroPass(); |
||
211 | glBegin(GL_QUADS); |
||
212 | if(right > width && _texWidth > width)
|
||
213 | { |
||
214 | glTexCoord2i ( width , 0 ); glVertex2i ( width , 0 ); |
||
215 | glTexCoord2i ( width , bottom ); glVertex2i ( width , bottom ); |
||
216 | glTexCoord2i ( right , bottom ); glVertex2i ( right , bottom ); |
||
217 | glTexCoord2i ( right , 0 ); glVertex2i ( right , 0 ); |
||
218 | } |
||
219 | if(bottom>height && _texHeight > height)
|
||
220 | { |
||
221 | glTexCoord2i ( 0 , height ); glVertex2i ( 0 , height ); |
||
222 | glTexCoord2i ( 0 , bottom ); glVertex2i ( 0 , bottom ); |
||
223 | glTexCoord2i ( width , bottom ); glVertex2i ( width , bottom ); |
||
224 | glTexCoord2i ( width , height ); glVertex2i ( width , height ); |
||
225 | } |
||
226 | glEnd(); |
||
227 | glFlush(); |
||
228 | } |
||
229 | |||
230 | } |
||
231 | |||
232 | void GLTexImage::DrawMargin(int right, int bottom) |
||
233 | { |
||
234 | glBegin(GL_QUADS); |
||
235 | if(right > _drawWidth)
|
||
236 | { |
||
237 | glTexCoord2i ( _drawWidth , 0 ); glVertex2i ( _drawWidth , 0 ); |
||
238 | glTexCoord2i ( _drawWidth , bottom ); glVertex2i ( _drawWidth , bottom ); |
||
239 | glTexCoord2i ( right , bottom ); glVertex2i ( right , bottom ); |
||
240 | glTexCoord2i ( right , 0 ); glVertex2i ( right , 0 ); |
||
241 | } |
||
242 | if(bottom>_drawHeight)
|
||
243 | { |
||
244 | glTexCoord2i ( 0 , _drawHeight ); glVertex2i ( 0 , _drawHeight ); |
||
245 | glTexCoord2i ( 0 , bottom ); glVertex2i ( 0 , bottom ); |
||
246 | glTexCoord2i ( _drawWidth , bottom ); glVertex2i ( _drawWidth , bottom ); |
||
247 | glTexCoord2i ( _drawWidth , _drawHeight ); glVertex2i ( _drawWidth , _drawHeight ); |
||
248 | } |
||
249 | glEnd(); |
||
250 | glFlush(); |
||
251 | |||
252 | |||
253 | } |
||
254 | |||
255 | |||
256 | void GLTexImage::DrawQuadMT4()
|
||
257 | { |
||
258 | int w = _drawWidth, h = _drawHeight;
|
||
259 | glBegin (GL_QUADS); |
||
260 | glMultiTexCoord2i( GL_TEXTURE0, 0 , 0 ); |
||
261 | glMultiTexCoord2i( GL_TEXTURE1, -1 , 0 ); |
||
262 | glMultiTexCoord2i( GL_TEXTURE2, 1 , 0 ); |
||
263 | glMultiTexCoord2i( GL_TEXTURE3, 0 , -1 ); |
||
264 | glMultiTexCoord2i( GL_TEXTURE4, 0 , 1 ); |
||
265 | glVertex2i ( 0 , 0 ); |
||
266 | |||
267 | glMultiTexCoord2i( GL_TEXTURE0, 0 , h );
|
||
268 | glMultiTexCoord2i( GL_TEXTURE1, -1 , h );
|
||
269 | glMultiTexCoord2i( GL_TEXTURE2, 1 , h );
|
||
270 | glMultiTexCoord2i( GL_TEXTURE3, 0 , h -1 ); |
||
271 | glMultiTexCoord2i( GL_TEXTURE4, 0 , h +1 ); |
||
272 | glVertex2i ( 0 , h );
|
||
273 | |||
274 | |||
275 | glMultiTexCoord2i( GL_TEXTURE0, w , h ); |
||
276 | glMultiTexCoord2i( GL_TEXTURE1, w-1 , h );
|
||
277 | glMultiTexCoord2i( GL_TEXTURE2, w+1 , h );
|
||
278 | glMultiTexCoord2i( GL_TEXTURE3, w , h-1 );
|
||
279 | glMultiTexCoord2i( GL_TEXTURE4, w , h+1 );
|
||
280 | glVertex2i ( w , h ); |
||
281 | |||
282 | glMultiTexCoord2i( GL_TEXTURE0, w , 0 );
|
||
283 | glMultiTexCoord2i( GL_TEXTURE1, w-1 , 0 ); |
||
284 | glMultiTexCoord2i( GL_TEXTURE2, w+1 , 0 ); |
||
285 | glMultiTexCoord2i( GL_TEXTURE3, w , -1 );
|
||
286 | glMultiTexCoord2i( GL_TEXTURE4, w , 1 );
|
||
287 | glVertex2i ( w , 0 );
|
||
288 | glEnd (); |
||
289 | glFlush(); |
||
290 | } |
||
291 | |||
292 | |||
293 | void GLTexImage::DrawQuadMT8()
|
||
294 | { |
||
295 | int w = _drawWidth;
|
||
296 | int h = _drawHeight;
|
||
297 | glBegin (GL_QUADS); |
||
298 | glMultiTexCoord2i( GL_TEXTURE0, 0 , 0 ); |
||
299 | glMultiTexCoord2i( GL_TEXTURE1, -1 , 0 ); |
||
300 | glMultiTexCoord2i( GL_TEXTURE2, 1 , 0 ); |
||
301 | glMultiTexCoord2i( GL_TEXTURE3, 0 , -1 ); |
||
302 | glMultiTexCoord2i( GL_TEXTURE4, 0 , 1 ); |
||
303 | glMultiTexCoord2i( GL_TEXTURE5, -1 , -1 ); |
||
304 | glMultiTexCoord2i( GL_TEXTURE6, -1 , 1 ); |
||
305 | glMultiTexCoord2i( GL_TEXTURE7, 1 , -1 ); |
||
306 | glVertex2i ( 0 , 0 ); |
||
307 | |||
308 | glMultiTexCoord2i( GL_TEXTURE0, 0 , h );
|
||
309 | glMultiTexCoord2i( GL_TEXTURE1, -1 , h );
|
||
310 | glMultiTexCoord2i( GL_TEXTURE2, 1 , h );
|
||
311 | glMultiTexCoord2i( GL_TEXTURE3, 0 , h -1 ); |
||
312 | glMultiTexCoord2i( GL_TEXTURE4, 0 , h +1 ); |
||
313 | glMultiTexCoord2i( GL_TEXTURE5, -1 , h -1 ); |
||
314 | glMultiTexCoord2i( GL_TEXTURE6, -1 , h +1 ); |
||
315 | glMultiTexCoord2i( GL_TEXTURE7, 1 , h -1 ); |
||
316 | glVertex2i ( 0 , h );
|
||
317 | |||
318 | |||
319 | glMultiTexCoord2i( GL_TEXTURE0, w , h ); |
||
320 | glMultiTexCoord2i( GL_TEXTURE1, w-1 , h );
|
||
321 | glMultiTexCoord2i( GL_TEXTURE2, w+1 , h );
|
||
322 | glMultiTexCoord2i( GL_TEXTURE3, w , h -1 );
|
||
323 | glMultiTexCoord2i( GL_TEXTURE4, w , h +1 );
|
||
324 | glMultiTexCoord2i( GL_TEXTURE5, w-1 , h -1 ); |
||
325 | glMultiTexCoord2i( GL_TEXTURE6, w-1 , h +1 ); |
||
326 | glMultiTexCoord2i( GL_TEXTURE7, w+1 , h -1 ); |
||
327 | glVertex2i ( w , h ); |
||
328 | |||
329 | glMultiTexCoord2i( GL_TEXTURE0, w , 0 );
|
||
330 | glMultiTexCoord2i( GL_TEXTURE1, w-1 , 0 ); |
||
331 | glMultiTexCoord2i( GL_TEXTURE2, w+1 , 0 ); |
||
332 | glMultiTexCoord2i( GL_TEXTURE3, w , -1 );
|
||
333 | glMultiTexCoord2i( GL_TEXTURE4, w , 1 );
|
||
334 | glMultiTexCoord2i( GL_TEXTURE5, w-1 , -1 ); |
||
335 | glMultiTexCoord2i( GL_TEXTURE6, w-1 , 1 ); |
||
336 | glMultiTexCoord2i( GL_TEXTURE7, w+1 , -1 ); |
||
337 | glVertex2i ( w , 0 );
|
||
338 | glEnd (); |
||
339 | glFlush(); |
||
340 | } |
||
341 | |||
342 | |||
343 | |||
344 | |||
345 | void GLTexImage::DrawImage()
|
||
346 | { |
||
347 | DrawQuad(); |
||
348 | } |
||
349 | |||
350 | |||
351 | |||
352 | void GLTexImage::FitTexViewPort()
|
||
353 | { |
||
354 | GlobalUtil::FitViewPort(_drawWidth, _drawHeight); |
||
355 | } |
||
356 | |||
357 | void GLTexImage::FitRealTexViewPort()
|
||
358 | { |
||
359 | GlobalUtil::FitViewPort(_texWidth, _texHeight); |
||
360 | } |
||
361 | |||
362 | void GLTexImage::AttachToFBO(int i) |
||
363 | { |
||
364 | glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, i+GL_COLOR_ATTACHMENT0_EXT, _texTarget, _texID, 0 );
|
||
365 | } |
||
366 | |||
367 | void GLTexImage::DetachFBO(int i) |
||
368 | { |
||
369 | glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, i+GL_COLOR_ATTACHMENT0_EXT, _texTarget, 0, 0 ); |
||
370 | } |
||
371 | |||
372 | |||
373 | void GLTexImage::DrawQuad(float x1, float x2, float y1, float y2) |
||
374 | { |
||
375 | |||
376 | glBegin (GL_QUADS); |
||
377 | glTexCoord2f ( x1 , y1 ); glVertex2f ( x1 , y1 ); |
||
378 | glTexCoord2f ( x1 , y2 ); glVertex2f ( x1 , y2 ); |
||
379 | glTexCoord2f ( x2 , y2 ); glVertex2f ( x2 , y2 ); |
||
380 | glTexCoord2f ( x2 , y1 ); glVertex2f ( x2 , y1 ); |
||
381 | glEnd (); |
||
382 | glFlush(); |
||
383 | } |
||
384 | |||
385 | void GLTexImage::TexConvertRGB()
|
||
386 | { |
||
387 | //change 3/22/09
|
||
388 | FrameBufferObject fbo; |
||
389 | //GlobalUtil::FitViewPort(1, 1);
|
||
390 | FitTexViewPort(); |
||
391 | |||
392 | AttachToFBO(0);
|
||
393 | ShaderMan::UseShaderRGB2Gray(); |
||
394 | glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); |
||
395 | DrawQuad(); |
||
396 | ShaderMan::UnloadProgram(); |
||
397 | DetachFBO(0);
|
||
398 | } |
||
399 | |||
400 | void GLTexImage::DrawQuadDS(int scale) |
||
401 | { |
||
402 | DrawScaledQuad(float(scale));
|
||
403 | } |
||
404 | |||
405 | void GLTexImage::DrawQuadUS(int scale) |
||
406 | { |
||
407 | DrawScaledQuad(1.0f/scale); |
||
408 | } |
||
409 | |||
410 | void GLTexImage::DrawScaledQuad(float texscale) |
||
411 | { |
||
412 | |||
413 | ////the texture coordinate for 0.5 is to + 0.5*texscale
|
||
414 | float to = 0.5f -0.5f * texscale; |
||
415 | float tx = _imgWidth*texscale +to;
|
||
416 | float ty = _imgHeight*texscale +to;
|
||
417 | glBegin (GL_QUADS); |
||
418 | glTexCoord2f ( to , to ); glVertex2i ( 0 , 0 ); |
||
419 | glTexCoord2f ( to , ty ); glVertex2i ( 0 , _imgHeight );
|
||
420 | glTexCoord2f ( tx , ty ); glVertex2i ( _imgWidth , _imgHeight ); |
||
421 | glTexCoord2f ( tx , to ); glVertex2i ( _imgWidth , 0 );
|
||
422 | glEnd (); |
||
423 | glFlush(); |
||
424 | } |
||
425 | |||
426 | |||
427 | void GLTexImage::DrawQuadReduction(int w , int h) |
||
428 | { |
||
429 | float to = -0.5f; |
||
430 | float tx = w*2 +to; |
||
431 | float ty = h*2 +to; |
||
432 | glBegin (GL_QUADS); |
||
433 | glMultiTexCoord2f ( GL_TEXTURE0, to , to ); |
||
434 | glMultiTexCoord2f ( GL_TEXTURE1, to +1, to );
|
||
435 | glMultiTexCoord2f ( GL_TEXTURE2, to , to+1 );
|
||
436 | glMultiTexCoord2f ( GL_TEXTURE3, to +1, to+1 ); |
||
437 | glVertex2i ( 0 , 0 ); |
||
438 | |||
439 | glMultiTexCoord2f ( GL_TEXTURE0, to , ty ); |
||
440 | glMultiTexCoord2f ( GL_TEXTURE1, to +1, ty );
|
||
441 | glMultiTexCoord2f ( GL_TEXTURE2, to , ty +1 );
|
||
442 | glMultiTexCoord2f ( GL_TEXTURE3, to +1, ty +1 ); |
||
443 | glVertex2i ( 0 , h );
|
||
444 | |||
445 | glMultiTexCoord2f ( GL_TEXTURE0, tx , ty ); |
||
446 | glMultiTexCoord2f ( GL_TEXTURE1, tx +1, ty );
|
||
447 | glMultiTexCoord2f ( GL_TEXTURE2, tx , ty +1);
|
||
448 | glMultiTexCoord2f ( GL_TEXTURE3, tx +1, ty +1); |
||
449 | |||
450 | glVertex2i ( w , h ); |
||
451 | |||
452 | glMultiTexCoord2f ( GL_TEXTURE0, tx , to ); |
||
453 | glMultiTexCoord2f ( GL_TEXTURE1, tx +1, to );
|
||
454 | glMultiTexCoord2f ( GL_TEXTURE2, tx , to +1 );
|
||
455 | glMultiTexCoord2f ( GL_TEXTURE3, tx +1, to +1 ); |
||
456 | glVertex2i ( w , 0 );
|
||
457 | glEnd (); |
||
458 | |||
459 | glFlush(); |
||
460 | } |
||
461 | |||
462 | |||
463 | void GLTexImage::DrawQuadReduction()
|
||
464 | { |
||
465 | float to = -0.5f; |
||
466 | float tx = _drawWidth*2 +to; |
||
467 | float ty = _drawHeight*2 +to; |
||
468 | glBegin (GL_QUADS); |
||
469 | glMultiTexCoord2f ( GL_TEXTURE0, to , to ); |
||
470 | glMultiTexCoord2f ( GL_TEXTURE1, to +1, to );
|
||
471 | glMultiTexCoord2f ( GL_TEXTURE2, to , to+1 );
|
||
472 | glMultiTexCoord2f ( GL_TEXTURE3, to +1, to+1 ); |
||
473 | glVertex2i ( 0 , 0 ); |
||
474 | |||
475 | glMultiTexCoord2f ( GL_TEXTURE0, to , ty ); |
||
476 | glMultiTexCoord2f ( GL_TEXTURE1, to +1, ty );
|
||
477 | glMultiTexCoord2f ( GL_TEXTURE2, to , ty +1 );
|
||
478 | glMultiTexCoord2f ( GL_TEXTURE3, to +1, ty +1 ); |
||
479 | glVertex2i ( 0 , _drawHeight );
|
||
480 | |||
481 | glMultiTexCoord2f ( GL_TEXTURE0, tx , ty ); |
||
482 | glMultiTexCoord2f ( GL_TEXTURE1, tx +1, ty );
|
||
483 | glMultiTexCoord2f ( GL_TEXTURE2, tx , ty +1);
|
||
484 | glMultiTexCoord2f ( GL_TEXTURE3, tx +1, ty +1); |
||
485 | |||
486 | glVertex2i ( _drawWidth , _drawHeight ); |
||
487 | |||
488 | glMultiTexCoord2f ( GL_TEXTURE0, tx , to ); |
||
489 | glMultiTexCoord2f ( GL_TEXTURE1, tx +1, to );
|
||
490 | glMultiTexCoord2f ( GL_TEXTURE2, tx , to +1 );
|
||
491 | glMultiTexCoord2f ( GL_TEXTURE3, tx +1, to +1 ); |
||
492 | glVertex2i ( _drawWidth , 0 );
|
||
493 | glEnd (); |
||
494 | |||
495 | glFlush(); |
||
496 | } |
||
497 | |||
498 | void GLTexPacked::TexConvertRGB()
|
||
499 | { |
||
500 | //update the actual size of daw area
|
||
501 | _drawWidth = (1 + _imgWidth) >> 1; |
||
502 | _drawHeight = (1 + _imgHeight) >> 1; |
||
503 | ///
|
||
504 | FrameBufferObject fbo; |
||
505 | GLuint oldTexID = _texID; |
||
506 | glGenTextures(1, &_texID);
|
||
507 | glBindTexture(_texTarget, _texID); |
||
508 | glTexImage2D(_texTarget, 0, _iTexFormat, _texWidth, _texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); |
||
509 | |||
510 | //input
|
||
511 | glBindTexture(_texTarget, oldTexID); |
||
512 | //output
|
||
513 | AttachToFBO(0);
|
||
514 | //program
|
||
515 | ShaderMan::UseShaderRGB2Gray(); |
||
516 | //draw buffer
|
||
517 | glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); |
||
518 | //run
|
||
519 | DrawQuadDS(2);
|
||
520 | ShaderMan::UnloadProgram(); |
||
521 | |||
522 | glDeleteTextures(1, &oldTexID);
|
||
523 | DetachFBO(0);
|
||
524 | } |
||
525 | |||
526 | |||
527 | void GLTexPacked::SetImageSize( int width, int height) |
||
528 | { |
||
529 | _imgWidth = width; _drawWidth = (width + 1) >> 1; |
||
530 | _imgHeight = height; _drawHeight = (height + 1) >> 1; |
||
531 | } |
||
532 | |||
533 | void GLTexPacked::InitTexture( int width, int height, int clamp_to_edge) |
||
534 | { |
||
535 | |||
536 | if(_texID && width == _imgWidth && height == _imgHeight ) return; |
||
537 | if(_texID==0) glGenTextures(1, &_texID); |
||
538 | |||
539 | _imgWidth = width; |
||
540 | _imgHeight = height; |
||
541 | if(GlobalUtil::_PreciseBorder)
|
||
542 | { |
||
543 | _texWidth = (width + 2) >> 1; |
||
544 | _texHeight = (height + 2) >> 1; |
||
545 | }else
|
||
546 | { |
||
547 | _texWidth = (width + 1) >> 1; |
||
548 | _texHeight = (height + 1) >> 1; |
||
549 | } |
||
550 | _drawWidth = (width + 1) >> 1; |
||
551 | _drawHeight = (height + 1) >> 1; |
||
552 | |||
553 | BindTex(); |
||
554 | |||
555 | if(clamp_to_edge)
|
||
556 | { |
||
557 | glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
||
558 | glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
||
559 | }else
|
||
560 | { |
||
561 | //out of bound tex read returns 0??
|
||
562 | glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); |
||
563 | glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); |
||
564 | } |
||
565 | glTexParameteri(_texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
||
566 | glTexParameteri(_texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
||
567 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); |
||
568 | |||
569 | glTexImage2D(_texTarget, 0, _iTexFormat,
|
||
570 | _texWidth, _texHeight, 0, GL_RGBA, GL_FLOAT, NULL); |
||
571 | |||
572 | UnbindTex(); |
||
573 | |||
574 | } |
||
575 | |||
576 | |||
577 | void GLTexPacked::DrawImage()
|
||
578 | { |
||
579 | float x1 =0, y1 = 0; //border.. |
||
580 | float x2 = _imgWidth*0.5f +x1; |
||
581 | float y2 = _imgHeight*0.5f + y1; |
||
582 | glBegin (GL_QUADS); |
||
583 | glTexCoord2f ( x1 , y1 ); glVertex2i ( 0 , 0 ); |
||
584 | glTexCoord2f ( x1 , y2 ); glVertex2i ( 0 , _imgHeight );
|
||
585 | glTexCoord2f ( x2 , y2 ); glVertex2i ( _imgWidth , _imgHeight ); |
||
586 | glTexCoord2f ( x2 , y1 ); glVertex2i ( _imgWidth , 0 );
|
||
587 | glEnd (); |
||
588 | glFlush(); |
||
589 | } |
||
590 | |||
591 | void GLTexPacked::DrawQuadUS(int scale) |
||
592 | { |
||
593 | int tw =_drawWidth, th = _drawHeight;
|
||
594 | float texscale = 1.0f / scale; |
||
595 | float x1 = 0.5f - 0.5f*scale, y1 = x1; |
||
596 | float x2 = tw * texscale + x1;
|
||
597 | float y2 = th * texscale + y1;
|
||
598 | float step = texscale *0.5f; |
||
599 | glBegin (GL_QUADS); |
||
600 | glMultiTexCoord2f( GL_TEXTURE0, x1 , y1 ); |
||
601 | glMultiTexCoord2f( GL_TEXTURE1, x1+step , y1 ); |
||
602 | glMultiTexCoord2f( GL_TEXTURE2, x1 , y1 +step); |
||
603 | glMultiTexCoord2f( GL_TEXTURE3, x1+step , y1 +step); |
||
604 | glVertex2i ( 0 , 0 ); |
||
605 | |||
606 | glMultiTexCoord2f( GL_TEXTURE0, x1 , y2 ); |
||
607 | glMultiTexCoord2f( GL_TEXTURE1, x1+step , y2 ); |
||
608 | glMultiTexCoord2f( GL_TEXTURE2, x1 , y2 +step); |
||
609 | glMultiTexCoord2f( GL_TEXTURE3, x1+step , y2 +step); |
||
610 | glVertex2i ( 0 , th );
|
||
611 | |||
612 | glMultiTexCoord2f( GL_TEXTURE0, x2 , y2 ); |
||
613 | glMultiTexCoord2f( GL_TEXTURE1, x2+step , y2 ); |
||
614 | glMultiTexCoord2f( GL_TEXTURE2, x2 , y2 +step); |
||
615 | glMultiTexCoord2f( GL_TEXTURE3, x2+step , y2 +step); |
||
616 | glVertex2i ( tw , th ); |
||
617 | |||
618 | glMultiTexCoord2f( GL_TEXTURE0, x2 , y1 ); |
||
619 | glMultiTexCoord2f( GL_TEXTURE1, x2+step , y1 ); |
||
620 | glMultiTexCoord2f( GL_TEXTURE2, x2 , y1 +step); |
||
621 | glMultiTexCoord2f( GL_TEXTURE3, x2+step , y1 +step); |
||
622 | glVertex2i ( tw , 0 );
|
||
623 | glEnd (); |
||
624 | } |
||
625 | |||
626 | void GLTexPacked::DrawQuadDS(int scale) |
||
627 | { |
||
628 | int tw = _drawWidth;
|
||
629 | int th = _drawHeight;
|
||
630 | float x1 = 0.5f - 0.5f*scale; |
||
631 | float x2 = tw * scale + x1;
|
||
632 | float y1 = 0.5f - 0.5f * scale; |
||
633 | float y2 = th * scale + y1;
|
||
634 | int step = scale / 2; |
||
635 | |||
636 | glBegin (GL_QUADS); |
||
637 | glMultiTexCoord2f( GL_TEXTURE0, x1 , y1 ); |
||
638 | glMultiTexCoord2f( GL_TEXTURE1, x1+step , y1 ); |
||
639 | glMultiTexCoord2f( GL_TEXTURE2, x1 , y1 +step); |
||
640 | glMultiTexCoord2f( GL_TEXTURE3, x1+step , y1 +step); |
||
641 | glVertex2i ( 0 , 0 ); |
||
642 | |||
643 | glMultiTexCoord2f( GL_TEXTURE0, x1 , y2 ); |
||
644 | glMultiTexCoord2f( GL_TEXTURE1, x1+step , y2 ); |
||
645 | glMultiTexCoord2f( GL_TEXTURE2, x1 , y2 +step); |
||
646 | glMultiTexCoord2f( GL_TEXTURE3, x1+step , y2 +step); |
||
647 | glVertex2i ( 0 , th );
|
||
648 | |||
649 | glMultiTexCoord2f( GL_TEXTURE0, x2 , y2 ); |
||
650 | glMultiTexCoord2f( GL_TEXTURE1, x2+step , y2 ); |
||
651 | glMultiTexCoord2f( GL_TEXTURE2, x2 , y2 +step); |
||
652 | glMultiTexCoord2f( GL_TEXTURE3, x2+step , y2 +step); |
||
653 | glVertex2i ( tw , th ); |
||
654 | |||
655 | glMultiTexCoord2f( GL_TEXTURE0, x2 , y1 ); |
||
656 | glMultiTexCoord2f( GL_TEXTURE1, x2+step , y1 ); |
||
657 | glMultiTexCoord2f( GL_TEXTURE2, x2 , y1 +step); |
||
658 | glMultiTexCoord2f( GL_TEXTURE3, x2+step , y1 +step); |
||
659 | glVertex2i ( tw , 0 );
|
||
660 | glEnd (); |
||
661 | } |
||
662 | |||
663 | void GLTexPacked::ZeroHistoMargin()
|
||
664 | { |
||
665 | int marginx = (((_imgWidth + 3) /4)*4) - _imgWidth; |
||
666 | int marginy = (((-_imgHeight + 3)/4)*4) - _imgHeight; |
||
667 | if(marginx >0 || marginy > 0) |
||
668 | { |
||
669 | int tw = (_imgWidth + marginx ) >> 1; |
||
670 | int th = (_imgHeight + marginy ) >> 1; |
||
671 | tw = min(_texWidth, tw ); |
||
672 | th = min(_texHeight, th); |
||
673 | GlobalUtil::FitViewPort(tw, th); |
||
674 | AttachToFBO(0);
|
||
675 | BindTex(); |
||
676 | ShaderMan::UseShaderZeroPass(); |
||
677 | DrawMargin(tw, th, 1, 1); |
||
678 | } |
||
679 | } |
||
680 | |||
681 | |||
682 | void GLTexPacked::FillMargin(int marginx, int marginy) |
||
683 | { |
||
684 | //
|
||
685 | marginx = min(marginx, _texWidth * 2 - _imgWidth);
|
||
686 | marginy = min(marginy, _texHeight * 2 - _imgHeight);
|
||
687 | if(marginx >0 || marginy > 0) |
||
688 | { |
||
689 | int tw = (_imgWidth + marginx + 1) >> 1; |
||
690 | int th = (_imgHeight + marginy + 1) >> 1; |
||
691 | GlobalUtil::FitViewPort(tw, th); |
||
692 | BindTex(); |
||
693 | AttachToFBO(0);
|
||
694 | ShaderMan::UseShaderMarginCopy(_imgWidth , _imgHeight); |
||
695 | DrawMargin(tw, th, marginx, marginy); |
||
696 | } |
||
697 | } |
||
698 | void GLTexPacked::DrawMargin(int right, int bottom, int mx, int my) |
||
699 | { |
||
700 | int tw = (_imgWidth >>1); |
||
701 | int th = (_imgHeight >>1); |
||
702 | glBegin(GL_QUADS); |
||
703 | if(right>tw && mx)
|
||
704 | { |
||
705 | glTexCoord2i ( tw , 0 ); glVertex2i ( tw , 0 ); |
||
706 | glTexCoord2i ( tw , bottom ); glVertex2i ( tw , bottom ); |
||
707 | glTexCoord2i ( right, bottom ); glVertex2i ( right, bottom ); |
||
708 | glTexCoord2i ( right, 0 ); glVertex2i ( right, 0 ); |
||
709 | } |
||
710 | if(bottom>th && my)
|
||
711 | { |
||
712 | glTexCoord2i ( 0 , th ); glVertex2i ( 0 , th ); |
||
713 | glTexCoord2i ( 0 , bottom ); glVertex2i ( 0 , bottom ); |
||
714 | glTexCoord2i ( tw , bottom ); glVertex2i ( tw , bottom ); |
||
715 | glTexCoord2i ( tw , th ); glVertex2i ( tw , th ); |
||
716 | } |
||
717 | glEnd(); |
||
718 | glFlush(); |
||
719 | |||
720 | } |
||
721 | |||
722 | |||
723 | void GLTexImage::UnbindMultiTex(int n) |
||
724 | { |
||
725 | for(int i = n-1; i>=0; i--) |
||
726 | { |
||
727 | glActiveTexture(GL_TEXTURE0+i); |
||
728 | glBindTexture(_texTarget, 0);
|
||
729 | } |
||
730 | } |
||
731 | |||
732 | template <class Uint> int |
||
733 | |||
734 | #if !defined(_MSC_VER) || _MSC_VER > 1200 |
||
735 | GLTexInput:: |
||
736 | #endif
|
||
737 | |||
738 | DownSamplePixelDataI(unsigned int gl_format, int width, int height, int ds, |
||
739 | const Uint * pin, Uint * pout)
|
||
740 | { |
||
741 | int step, linestep;
|
||
742 | int i, j;
|
||
743 | int ws = width/ds;
|
||
744 | int hs = height/ds;
|
||
745 | const Uint * line = pin, * p;
|
||
746 | Uint *po = pout; |
||
747 | switch(gl_format)
|
||
748 | { |
||
749 | case GL_LUMINANCE:
|
||
750 | case GL_LUMINANCE_ALPHA:
|
||
751 | step = ds * (gl_format == GL_LUMINANCE? 1: 2); |
||
752 | linestep = width * step; |
||
753 | for(i = 0 ; i < hs; i++, line+=linestep) |
||
754 | { |
||
755 | for(j = 0, p = line; j < ws; j++, p+=step) |
||
756 | { |
||
757 | *po++ = *p; |
||
758 | } |
||
759 | } |
||
760 | break;
|
||
761 | case GL_RGB:
|
||
762 | case GL_RGBA:
|
||
763 | step = ds * (gl_format == GL_RGB? 3: 4); |
||
764 | linestep = width * step; |
||
765 | |||
766 | for(i = 0 ; i < hs; i++, line+=linestep) |
||
767 | { |
||
768 | for(j = 0, p = line; j < ws; j++, p+=step) |
||
769 | { |
||
770 | //*po++ = int(p[0]*0.299 + p[1] * 0.587 + p[2]* 0.114 + 0.5);
|
||
771 | *po++ = ((19595*p[0] + 38470*p[1] + 7471*p[2]+ 32768)>>16); |
||
772 | } |
||
773 | } |
||
774 | break;
|
||
775 | case GL_BGR:
|
||
776 | case GL_BGRA:
|
||
777 | step = ds * (gl_format == GL_BGR? 3: 4); |
||
778 | linestep = width * step; |
||
779 | for(i = 0 ; i < hs; i++, line+=linestep) |
||
780 | { |
||
781 | for(j = 0, p = line; j < ws; j++, p+=step) |
||
782 | { |
||
783 | *po++ = ((7471*p[0] + 38470*p[1] + 19595*p[2]+ 32768)>>16); |
||
784 | } |
||
785 | } |
||
786 | break;
|
||
787 | default:
|
||
788 | return 0; |
||
789 | } |
||
790 | |||
791 | return 1; |
||
792 | |||
793 | } |
||
794 | |||
795 | |||
796 | template <class Uint> int |
||
797 | |||
798 | #if !defined(_MSC_VER) || _MSC_VER > 1200 |
||
799 | GLTexInput:: |
||
800 | #endif
|
||
801 | |||
802 | DownSamplePixelDataI2F(unsigned int gl_format, int width, int height, int ds, |
||
803 | const Uint * pin, float * pout, int skip) |
||
804 | { |
||
805 | int step, linestep;
|
||
806 | int i, j;
|
||
807 | int ws = width/ds - skip;
|
||
808 | int hs = height/ds;
|
||
809 | const Uint * line = pin, * p;
|
||
810 | float *po = pout;
|
||
811 | const float factor = (sizeof(Uint) == 1? 255.0f : 65535.0f); |
||
812 | switch(gl_format)
|
||
813 | { |
||
814 | case GL_LUMINANCE:
|
||
815 | case GL_LUMINANCE_ALPHA:
|
||
816 | step = ds * (gl_format == GL_LUMINANCE? 1: 2); |
||
817 | linestep = width * step; |
||
818 | for(i = 0 ; i < hs; i++, line+=linestep) |
||
819 | { |
||
820 | for(j = 0, p = line; j < ws; j++, p+=step) |
||
821 | { |
||
822 | *po++ = (*p) / factor; |
||
823 | } |
||
824 | } |
||
825 | break;
|
||
826 | case GL_RGB:
|
||
827 | case GL_RGBA:
|
||
828 | step = ds * (gl_format == GL_RGB? 3: 4); |
||
829 | linestep = width * step; |
||
830 | |||
831 | for(i = 0 ; i < hs; i++, line+=linestep) |
||
832 | { |
||
833 | for(j = 0, p = line; j < ws; j++, p+=step) |
||
834 | { |
||
835 | //*po++ = int(p[0]*0.299 + p[1] * 0.587 + p[2]* 0.114 + 0.5);
|
||
836 | *po++ = ((19595*p[0] + 38470*p[1] + 7471*p[2]) / (65535.0f * factor)); |
||
837 | } |
||
838 | } |
||
839 | break;
|
||
840 | case GL_BGR:
|
||
841 | case GL_BGRA:
|
||
842 | step = ds * (gl_format == GL_BGR? 3: 4); |
||
843 | linestep = width * step; |
||
844 | for(i = 0 ; i < hs; i++, line+=linestep) |
||
845 | { |
||
846 | for(j = 0, p = line; j < ws; j++, p+=step) |
||
847 | { |
||
848 | *po++ = ((7471*p[0] + 38470*p[1] + 19595*p[2]) / (65535.0f * factor)); |
||
849 | } |
||
850 | } |
||
851 | break;
|
||
852 | default:
|
||
853 | return 0; |
||
854 | } |
||
855 | return 1; |
||
856 | } |
||
857 | |||
858 | int GLTexInput::DownSamplePixelDataF(unsigned int gl_format, int width, int height, int ds, const float * pin, float * pout, int skip) |
||
859 | { |
||
860 | int step, linestep;
|
||
861 | int i, j;
|
||
862 | int ws = width/ds - skip;
|
||
863 | int hs = height/ds;
|
||
864 | const float * line = pin, * p; |
||
865 | float *po = pout;
|
||
866 | switch(gl_format)
|
||
867 | { |
||
868 | case GL_LUMINANCE:
|
||
869 | case GL_LUMINANCE_ALPHA:
|
||
870 | step = ds * (gl_format == GL_LUMINANCE? 1: 2); |
||
871 | linestep = width * step; |
||
872 | for(i = 0 ; i < hs; i++, line+=linestep) |
||
873 | { |
||
874 | for(j = 0, p = line; j < ws; j++, p+=step) |
||
875 | { |
||
876 | *po++ = *p; |
||
877 | } |
||
878 | } |
||
879 | break;
|
||
880 | case GL_RGB:
|
||
881 | case GL_RGBA:
|
||
882 | step = ds * (gl_format == GL_RGB? 3: 4); |
||
883 | linestep = width * step; |
||
884 | for(i = 0 ; i < hs; i++, line+=linestep) |
||
885 | { |
||
886 | for(j = 0, p = line; j < ws; j++, p+=step) |
||
887 | { |
||
888 | *po++ = (0.299f*p[0] + 0.587f*p[1] + 0.114f*p[2]); |
||
889 | } |
||
890 | } |
||
891 | break;
|
||
892 | case GL_BGR:
|
||
893 | case GL_BGRA:
|
||
894 | step = ds * (gl_format == GL_BGR? 3: 4); |
||
895 | linestep = width * step; |
||
896 | for(i = 0 ; i < hs; i++, line+=linestep) |
||
897 | { |
||
898 | for(j = 0, p = line; j < ws; j++, p+=step) |
||
899 | { |
||
900 | *po++ = (0.114f*p[0] + 0.587f*p[1] + 0.299f * p[2]); |
||
901 | } |
||
902 | } |
||
903 | break;
|
||
904 | default:
|
||
905 | return 0; |
||
906 | } |
||
907 | |||
908 | return 1; |
||
909 | |||
910 | } |
||
911 | |||
912 | int GLTexInput::SetImageData( int width, int height, const void * data, |
||
913 | unsigned int gl_format, unsigned int gl_type ) |
||
914 | { |
||
915 | int simple_format = IsSimpleGlFormat(gl_format, gl_type);//no cpu code to handle other formats |
||
916 | int ws, hs, done = 1; |
||
917 | |||
918 | if(_converted_data) {delete [] _converted_data; _converted_data = NULL; } |
||
919 | |||
920 | _rgb_converted = 1;
|
||
921 | _data_modified = 0;
|
||
922 | |||
923 | if( simple_format
|
||
924 | && ( width > _texMaxDim || height > _texMaxDim || GlobalUtil::_PreProcessOnCPU) |
||
925 | && GlobalUtil::_octave_min_default >0 )
|
||
926 | { |
||
927 | _down_sampled = GlobalUtil::_octave_min_default; |
||
928 | ws = width >> GlobalUtil::_octave_min_default; |
||
929 | hs = height >> GlobalUtil::_octave_min_default; |
||
930 | }else
|
||
931 | { |
||
932 | _down_sampled = 0;
|
||
933 | ws = width; |
||
934 | hs = height; |
||
935 | } |
||
936 | |||
937 | if ( ws > _texMaxDim || hs > _texMaxDim)
|
||
938 | { |
||
939 | if(simple_format)
|
||
940 | { |
||
941 | if(GlobalUtil::_verbose) std::cout<<"Automatic down-sampling is used\n"; |
||
942 | do
|
||
943 | { |
||
944 | _down_sampled ++; |
||
945 | ws >>= 1;
|
||
946 | hs >>= 1;
|
||
947 | }while(ws > _texMaxDim || hs > _texMaxDim);
|
||
948 | }else
|
||
949 | { |
||
950 | std::cerr<<"Input images is too big to fit into a texture\n";
|
||
951 | return 0; |
||
952 | } |
||
953 | } |
||
954 | |||
955 | _texWidth = _imgWidth = _drawWidth = ws; |
||
956 | _texHeight = _imgHeight = _drawHeight = hs; |
||
957 | |||
958 | if(GlobalUtil::_verbose)
|
||
959 | { |
||
960 | std::cout<<"Image size :\t"<<width<<"x"<<height<<"\n"; |
||
961 | if(_down_sampled >0) std::cout<<"Down sample to \t"<<ws<<"x"<<hs<<"\n"; |
||
962 | } |
||
963 | |||
964 | |||
965 | if(GlobalUtil::_UseCUDA || GlobalUtil::_UseOpenCL)
|
||
966 | { |
||
967 | //////////////////////////////////////
|
||
968 | int tWidth = TruncateWidthCU(_imgWidth);
|
||
969 | int skip = _imgWidth - tWidth;
|
||
970 | //skip = 0;
|
||
971 | if(!simple_format)
|
||
972 | { |
||
973 | std::cerr << "Input format not supported under current settings.\n";
|
||
974 | return 0; |
||
975 | }else if(_down_sampled > 0 || gl_format != GL_LUMINANCE || gl_type != GL_FLOAT) |
||
976 | { |
||
977 | _converted_data = new float [_imgWidth * _imgHeight]; |
||
978 | if(gl_type == GL_UNSIGNED_BYTE)
|
||
979 | DownSamplePixelDataI2F(gl_format, width, height, 1<<_down_sampled,
|
||
980 | ((const unsigned char*) data), _converted_data, skip); |
||
981 | else if(gl_type == GL_UNSIGNED_SHORT) |
||
982 | DownSamplePixelDataI2F(gl_format, width, height, 1<<_down_sampled,
|
||
983 | ((const unsigned short*) data), _converted_data, skip); |
||
984 | else
|
||
985 | DownSamplePixelDataF(gl_format, width, height, 1<<_down_sampled, (float*)data, _converted_data, skip); |
||
986 | _rgb_converted = 2; //indidates a new data copy |
||
987 | _pixel_data = _converted_data; |
||
988 | }else
|
||
989 | { |
||
990 | //Luminance data that doesn't need to down sample
|
||
991 | _rgb_converted = 1;
|
||
992 | _pixel_data = data; |
||
993 | if(skip > 0) |
||
994 | { |
||
995 | for(int i = 1; i < _imgHeight; ++i) |
||
996 | { |
||
997 | float * dst = ((float*)data) + i * tWidth, * src = ((float*)data) + i * _imgWidth; |
||
998 | for(int j = 0; j < tWidth; ++j) *dst++ = * src++; |
||
999 | } |
||
1000 | } |
||
1001 | } |
||
1002 | _texWidth = _imgWidth = _drawWidth = tWidth; |
||
1003 | _data_modified = 1;
|
||
1004 | }else
|
||
1005 | { |
||
1006 | if(_texID ==0) glGenTextures(1, &_texID); |
||
1007 | glBindTexture(_texTarget, _texID); |
||
1008 | CheckErrorsGL("glBindTexture");
|
||
1009 | glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
||
1010 | glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
||
1011 | glPixelStorei(GL_UNPACK_ALIGNMENT , 1);
|
||
1012 | |||
1013 | if(simple_format && ( _down_sampled> 0 || (gl_format != GL_LUMINANCE && GlobalUtil::_PreProcessOnCPU) )) |
||
1014 | { |
||
1015 | |||
1016 | if(gl_type == GL_UNSIGNED_BYTE)
|
||
1017 | { |
||
1018 | unsigned char * newdata = new unsigned char [_imgWidth * _imgHeight]; |
||
1019 | DownSamplePixelDataI(gl_format, width, height, 1<<_down_sampled, ((const unsigned char*) data), newdata); |
||
1020 | glTexImage2D(_texTarget, 0, GL_LUMINANCE32F_ARB, //internal format changed |
||
1021 | _imgWidth, _imgHeight, 0,
|
||
1022 | GL_LUMINANCE, GL_UNSIGNED_BYTE, newdata); |
||
1023 | delete newdata;
|
||
1024 | }else if(gl_type == GL_UNSIGNED_SHORT) |
||
1025 | { |
||
1026 | unsigned short * newdata = new unsigned short [_imgWidth * _imgHeight]; |
||
1027 | DownSamplePixelDataI(gl_format, width, height, 1<<_down_sampled, ((const unsigned short*) data), newdata); |
||
1028 | |||
1029 | glTexImage2D(_texTarget, 0, GL_LUMINANCE32F_ARB, //internal format changed |
||
1030 | _imgWidth, _imgHeight, 0,
|
||
1031 | GL_LUMINANCE, GL_UNSIGNED_SHORT, newdata); |
||
1032 | delete newdata;
|
||
1033 | }else if(gl_type == GL_FLOAT) |
||
1034 | { |
||
1035 | float * newdata = new float [_imgWidth * _imgHeight]; |
||
1036 | DownSamplePixelDataF(gl_format, width, height, 1<<_down_sampled, (float*)data, newdata); |
||
1037 | glTexImage2D(_texTarget, 0, GL_LUMINANCE32F_ARB, //internal format changed |
||
1038 | _imgWidth, _imgHeight, 0,
|
||
1039 | GL_LUMINANCE, GL_FLOAT, newdata); |
||
1040 | delete newdata;
|
||
1041 | }else
|
||
1042 | { |
||
1043 | //impossible
|
||
1044 | done = 0;
|
||
1045 | _rgb_converted = 0;
|
||
1046 | } |
||
1047 | GlobalUtil::FitViewPort(1, 1); //this used to be necessary |
||
1048 | }else
|
||
1049 | { |
||
1050 | //ds must be 0 here if not simpleformat
|
||
1051 | if(gl_format == GL_LUMINANCE || gl_format == GL_LUMINANCE_ALPHA)
|
||
1052 | { |
||
1053 | //use one channel internal format if data is intensity image
|
||
1054 | glTexImage2D(_texTarget, 0, GL_LUMINANCE32F_ARB,
|
||
1055 | _imgWidth, _imgHeight, 0, gl_format, gl_type, data);
|
||
1056 | GlobalUtil::FitViewPort(1, 1); //this used to be necessary |
||
1057 | } |
||
1058 | else
|
||
1059 | { |
||
1060 | //convert RGB 2 GRAY if needed
|
||
1061 | glTexImage2D(_texTarget, 0, _iTexFormat, _imgWidth, _imgHeight, 0, gl_format, gl_type, data); |
||
1062 | if(ShaderMan::HaveShaderMan())
|
||
1063 | TexConvertRGB(); |
||
1064 | else
|
||
1065 | _rgb_converted = 0; //In CUDA mode, the conversion will be done by CUDA kernel |
||
1066 | } |
||
1067 | } |
||
1068 | UnbindTex(); |
||
1069 | } |
||
1070 | return done;
|
||
1071 | } |
||
1072 | |||
1073 | |||
1074 | GLTexInput::~GLTexInput() |
||
1075 | { |
||
1076 | if(_converted_data) delete [] _converted_data; |
||
1077 | } |
||
1078 | |||
1079 | |||
1080 | int GLTexInput::LoadImageFile(char *imagepath, int &w, int &h ) |
||
1081 | { |
||
1082 | #ifndef SIFTGPU_NO_DEVIL
|
||
1083 | static int devil_loaded = 0; |
||
1084 | unsigned int imID; |
||
1085 | int done = 1; |
||
1086 | |||
1087 | if(devil_loaded == 0) |
||
1088 | { |
||
1089 | ilInit(); |
||
1090 | ilOriginFunc(IL_ORIGIN_UPPER_LEFT); |
||
1091 | ilEnable(IL_ORIGIN_SET); |
||
1092 | devil_loaded = 1;
|
||
1093 | } |
||
1094 | |||
1095 | ///
|
||
1096 | ilGenImages(1, &imID);
|
||
1097 | ilBindImage(imID); |
||
1098 | |||
1099 | if(ilLoadImage(imagepath))
|
||
1100 | { |
||
1101 | w = ilGetInteger(IL_IMAGE_WIDTH); |
||
1102 | h = ilGetInteger(IL_IMAGE_HEIGHT); |
||
1103 | int ilformat = ilGetInteger(IL_IMAGE_FORMAT);
|
||
1104 | |||
1105 | if(SetImageData(w, h, ilGetData(), ilformat, GL_UNSIGNED_BYTE)==0) |
||
1106 | { |
||
1107 | done =0;
|
||
1108 | }else if(GlobalUtil::_verbose) |
||
1109 | { |
||
1110 | std::cout<<"Image loaded :\t"<<imagepath<<"\n"; |
||
1111 | } |
||
1112 | |||
1113 | }else
|
||
1114 | { |
||
1115 | std::cerr<<"Unable to open image [code = "<<ilGetError()<<"]\n"; |
||
1116 | done = 0;
|
||
1117 | } |
||
1118 | |||
1119 | ilDeleteImages(1, &imID);
|
||
1120 | |||
1121 | return done;
|
||
1122 | #else
|
||
1123 | FILE * file = fopen(imagepath, "rb"); if (file ==NULL) return 0; |
||
1124 | |||
1125 | char buf[8]; int width, height, cn, g, done = 1; |
||
1126 | |||
1127 | if(fscanf(file, "%s %d %d %d", buf, &width, &height, &cn )<4 || cn > 255 || width < 0 || height < 0) |
||
1128 | { |
||
1129 | fclose(file); |
||
1130 | std::cerr << "ERROR: fileformat not supported\n";
|
||
1131 | return 0; |
||
1132 | }else
|
||
1133 | { |
||
1134 | w = width; |
||
1135 | h = height; |
||
1136 | } |
||
1137 | unsigned char * data = new unsigned char[width * height]; |
||
1138 | unsigned char * pixels = data; |
||
1139 | if (strcmp(buf, "P5")==0 ) |
||
1140 | { |
||
1141 | fscanf(file, "%c",buf);//skip one byte |
||
1142 | fread(pixels, 1, width*height, file);
|
||
1143 | }else if (strcmp(buf, "P2")==0 ) |
||
1144 | { |
||
1145 | for (int i = 0 ; i< height; i++) |
||
1146 | { |
||
1147 | for ( int j = 0; j < width; j++) |
||
1148 | { |
||
1149 | fscanf(file, "%d", &g);
|
||
1150 | *pixels++ = (unsigned char) g; |
||
1151 | } |
||
1152 | } |
||
1153 | }else if (strcmp(buf, "P6")==0 ) |
||
1154 | { |
||
1155 | fscanf(file, "%c", buf);//skip one byte |
||
1156 | int j, num = height*width;
|
||
1157 | unsigned char buf[3]; |
||
1158 | for ( j =0 ; j< num; j++) |
||
1159 | { |
||
1160 | fread(buf,1,3, file); |
||
1161 | *pixels++=int(0.10454f* buf[2]+0.60581f* buf[1]+0.28965f* buf[0]); |
||
1162 | } |
||
1163 | }else if (strcmp(buf, "P3")==0 ) |
||
1164 | { |
||
1165 | int r, g, b;
|
||
1166 | int i , num =height*width;
|
||
1167 | for ( i = 0 ; i< num; i++) |
||
1168 | { |
||
1169 | fscanf(file, "%d %d %d", &r, &g, &b);
|
||
1170 | *pixels++ = int(0.10454f* b+0.60581f* g+0.28965f* r); |
||
1171 | } |
||
1172 | |||
1173 | }else
|
||
1174 | { |
||
1175 | std::cerr << "ERROR: fileformat not supported\n";
|
||
1176 | done = 0;
|
||
1177 | } |
||
1178 | if(done) SetImageData(width, height, data, GL_LUMINANCE, GL_UNSIGNED_BYTE);
|
||
1179 | fclose(file); |
||
1180 | delete data;
|
||
1181 | if(GlobalUtil::_verbose && done) std::cout<< "Image loaded :\t" << imagepath << "\n"; |
||
1182 | return 1; |
||
1183 | #endif
|
||
1184 | } |
||
1185 | |||
1186 | int GLTexImage::CopyToPBO(GLuint pbo, int width, int height, GLenum format) |
||
1187 | { |
||
1188 | /////////
|
||
1189 | if(format != GL_RGBA && format != GL_LUMINANCE) return 0; |
||
1190 | |||
1191 | FrameBufferObject fbo; |
||
1192 | GLint bsize, esize = width * height * sizeof(float) * (format == GL_RGBA ? 4 : 1); |
||
1193 | AttachToFBO(0);
|
||
1194 | glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, pbo); |
||
1195 | glGetBufferParameteriv(GL_PIXEL_PACK_BUFFER_ARB, GL_BUFFER_SIZE, &bsize); |
||
1196 | if(bsize < esize)
|
||
1197 | { |
||
1198 | glBufferData(GL_PIXEL_PACK_BUFFER_ARB, esize, NULL, GL_STATIC_DRAW_ARB);
|
||
1199 | glGetBufferParameteriv(GL_PIXEL_PACK_BUFFER_ARB, GL_BUFFER_SIZE, &bsize); |
||
1200 | } |
||
1201 | if(bsize >= esize)
|
||
1202 | { |
||
1203 | glReadPixels(0, 0, width, height, format, GL_FLOAT, 0); |
||
1204 | } |
||
1205 | glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
|
||
1206 | DetachFBO(0);
|
||
1207 | |||
1208 | return bsize >= esize;
|
||
1209 | } |
||
1210 | |||
1211 | void GLTexInput::VerifyTexture()
|
||
1212 | { |
||
1213 | //for CUDA or OpenCL the texture is not generated by default
|
||
1214 | if(!_data_modified) return; |
||
1215 | if(_pixel_data== NULL) return; |
||
1216 | InitTexture(_imgWidth, _imgHeight); |
||
1217 | BindTex(); |
||
1218 | glTexImage2D( _texTarget, 0, GL_LUMINANCE32F_ARB, //internal format changed |
||
1219 | _imgWidth, _imgHeight, 0,
|
||
1220 | GL_LUMINANCE, GL_FLOAT, _pixel_data); |
||
1221 | UnbindTex(); |
||
1222 | _data_modified = 0;
|
||
1223 | } |
||
1224 | |||
1225 | void GLTexImage::CopyFromPBO(GLuint pbo, int width, int height, GLenum format) |
||
1226 | { |
||
1227 | InitTexture(max(width, _texWidth), max(height, _texHeight)); |
||
1228 | SetImageSize(width, height); |
||
1229 | if(width > 0 && height > 0) |
||
1230 | { |
||
1231 | BindTex(); |
||
1232 | glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo); |
||
1233 | glTexSubImage2D(GlobalUtil::_texTarget, 0, 0, 0, width, height, format, GL_FLOAT, 0); |
||
1234 | GlobalUtil::CheckErrorsGL("GLTexImage::CopyFromPBO->glTexSubImage2D");
|
||
1235 | glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
|
||
1236 | UnbindTex(); |
||
1237 | } |
||
1238 | } |