framework2

Форк
0
1271 строка · 40.7 Кб
1
#include "ofTexture.h"
2
#include "ofGraphics.h"
3
#include "ofPixels.h"
4
#include "ofGLUtils.h"
5
#include "ofGLBaseTypes.h"
6
#include "ofBufferObject.h"
7
#include "ofMesh.h"
8
#include <unordered_map>
9

10
#ifdef TARGET_ANDROID
11
#include "ofAppAndroidWindow.h"
12
#endif
13

14
//----------------------------------------------------------
15
// static
16
static bool bTexHackEnabled = true;
17
static bool	bUsingArbTex		= true;
18
static bool bUsingNormalizedTexCoords = false;
19
static bool bUseCustomMinMagFilters = false;
20

21
using std::set;
22

23
//---------------------------------
24
void ofEnableTextureEdgeHack(){
25
	bTexHackEnabled = true;
26
}
27

28
//---------------------------------
29
void ofDisableTextureEdgeHack(){
30
	bTexHackEnabled = false;
31
}
32

33
//---------------------------------
34
bool ofIsTextureEdgeHackEnabled(){
35
	return bTexHackEnabled;
36
}
37

38
//---------------------------------
39
bool ofGetUsingNormalizedTexCoords(){
40
	return bUsingNormalizedTexCoords;
41
}
42

43
//---------------------------------
44
void ofEnableNormalizedTexCoords(){
45
	bUsingNormalizedTexCoords = true;
46
}
47

48
//---------------------------------
49
void ofDisableNormalizedTexCoords(){
50
	bUsingNormalizedTexCoords = false;
51
}
52

53

54

55
//***** add global functions to override texture settings
56
//----------------------------------------------------------
57
static bool bUseCustomTextureWrap = false;
58

59
//----------------------------------------------------------
60
void ofSetTextureWrap(GLfloat wrapS, GLfloat wrapT){
61
	bUseCustomTextureWrap = true;
62
	GLenum textureTarget = GL_TEXTURE_2D;
63
#ifndef TARGET_OPENGLES
64
	if (ofGetUsingArbTex() && GL_ARB_texture_rectangle){
65
		textureTarget = GL_TEXTURE_RECTANGLE_ARB;
66
	};
67
#endif
68
	glTexParameterf(textureTarget, GL_TEXTURE_WRAP_S, wrapS);
69
	glTexParameterf(textureTarget, GL_TEXTURE_WRAP_T, wrapT);
70
}
71

72
//----------------------------------------------------------
73
bool ofGetUsingCustomTextureWrap(){
74
	return bUseCustomTextureWrap;
75
}
76

77
//----------------------------------------------------------
78
void ofRestoreTextureWrap(){
79
	bUseCustomTextureWrap = false;
80
}
81

82
//----------------------------------------------------------
83
void ofSetMinMagFilters(GLfloat minFilter, GLfloat magFilter){
84
	bUseCustomMinMagFilters = true;
85
	GLenum textureTarget = GL_TEXTURE_2D;
86
#ifndef TARGET_OPENGLES
87
	if (ofGetUsingArbTex() && GL_ARB_texture_rectangle){
88
		textureTarget = GL_TEXTURE_RECTANGLE_ARB;
89
	};
90
#endif
91
	glTexParameterf(textureTarget, GL_TEXTURE_MIN_FILTER, minFilter);
92
	glTexParameterf(textureTarget, GL_TEXTURE_MAG_FILTER, magFilter);
93
}
94

95
//----------------------------------------------------------
96
bool ofGetUsingCustomMinMagFilters(){
97
	return bUseCustomMinMagFilters;
98
}
99

100
//----------------------------------------------------------
101
void ofRestoreMinMagFilters(){
102
	bUseCustomMinMagFilters = false;
103
}
104

105
//***** global functions to override texture settings
106

107

108
//----------------------------------------------------------
109
bool ofGetUsingArbTex(){
110
	return bUsingArbTex;
111
}
112

113
//----------------------------------------------------------
114
void ofEnableArbTex(){
115
	bUsingArbTex = true;
116
}
117

118
//----------------------------------------------------------
119
void ofDisableArbTex(){
120
	bUsingArbTex = false;
121
}
122

123

124
static std::unordered_map<GLuint,int> & getTexturesIndex(){
125
	static std::unordered_map<GLuint,int> * textureReferences = new std::unordered_map<GLuint,int>;
126
	return *textureReferences;
127
}
128

129
static void retain(GLuint id){
130
	if(id!=0){
131
		if(getTexturesIndex().find(id)!=getTexturesIndex().end()){
132
			getTexturesIndex()[id]++;
133
		}else{
134
			getTexturesIndex()[id]=1;
135
		}
136
	}
137
}
138

139
static void release(GLuint id){
140
	// try to free up the texture memory so we don't reallocate
141
	// http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/deletetextures.html
142
	if (id != 0){
143
		if(getTexturesIndex().find(id)!=getTexturesIndex().end()){
144
			getTexturesIndex()[id]--;
145
			if(getTexturesIndex()[id]==0){
146

147
#ifdef TARGET_ANDROID
148
				if (!ofAppAndroidWindow::isSurfaceDestroyed())
149
#endif
150
					glDeleteTextures(1, (GLuint *)&id);
151

152
				getTexturesIndex().erase(id);
153
			}
154
		}else{
155
			ofLogError("ofTexture") << "release(): something's wrong here, releasing unknown texture id " << id;
156

157
#ifdef TARGET_ANDROID
158
			if (!ofAppAndroidWindow::isSurfaceDestroyed())
159
#endif
160
				glDeleteTextures(1, (GLuint *)&id);
161
		}
162
	}
163
}
164

165
#ifdef TARGET_ANDROID
166
static set<ofTexture*> & allTextures(){
167
	static set<ofTexture*> * allTextures = new set<ofTexture*>;
168
	return *allTextures;
169
}
170

171
static void registerTexture(ofTexture * texture){
172
	allTextures().insert(texture);
173
}
174

175
static void unregisterTexture(ofTexture * texture){
176
	allTextures().erase(texture);
177
}
178

179
void ofRegenerateAllTextures(){
180
	for(auto tex: allTextures()){
181
		tex->clear();
182
	}
183
}
184

185
#endif
186

187
//----------------------------------------------------------
188
ofTexture::ofTexture(){
189
	resetAnchor();
190
	bWantsMipmap = false;
191
}
192

193
//----------------------------------------------------------
194
ofTexture::ofTexture(const ofTexture & mom){
195
	anchor = mom.anchor;
196
	bAnchorIsPct = mom.bAnchorIsPct;
197
	texData = mom.texData;
198
	bWantsMipmap = mom.bWantsMipmap;
199
	retain(texData.textureID);
200
#ifdef TARGET_ANDROID
201
	registerTexture(this);
202
#endif
203
}
204

205
ofTexture::ofTexture(ofTexture && mom){
206
    anchor = mom.anchor;
207
    bAnchorIsPct = mom.bAnchorIsPct;
208
    texData = mom.texData;
209
    bWantsMipmap = mom.bWantsMipmap;
210
    mom.texData.bAllocated = 0;
211
    mom.texData.textureID = 0;
212
#ifdef TARGET_ANDROID
213
    registerTexture(this);
214
#endif
215
}
216

217
//----------------------------------------------------------
218
ofTexture& ofTexture::operator=(const ofTexture & mom){
219
	if(!texData.bUseExternalTextureID){
220
		release(texData.textureID);
221
	}
222
	anchor = mom.anchor;
223
	bAnchorIsPct = mom.bAnchorIsPct;
224
	texData = mom.texData;
225
	bWantsMipmap = mom.bWantsMipmap;
226
	retain(texData.textureID);
227
#ifdef TARGET_ANDROID
228
	unregisterTexture(this);
229
#endif
230
	return *this;
231
}
232

233
//----------------------------------------------------------
234
ofTexture& ofTexture::operator=(ofTexture && mom){
235
    if(!texData.bUseExternalTextureID){
236
        release(texData.textureID);
237
    }
238
    anchor = mom.anchor;
239
    bAnchorIsPct = mom.bAnchorIsPct;
240
    texData = mom.texData;
241
    bWantsMipmap = mom.bWantsMipmap;
242
    mom.texData.bAllocated = 0;
243
    mom.texData.textureID = 0;
244
#ifdef TARGET_ANDROID
245
    unregisterTexture(this);
246
#endif
247
    return *this;
248
}
249

250
//----------------------------------------------------------
251
bool ofTexture::bAllocated() const {
252
	return texData.bAllocated;
253
}
254

255
//----------------------------------------------------------
256
bool ofTexture::isAllocated() const {
257
	return texData.bAllocated;
258
}
259

260

261
//----------------------------------------------------------
262
ofTextureData& ofTexture::getTextureData(){
263
	if(!texData.bAllocated){
264
		ofLogError("ofTexture") << "getTextureData(): texture has not been allocated";
265
	}
266
	
267
	return texData;
268
}
269

270
const ofTextureData& ofTexture::getTextureData() const {
271
	if(!texData.bAllocated){
272
		ofLogError("ofTexture") << "getTextureData(): texture has not been allocated";
273
	}
274
	
275
	return texData;
276
}
277

278
//----------------------------------------------------------
279
ofTexture::~ofTexture(){
280
	if(!texData.bUseExternalTextureID){
281
		release(texData.textureID);
282
	}
283
#ifdef TARGET_ANDROID
284
	unregisterTexture(this);
285
#endif
286
}
287

288
//----------------------------------------------------------
289
void ofTexture::clear(){
290
	if(!texData.bUseExternalTextureID){
291
		release(texData.textureID);
292
	}
293
	texData.bUseExternalTextureID = false;
294
	texData.textureID  = 0;
295
	texData.bAllocated = false;
296
}
297

298
//----------------------------------------------------------
299
void ofTexture::setUseExternalTextureID(GLuint externTexID){
300
	clear();
301
	texData.textureID = externTexID;
302
	texData.bAllocated = true;
303
	texData.bUseExternalTextureID = true;
304
}
305

306
//----------------------------------------------------------
307
void ofTexture::allocate(int w, int h, int glInternalFormat){
308
	allocate(w, h, glInternalFormat, ofGetUsingArbTex(), ofGetGLFormatFromInternal(glInternalFormat), ofGetGLTypeFromInternal(glInternalFormat));
309
}
310

311
//----------------------------------------------------------
312
void ofTexture::allocate(int w, int h, int glInternalFormat, bool bUseARBExtension){
313
	allocate(w, h, glInternalFormat, bUseARBExtension, ofGetGLFormatFromInternal(glInternalFormat), ofGetGLTypeFromInternal(glInternalFormat));
314
}
315

316
//----------------------------------------------------------
317
void ofTexture::allocate(int w, int h, int glInternalFormat, int glFormat, int pixelType){
318
	allocate(w, h, glInternalFormat, ofGetUsingArbTex(), glFormat, pixelType);
319
}
320

321
//----------------------------------------------------------
322
void ofTexture::allocate(const ofPixels& pix){
323
	allocate(pix.getWidth(), pix.getHeight(), ofGetGLInternalFormat(pix), ofGetUsingArbTex(), ofGetGLFormat(pix), ofGetGLType(pix));
324
	if((pix.getPixelFormat()==OF_PIXELS_GRAY || pix.getPixelFormat()==OF_PIXELS_GRAY_ALPHA) && ofIsGLProgrammableRenderer()){
325
		setRGToRGBASwizzles(true);
326
	}
327
	if(texData.bAllocated) loadData(pix);
328
}
329

330
//----------------------------------------------------------
331
void ofTexture::allocate(const ofPixels& pix, bool bUseARBExtension){
332
	allocate(pix.getWidth(), pix.getHeight(), ofGetGLInternalFormat(pix), bUseARBExtension, ofGetGLFormat(pix), ofGetGLType(pix));
333
	if((pix.getPixelFormat()==OF_PIXELS_GRAY || pix.getPixelFormat()==OF_PIXELS_GRAY_ALPHA) && ofIsGLProgrammableRenderer()){
334
		setRGToRGBASwizzles(true);
335
	}
336
	if(texData.bAllocated) loadData(pix);
337
}
338

339
//----------------------------------------------------------
340
void ofTexture::allocate(const ofShortPixels& pix){
341
	allocate(pix.getWidth(), pix.getHeight(), ofGetGLInternalFormat(pix), ofGetUsingArbTex(), ofGetGLFormat(pix), ofGetGLType(pix));
342
	if((pix.getPixelFormat()==OF_PIXELS_GRAY || pix.getPixelFormat()==OF_PIXELS_GRAY_ALPHA) && ofIsGLProgrammableRenderer()){
343
		setRGToRGBASwizzles(true);
344
	}
345
	if(texData.bAllocated) loadData(pix);
346
}
347

348
//----------------------------------------------------------
349
void ofTexture::allocate(const ofShortPixels& pix, bool bUseARBExtension){
350
	allocate(pix.getWidth(), pix.getHeight(), ofGetGLInternalFormat(pix), bUseARBExtension, ofGetGLFormat(pix), ofGetGLType(pix));
351
	if((pix.getPixelFormat()==OF_PIXELS_GRAY || pix.getPixelFormat()==OF_PIXELS_GRAY_ALPHA) && ofIsGLProgrammableRenderer()){
352
		setRGToRGBASwizzles(true);
353
	}
354
	if(texData.bAllocated) loadData(pix);
355
}
356

357

358
//----------------------------------------------------------
359
void ofTexture::allocate(const ofFloatPixels& pix){
360
	allocate(pix.getWidth(), pix.getHeight(), ofGetGLInternalFormat(pix), ofGetUsingArbTex(), ofGetGLFormat(pix), ofGetGLType(pix));
361
	if((pix.getPixelFormat()==OF_PIXELS_GRAY || pix.getPixelFormat()==OF_PIXELS_GRAY_ALPHA) && ofIsGLProgrammableRenderer()){
362
		setRGToRGBASwizzles(true);
363
	}
364
	if(texData.bAllocated) loadData(pix);
365
}
366

367
//----------------------------------------------------------
368
void ofTexture::allocate(const ofFloatPixels& pix, bool bUseARBExtension){
369
	allocate(pix.getWidth(), pix.getHeight(), ofGetGLInternalFormat(pix), bUseARBExtension, ofGetGLFormat(pix), ofGetGLType(pix));
370
	if((pix.getPixelFormat()==OF_PIXELS_GRAY || pix.getPixelFormat()==OF_PIXELS_GRAY_ALPHA) && ofIsGLProgrammableRenderer()){
371
		setRGToRGBASwizzles(true);
372
	}
373
	if(texData.bAllocated) loadData(pix);
374
}
375

376
#ifndef TARGET_OPENGLES
377
//----------------------------------------------------------
378
void ofTexture::allocateAsBufferTexture(const ofBufferObject & buffer, int glInternalFormat){
379
	texData.glInternalFormat = glInternalFormat;
380
	texData.textureTarget = GL_TEXTURE_BUFFER;
381
	texData.bufferId = buffer.getId();
382
	allocate(texData,0,0);
383
	buffer.bind(GL_TEXTURE_BUFFER);
384
}
385
#endif
386

387
//----------------------------------------------------------
388
void ofTexture::allocate(int w, int h, int glInternalFormat, bool bUseARBExtension, int glFormat, int pixelType){
389
	texData.width = w;
390
	texData.height = h;
391
	texData.bFlipTexture = false;
392
	texData.glInternalFormat = glInternalFormat;
393
	//our graphics card might not support arb so we have to see if it is supported.
394
#ifndef TARGET_OPENGLES
395
	if (bUseARBExtension && GL_ARB_texture_rectangle){
396
		texData.textureTarget = GL_TEXTURE_RECTANGLE_ARB;
397
	} else 
398
#endif
399
	{
400
		texData.textureTarget = GL_TEXTURE_2D;
401
	}
402
	
403
	allocate(texData,glFormat,pixelType);
404
}
405

406
//----------------------------------------------------------
407

408
void ofTexture::allocate(const ofTextureData & textureData){
409
	allocate(textureData,ofGetGLFormatFromInternal(textureData.glInternalFormat),ofGetGLTypeFromInternal(textureData.glInternalFormat));
410
}
411

412
//----------------------------------------------------------
413

414
void ofTexture::allocate(const ofTextureData & textureData, int glFormat, int pixelType){
415
#ifndef TARGET_OPENGLES
416
	if(texData.textureTarget == GL_TEXTURE_2D || texData.textureTarget == GL_TEXTURE_RECTANGLE_ARB){
417
#else
418
	if(texData.textureTarget == GL_TEXTURE_2D){
419
#endif
420
		if( textureData.width <= 0.0 || textureData.height <= 0.0 ){
421
			ofLogError("ofTexture") << "allocate(): ofTextureData has 0 width and/or height: " << textureData.width << "x" << textureData.height;
422
			return;
423
		}
424
	}
425

426
	texData = textureData;
427
	//our graphics card might not support arb so we have to see if it is supported.
428
#ifndef TARGET_OPENGLES
429
	if( texData.textureTarget==GL_TEXTURE_RECTANGLE_ARB && ofGLSupportsNPOTTextures() ){
430
		texData.tex_w = texData.width;
431
		texData.tex_h = texData.height;
432
		texData.tex_t = texData.width;
433
		texData.tex_u = texData.height;
434
	}else if(texData.textureTarget == GL_TEXTURE_2D)
435
#endif
436
	{
437
		if(ofGLSupportsNPOTTextures()){
438
			texData.tex_w = texData.width;
439
			texData.tex_h = texData.height;
440
		}else{
441
			//otherwise we need to calculate the next power of 2 for the requested dimensions
442
			//ie (320x240) becomes (512x256)
443
			texData.tex_w = ofNextPow2(texData.width);
444
			texData.tex_h = ofNextPow2(texData.height);
445
		}
446

447
		texData.tex_t = texData.width / texData.tex_w;
448
		texData.tex_u = texData.height / texData.tex_h;
449
	}
450

451
	// attempt to free the previous bound texture, if we can:
452
	clear();
453

454
	glGenTextures(1, (GLuint *)&texData.textureID);   // could be more then one, but for now, just one
455
	retain(texData.textureID);
456

457
#ifndef TARGET_OPENGLES
458
	if(texData.textureTarget == GL_TEXTURE_2D || texData.textureTarget == GL_TEXTURE_RECTANGLE_ARB){
459
#else
460
	if(texData.textureTarget == GL_TEXTURE_2D){
461
#endif
462
		glBindTexture(texData.textureTarget,texData.textureID);
463
		glTexImage2D(texData.textureTarget, 0, texData.glInternalFormat, (GLint)texData.tex_w, (GLint)texData.tex_h, 0, glFormat, pixelType, 0);  // init to black...
464

465
		glTexParameterf(texData.textureTarget, GL_TEXTURE_MAG_FILTER, texData.magFilter);
466
		glTexParameterf(texData.textureTarget, GL_TEXTURE_MIN_FILTER, texData.minFilter);
467
		glTexParameterf(texData.textureTarget, GL_TEXTURE_WRAP_S, texData.wrapModeHorizontal);
468
		glTexParameterf(texData.textureTarget, GL_TEXTURE_WRAP_T, texData.wrapModeVertical);
469

470
		#ifndef TARGET_PROGRAMMABLE_GL
471
			if (!ofIsGLProgrammableRenderer()){
472
				glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
473
			}
474
		#endif
475
		glBindTexture(texData.textureTarget,0);
476
	}
477

478
	texData.bAllocated = true;
479

480
#ifdef TARGET_ANDROID
481
	registerTexture(this);
482
#endif
483
}
484

485

486
void ofTexture::setRGToRGBASwizzles(bool rToRGBSwizzles){
487
#ifndef TARGET_OPENGLES
488
	glBindTexture(texData.textureTarget,texData.textureID);
489
	if(rToRGBSwizzles){
490
		if(texData.glInternalFormat==GL_R8 ||
491
			texData.glInternalFormat==GL_R16 ||
492
			texData.glInternalFormat==GL_R32F||
493
			texData.glInternalFormat==GL_DEPTH_COMPONENT
494

495
	#ifndef TARGET_OPENGLES
496
			||
497
			texData.glInternalFormat==GL_DEPTH_COMPONENT16 ||
498
			texData.glInternalFormat==GL_DEPTH_COMPONENT24 ||
499
			texData.glInternalFormat==GL_DEPTH_COMPONENT32
500

501
	#endif
502
		   ){
503
			 glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_R, GL_RED);
504
			 glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_G, GL_RED);
505
			 glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_B, GL_RED);
506

507
		}else if(texData.glInternalFormat==GL_RG8 ||
508
				texData.glInternalFormat==GL_RG16 ||
509
				texData.glInternalFormat==GL_RG32F){
510
			 glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_R, GL_RED);
511
			 glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_G, GL_RED);
512
			 glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_B, GL_RED);
513
			 glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_A, GL_GREEN);
514
		}
515
	}else{
516
		if(texData.glInternalFormat==GL_R8 ||
517
				texData.glInternalFormat==GL_R16 ||
518
				texData.glInternalFormat==GL_R32F){
519
			 glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_R, GL_RED);
520
			 glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
521
			 glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
522

523
		}else if(texData.glInternalFormat==GL_RG8 ||
524
				texData.glInternalFormat==GL_RG16 ||
525
				texData.glInternalFormat==GL_RG32F){
526
			 glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_R, GL_RED);
527
			 glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
528
			 glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
529
			 glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);
530
		}
531
	}
532
	glBindTexture(texData.textureTarget,0);
533
#endif
534
}
535

536
void ofTexture::setSwizzle(GLenum srcSwizzle, GLenum dstChannel){
537
#ifndef TARGET_OPENGLES
538
	glBindTexture(texData.textureTarget,texData.textureID);
539
	glTexParameteri(texData.textureTarget, srcSwizzle, dstChannel);
540
	glBindTexture(texData.textureTarget,0);
541
#endif
542
}
543

544
//----------------------------------------------------------
545
void ofTexture::loadData(const uint8_t * data, int w, int h, int glFormat){
546
	ofSetPixelStoreiAlignment(GL_UNPACK_ALIGNMENT,w,1,ofGetNumChannelsFromGLFormat(glFormat));
547
	loadData(data, w, h, glFormat, GL_UNSIGNED_BYTE);
548
}
549

550
//----------------------------------------------------------
551
void ofTexture::loadData(const uint16_t * data, int w, int h, int glFormat){
552
	ofSetPixelStoreiAlignment(GL_UNPACK_ALIGNMENT,w,2,ofGetNumChannelsFromGLFormat(glFormat));
553
	loadData(data, w, h, glFormat, GL_UNSIGNED_SHORT);
554
}
555

556
//----------------------------------------------------------
557
void ofTexture::loadData(const uint32_t * data, int w, int h, int glFormat){
558
	ofSetPixelStoreiAlignment(GL_UNPACK_ALIGNMENT,w,2,ofGetNumChannelsFromGLFormat(glFormat));
559
	loadData(data, w, h, glFormat, GL_UNSIGNED_INT);
560
}
561

562
//----------------------------------------------------------
563
void ofTexture::loadData(const int8_t * data, int w, int h, int glFormat){
564
	ofSetPixelStoreiAlignment(GL_UNPACK_ALIGNMENT,w,1,ofGetNumChannelsFromGLFormat(glFormat));
565
	loadData(data, w, h, glFormat, GL_BYTE);
566
}
567

568
//----------------------------------------------------------
569
void ofTexture::loadData(const int16_t * data, int w, int h, int glFormat){
570
	ofSetPixelStoreiAlignment(GL_UNPACK_ALIGNMENT,w,2,ofGetNumChannelsFromGLFormat(glFormat));
571
	loadData(data, w, h, glFormat, GL_SHORT);
572
}
573

574
//----------------------------------------------------------
575
void ofTexture::loadData(const int32_t * data, int w, int h, int glFormat){
576
	ofSetPixelStoreiAlignment(GL_UNPACK_ALIGNMENT,w,2,ofGetNumChannelsFromGLFormat(glFormat));
577
	loadData(data, w, h, glFormat, GL_INT);
578
}
579

580
//----------------------------------------------------------
581
void ofTexture::loadData(const float * data, int w, int h, int glFormat){
582
	ofSetPixelStoreiAlignment(GL_UNPACK_ALIGNMENT,w,4,ofGetNumChannelsFromGLFormat(glFormat));
583
	loadData(data, w, h, glFormat, GL_FLOAT);
584
}
585

586
//----------------------------------------------------------
587
void ofTexture::loadData(const ofPixels & pix){
588
	if(!isAllocated()){
589
		allocate(pix);
590
	}else{
591
		ofSetPixelStoreiAlignment(GL_UNPACK_ALIGNMENT,pix.getBytesStride());
592
		loadData(pix.getData(), pix.getWidth(), pix.getHeight(), ofGetGLFormat(pix), ofGetGLType(pix));
593
	}
594
}
595

596
//----------------------------------------------------------
597
void ofTexture::loadData(const ofShortPixels & pix){
598
	if(!isAllocated()){
599
		allocate(pix);
600
	}else{
601
		ofSetPixelStoreiAlignment(GL_UNPACK_ALIGNMENT,pix.getBytesStride());
602
		loadData(pix.getData(), pix.getWidth(), pix.getHeight(), ofGetGLFormat(pix), ofGetGLType(pix));
603
	}
604
}
605

606
//----------------------------------------------------------
607
void ofTexture::loadData(const ofFloatPixels & pix){
608
	if(!isAllocated()){
609
		allocate(pix);
610
	}else{
611
		ofSetPixelStoreiAlignment(GL_UNPACK_ALIGNMENT,pix.getBytesStride());
612
		loadData(pix.getData(), pix.getWidth(), pix.getHeight(), ofGetGLFormat(pix), ofGetGLType(pix));
613
	}
614
}
615

616
//----------------------------------------------------------
617
void ofTexture::loadData(const ofPixels & pix, int glFormat){
618
	if(!isAllocated()){
619
		allocate(pix.getWidth(), pix.getHeight(), ofGetGLInternalFormat(pix), ofGetUsingArbTex(), glFormat, ofGetGLType(pix));
620
	}
621
	ofSetPixelStoreiAlignment(GL_UNPACK_ALIGNMENT,pix.getWidth(),pix.getBytesPerChannel(),ofGetNumChannelsFromGLFormat(glFormat));
622
	loadData(pix.getData(), pix.getWidth(), pix.getHeight(), glFormat, ofGetGLType(pix));
623
}
624

625
//----------------------------------------------------------
626
void ofTexture::loadData(const ofShortPixels & pix, int glFormat){
627
	if(!isAllocated()){
628
		allocate(pix.getWidth(), pix.getHeight(), ofGetGLInternalFormat(pix), ofGetUsingArbTex(), glFormat, ofGetGLType(pix));
629
	}
630
	ofSetPixelStoreiAlignment(GL_UNPACK_ALIGNMENT,pix.getWidth(),pix.getBytesPerChannel(),ofGetNumChannelsFromGLFormat(glFormat));
631
	loadData(pix.getData(), pix.getWidth(), pix.getHeight(), glFormat, ofGetGLType(pix));
632
}
633

634
//----------------------------------------------------------
635
void ofTexture::loadData(const ofFloatPixels & pix, int glFormat){
636
	if(!isAllocated()){
637
		allocate(pix.getWidth(), pix.getHeight(), ofGetGLInternalFormat(pix), ofGetUsingArbTex(), glFormat, ofGetGLType(pix));
638
	}
639
	ofSetPixelStoreiAlignment(GL_UNPACK_ALIGNMENT,pix.getWidth(),pix.getBytesPerChannel(),ofGetNumChannelsFromGLFormat(glFormat));
640
	loadData(pix.getData(), pix.getWidth(), pix.getHeight(), glFormat, ofGetGLType(pix));
641
}
642

643
#ifndef TARGET_OPENGLES
644
//----------------------------------------------------------
645
void ofTexture::loadData(const ofBufferObject & buffer, int glFormat, int glType){
646
	buffer.bind(GL_PIXEL_UNPACK_BUFFER);
647
	loadData(0,texData.width,texData.height,glFormat,glType);
648
	buffer.unbind(GL_PIXEL_UNPACK_BUFFER);
649
}
650
#endif
651

652
//----------------------------------------------------------
653
void ofTexture::loadData(const void * data, int w, int h, int glFormat, int glType){
654

655
	if(w > texData.tex_w || h > texData.tex_h) {
656
		if(isAllocated()){
657
			allocate(w, h, texData.glInternalFormat, glFormat, glType);
658
		}else{
659
			// TODO: guess correct internal from glFormat
660
			allocate(w, h, glFormat, glFormat, glType);
661
		}
662
	}
663
	
664
	// compute new tex co-ords based on the ratio of data's w, h to texture w,h;
665
#ifndef TARGET_OPENGLES
666
	if (texData.textureTarget == GL_TEXTURE_RECTANGLE_ARB){
667
		texData.tex_t = w;
668
		texData.tex_u = h;
669
	} else 
670
#endif
671
	{
672
		texData.tex_t = (float)(w) / (float)texData.tex_w;
673
		texData.tex_u = (float)(h) / (float)texData.tex_h;
674
	}
675
	
676
	// bind texture
677
	glBindTexture(texData.textureTarget, (GLuint) texData.textureID);
678
	//update the texture image:
679
#ifdef TARGET_OF_IOS
680
	glTexImage2D(texData.textureTarget, 0, texData.glInternalFormat, texData.tex_w, texData.tex_h, 0, glFormat, glType, 0);
681
#endif
682
	glTexSubImage2D(texData.textureTarget, 0, 0, 0, w, h, glFormat, glType, data);
683
	// unbind texture target by binding 0
684
	glBindTexture(texData.textureTarget, 0);
685
	
686
	if (bWantsMipmap) {
687
		// auto-generate mipmap, since this ofTexture wants us to.
688
		generateMipmap();
689
	}
690
	
691
}
692

693
//----------------------------------------------------------
694
void ofTexture::generateMipmap(){
695

696
	// Generate mipmaps using hardware-accelerated core GL methods.
697
	
698
	// 1. Check whether the current OpenGL version supports mipmap generation:
699
	//    glGenerateMipmap() was introduced to OpenGL core in 3.0, and
700
	//    OpenGLES core in 2.0 but earlier versions may support it if they
701
	//	  support extension GL_EXT_framebuffer_object
702

703
	bool isGlGenerateMipmapAvailable = false;
704
	if(ofIsGLProgrammableRenderer()){
705
		isGlGenerateMipmapAvailable = true;
706
	}
707
	
708
	
709
	if (!isGlGenerateMipmapAvailable && !ofGLCheckExtension("GL_EXT_framebuffer_object")) {
710
		static bool versionWarningIssued = false;
711
		if (!versionWarningIssued) ofLogWarning() << "Your current OpenGL version does not support mipmap generation via glGenerateMipmap().";
712
		versionWarningIssued = true;
713
		texData.hasMipmap = false;
714
		return;
715
	}
716

717
	// 2. Check whether the texture's texture target supports mipmap generation.
718
	
719
	switch (texData.textureTarget) {
720
			/// OpenGL ES only supports mipmap for the following two texture targets:
721
		case GL_TEXTURE_2D:
722
		case GL_TEXTURE_CUBE_MAP:
723
#ifndef TARGET_OPENGLES
724
			/// OpenGL supports mipmaps for additional texture targets:
725
		case GL_TEXTURE_1D:
726
		case GL_TEXTURE_3D:
727
		case GL_TEXTURE_1D_ARRAY:
728
		case GL_TEXTURE_2D_ARRAY:
729
#endif
730
		{
731
			// All good, this particular texture target supports mipmaps.
732
			
733
			// glEnable(texData.textureTarget);	/// < uncomment this hack if you are unlucky enough to run an older ATI card.
734
			// See also: https://www.opengl.org/wiki/Common_Mistakes#Automatic_mipmap_generation
735

736
			glBindTexture(texData.textureTarget, (GLuint) texData.textureID);
737
			glGenerateMipmap(texData.textureTarget);
738
			glBindTexture(texData.textureTarget, 0);
739
			texData.hasMipmap = true;
740
			break;
741
		}
742
		default:
743
		{
744
			// This particular texture target does not support mipmaps.
745
			static bool warningIssuedAlready = false;
746
			
747
			if (!warningIssuedAlready){
748
				ofLogWarning() << "Mipmaps are not supported for textureTarget 0x" << std::hex << texData.textureTarget << std::endl
749
				<< "Most probably you are trying to create mipmaps from a GL_TEXTURE_RECTANGLE texture." << std::endl
750
				<< "Try ofDisableArbTex() before loading this texture.";
751
				warningIssuedAlready = true;
752
			}
753
			texData.hasMipmap = false;
754
			break;
755
		}
756
	} // end switch(texData.textureTarget)
757
		
758
}
759

760
//----------------------------------------------------------
761
void ofTexture::loadScreenData(int x, int y, int w, int h){
762
	// TODO: this should go into the renderers so it
763
	// doesn't depend on global calls
764
	int screenHeight = ofGetViewportHeight();
765
	y = screenHeight - y;
766
	y -= h; // top, bottom issues
767
	texData.bFlipTexture = true;
768
	
769
	if ( w > texData.tex_w || h > texData.tex_h) {
770
		ofLogError("ofTexture") << "loadScreenData(): " << w << "x" << h << " image data too big for "
771
		<< texData.tex_w << "x " << texData.tex_h << " allocated texture, not uploading";
772
		return;
773
	}
774
	
775
	//update our size with the new dimensions - this should be the same size or smaller than the allocated texture size
776
	texData.width 	= w;
777
	texData.height 	= h;
778
	
779
	//compute new tex co-ords based on the ratio of data's w, h to texture w,h;
780
#ifndef TARGET_OPENGLES // DAMIAN
781
	if (texData.textureTarget == GL_TEXTURE_RECTANGLE_ARB){
782
		texData.tex_t = (float)(w);
783
		texData.tex_u = (float)(h);
784
	} else 
785
#endif
786
	{
787
		texData.tex_t = (float)(w) / (float)texData.tex_w;
788
		texData.tex_u = (float)(h) / (float)texData.tex_h;
789
	}
790
	
791
	
792
	glBindTexture(texData.textureTarget,texData.textureID);
793

794
	glCopyTexSubImage2D(texData.textureTarget, 0,0,0,x,y,w,h);
795

796
	glBindTexture(texData.textureTarget,0);
797
	
798
	if (bWantsMipmap) {
799
		generateMipmap();
800
	}
801
}
802

803

804
//we could cap these values - but it might be more useful
805
//to be able to set anchor points outside the image
806

807
//----------------------------------------------------------
808
void ofTexture::setAnchorPercent(float xPct, float yPct){
809
	anchor.x  = xPct;
810
	anchor.y  = yPct;
811
	
812
	bAnchorIsPct = true;
813
}
814

815
//----------------------------------------------------------
816
void ofTexture::setAnchorPoint(float x, float y){
817
	anchor.x = x;
818
	anchor.y = y;
819
	
820
	bAnchorIsPct = false;
821
}
822

823
//----------------------------------------------------------
824
void ofTexture::resetAnchor(){
825
	anchor = {0.f, 0.f, 0.f};
826
	bAnchorIsPct = false;
827
}
828

829
//----------------------------------------------------------
830
void ofTexture::bind(int textureLocation) const{
831
	ofGetGLRenderer()->bind(*this,textureLocation);
832
}
833

834
//----------------------------------------------------------
835
void ofTexture::unbind(int textureLocation) const{
836
	ofGetGLRenderer()->unbind(*this,textureLocation);
837
}
838

839
#if !defined(TARGET_OPENGLES) && defined(glBindImageTexture)
840
//----------------------------------------------------------
841
void ofTexture::bindAsImage(GLuint unit, GLenum access, GLint level, GLboolean layered, GLint layer){
842
	glBindImageTexture(unit,texData.textureID,level,layered,layer,access,texData.glInternalFormat);
843
}
844
#endif
845

846
//----------------------------------------------------------
847
void ofTexture::setAlphaMask(ofTexture & mask){
848
	if(mask.texData.textureTarget!=this->texData.textureTarget){
849
		ofLogError("ofTexture") << "Cannot set alpha mask with different texture target";
850
	}else{
851
		texData.alphaMask = std::make_shared<ofTexture>(mask);
852
	}
853
}
854

855
//----------------------------------------------------------
856
const ofTexture * ofTexture::getAlphaMask() const{
857
	return texData.alphaMask.get();
858
}
859

860
//----------------------------------------------------------
861
void ofTexture::disableAlphaMask(){
862
	if(texData.alphaMask){
863
		texData.alphaMask.reset();
864
	}
865
}
866

867

868
//----------------------------------------------------------
869
glm::vec2 ofTexture::getCoordFromPoint(float xPos, float yPos) const{
870
	
871
	glm::vec2 temp(0);
872
	
873
	if (!isAllocated()) return temp;
874
	
875
#ifndef TARGET_OPENGLES	
876
	if (texData.textureTarget == GL_TEXTURE_RECTANGLE_ARB){
877
		
878
		temp = {xPos, yPos};
879
		
880
	} else {
881
#endif		
882
		// non arb textures are 0 to 1, so we 
883
		// (a) convert to a pct: 
884
		
885
		float pctx = xPos / texData.width;
886
		float pcty = yPos / texData.height;
887
		
888
		// (b) mult by our internal pct (since we might not be 0-1 internally)
889
		
890
		pctx *= texData.tex_t;
891
		pcty *= texData.tex_u;
892
		
893
		temp = {pctx, pcty};
894
		
895
#ifndef TARGET_OPENGLES	
896
	}
897
#endif		
898
	
899
	return temp;
900
	
901
}
902

903
//----------------------------------------------------------
904
/// Sets a texture matrix that will be uploaded whenever the texture is
905
/// binded.
906
void ofTexture::setTextureMatrix(const glm::mat4 & m){
907
	texData.textureMatrix = m;
908
	texData.useTextureMatrix = true;
909
}
910

911
//----------------------------------------------------------
912
/// Disable the texture matrix.
913
void ofTexture::disableTextureMatrix(){
914
	texData.useTextureMatrix = false;
915
	texData.textureMatrix = glm::mat4(1.0);
916
}
917

918

919
//----------------------------------------------------------
920
const glm::mat4 & ofTexture::getTextureMatrix() const{
921
	return texData.textureMatrix;
922
}
923

924
//----------------------------------------------------------
925
bool ofTexture::isUsingTextureMatrix() const{
926
	return texData.useTextureMatrix;
927
}
928

929
//----------------------------------------------------------
930
glm::vec2 ofTexture::getCoordFromPercent(float xPct, float yPct) const{
931
	
932
	glm::vec2 temp(0);
933
	
934
	if (!isAllocated()) return temp;
935
	
936
#ifndef TARGET_OPENGLES	
937
	if (texData.textureTarget == GL_TEXTURE_RECTANGLE_ARB){
938
		
939
		temp = {xPct * texData.width, yPct * texData.height};
940
		
941
	} else {
942
#endif	
943
		xPct *= texData.tex_t;
944
		yPct *= texData.tex_u;
945
		temp = {xPct, yPct};
946
		
947
#ifndef TARGET_OPENGLES	
948
	}
949
#endif	
950
	return temp;
951
}
952

953

954
//----------------------------------------------------------
955
void ofTexture::setTextureWrap(GLint wrapModeHorizontal, GLint wrapModeVertical) {
956
	glBindTexture(texData.textureTarget,texData.textureID);
957
	glTexParameteri(texData.textureTarget, GL_TEXTURE_WRAP_S, wrapModeHorizontal);
958
	glTexParameteri(texData.textureTarget, GL_TEXTURE_WRAP_T, wrapModeVertical);
959
	texData.wrapModeVertical = wrapModeVertical;
960
	texData.wrapModeHorizontal = wrapModeHorizontal;
961
	glBindTexture(texData.textureTarget,0);
962
}
963

964
//----------------------------------------------------------
965
void ofTexture::setTextureMinMagFilter(GLint minFilter, GLint magFilter){
966

967
	// Issue warning if mipmaps not present for mipmap based min filter.
968
	
969
	if ( (minFilter > GL_LINEAR) && texData.hasMipmap == false ){
970
		static bool hasWarnedNoMipmapsForMinFilter = false;
971
		if(!hasWarnedNoMipmapsForMinFilter) {
972
			ofLogWarning() << "Texture has no mipmaps - but minFilter 0x"<< std::hex << minFilter << " requires mipmaps."
973
			<< std::endl << "Call ofTexture::generateMipmaps() first.";
974
		}
975
		hasWarnedNoMipmapsForMinFilter = true;
976
		return;
977
	}
978

979
	// Issue warning if invalid magFilter specified.
980
	
981
	if ( (magFilter > GL_LINEAR ) ) {
982
		static bool hasWarnedInvalidMagFilter = false;
983
		if (!hasWarnedInvalidMagFilter) {
984
			ofLogWarning() << "magFilter must be either GL_LINEAR or GL_NEAREST.";
985
		}
986
		hasWarnedInvalidMagFilter = true;
987
		return;
988
	}
989

990
	glBindTexture(texData.textureTarget,texData.textureID);
991
	glTexParameteri(texData.textureTarget, GL_TEXTURE_MAG_FILTER, magFilter);
992
	glTexParameteri(texData.textureTarget, GL_TEXTURE_MIN_FILTER, minFilter);
993
	texData.magFilter = magFilter;
994
	texData.minFilter = minFilter;
995
	glBindTexture(texData.textureTarget,0);
996
}
997

998
//----------------------------------------------------------
999
void ofTexture::setCompression(ofTexCompression compression){
1000
	texData.compressionType = compression;
1001
}
1002

1003
//------------------------------------
1004
void ofTexture::enableMipmap(){
1005
	bWantsMipmap = true;
1006
	texData.minFilter = GL_LINEAR_MIPMAP_LINEAR;
1007
}
1008

1009
//------------------------------------
1010
void ofTexture::disableMipmap(){
1011
	bWantsMipmap = false;
1012
	texData.minFilter = GL_LINEAR;
1013
}
1014

1015
//------------------------------------
1016
bool ofTexture::hasMipmap() const{
1017
	return texData.hasMipmap;
1018
}
1019

1020
//------------------------------------
1021
void ofTexture::draw(float x, float y) const{
1022
	draw(x,y,0,getWidth(),getHeight());
1023
}
1024

1025
//------------------------------------
1026
void ofTexture::draw(float x, float y, float z) const{
1027
	draw(x,y,z,getWidth(),getHeight());
1028
}
1029

1030
//------------------------------------
1031
void ofTexture::draw(const glm::vec3 & pos) const{
1032
	draw(pos.x,pos.y,pos.z,getWidth(),getHeight());
1033
}
1034

1035
//------------------------------------
1036
void ofTexture::draw(float x, float y, float w, float h) const{
1037
	draw(x,y,0,w,h);
1038
}
1039

1040
void ofTexture::draw(const glm::vec3 & pos, float w, float h) const{
1041
	draw(pos.x,pos.y,pos.z,w,h);
1042
}
1043

1044
//------------------------------------
1045
void ofTexture::draw(float x, float y, float z, float w, float h) const{
1046
	drawSubsection(x,y,z,w,h,0,0,getWidth(),getHeight());
1047
}
1048

1049
//------------------------------------
1050
void ofTexture::drawSubsection(float x, float y, float w, float h, float sx, float sy) const{
1051
	drawSubsection(x,y,0,w,h,sx,sy,w,h);
1052
}
1053

1054
//------------------------------------
1055
void ofTexture::drawSubsection(float x, float y, float w, float h, float sx, float sy, float _sw, float _sh) const{
1056
	drawSubsection(x,y,0,w,h,sx,sy,_sw,_sh);
1057
}
1058

1059
//------------------------------------
1060
void ofTexture::drawSubsection(const ofRectangle& drawBounds, const ofRectangle& subsectionBounds) const {
1061
	drawSubsection(drawBounds.x,drawBounds.y,0,drawBounds.width,drawBounds.height,subsectionBounds.x,subsectionBounds.y,subsectionBounds.width,subsectionBounds.height);
1062
}
1063

1064
//------------------------------------
1065
void ofTexture::drawSubsection(float x, float y, float z, float w, float h, float sx, float sy) const{
1066
	drawSubsection(x,y,z,w,h,sx,sy,w,h);
1067
}
1068

1069
//----------------------------------------------------------
1070
void ofTexture::drawSubsection(float x, float y, float z, float w, float h, float sx, float sy, float sw, float sh) const{
1071
	std::shared_ptr<ofBaseGLRenderer> renderer = ofGetGLRenderer();
1072
	if(renderer){
1073
		renderer->draw(*this,x,y,z,w,h,sx,sy,sw,sh);
1074
	}
1075
}
1076

1077

1078
//------------------------------------
1079
ofMesh ofTexture::getMeshForSubsection(float x, float y, float z, float w, float h, float sx, float sy, float sw, float sh, bool vflipped, ofRectMode rectMode) const{
1080
	ofMesh quad;
1081
	if(!texData.bAllocated){
1082
		return quad;
1083
	}
1084

1085
	GLfloat px0 = x;		// up to you to get the aspect ratio right
1086
	GLfloat py0 = y;
1087
	GLfloat px1 = w+x;
1088
	GLfloat py1 = h+y;
1089

1090
	if (texData.bFlipTexture == vflipped){
1091
		std::swap(py0,py1);
1092
	}
1093

1094
	// for rect mode center, let's do this:
1095
	if (rectMode == OF_RECTMODE_CENTER){
1096
		px0 -= w/2;
1097
		py0 -= h/2;
1098
		px1 -= w/2;
1099
		py1 -= h/2;
1100
	}
1101

1102
	//we translate our drawing points by our anchor point.
1103
	//we still respect ofRectMode so if you have rect mode set to
1104
	//OF_RECTMODE_CENTER your anchor will be relative to that.
1105
	GLfloat anchorX;
1106
	GLfloat anchorY;
1107

1108
	if(bAnchorIsPct){
1109
		anchorX = anchor.x * w;
1110
		anchorY = anchor.y * h;
1111
	}else{
1112
		anchorX = anchor.x;
1113
		anchorY = anchor.y;
1114
	}
1115

1116
	px0 -= anchorX;
1117
	py0 -= anchorY;
1118
	px1 -= anchorX;
1119
	py1 -= anchorY;
1120

1121

1122
	// -------------------------------------------------
1123
	// complete hack to remove border artifacts.
1124
	// slightly, slightly alters an image, scaling...
1125
	// to remove the border.
1126
	// we need a better solution for this, but
1127
	// to constantly add a 2 pixel border on all uploaded images
1128
	// is insane..
1129

1130
	GLfloat offsetw = 0.0f;
1131
	GLfloat offseth = 0.0f;
1132

1133
	if (!ofGLSupportsNPOTTextures() && bTexHackEnabled) {
1134
		offsetw = 1.0f / (texData.tex_w);
1135
		offseth = 1.0f / (texData.tex_h);
1136
	}
1137
	// -------------------------------------------------
1138

1139
	auto topLeft = getCoordFromPoint(sx, sy);
1140
	auto bottomRight = getCoordFromPoint(sx + sw, sy + sh);
1141

1142
	GLfloat tx0 = topLeft.x + offsetw;
1143
	GLfloat ty0 = topLeft.y + offseth;
1144
	GLfloat tx1 = bottomRight.x - offsetw;
1145
	GLfloat ty1 = bottomRight.y - offseth;
1146

1147
	quad.setMode(OF_PRIMITIVE_TRIANGLE_FAN);
1148
	quad.getVertices().resize(4);
1149
	quad.getTexCoords().resize(4);
1150
	quad.getVertices()[0] = {px0,py0,z};
1151
	quad.getVertices()[1] = {px1,py0,z};
1152
	quad.getVertices()[2] = {px1,py1,z};
1153
	quad.getVertices()[3] = {px0,py1,z};
1154

1155
	quad.getTexCoords()[0] = {tx0,ty0};
1156
	quad.getTexCoords()[1] = {tx1,ty0};
1157
	quad.getTexCoords()[2] = {tx1,ty1};
1158
	quad.getTexCoords()[3] = {tx0,ty1};
1159

1160
	return quad;
1161
}
1162

1163
// ROGER
1164
//----------------------------------------------------------
1165
void ofTexture::draw(const glm::vec3 & p1, const glm::vec3 & p2, const glm::vec3 & p3, const glm::vec3 & p4) const{
1166

1167
	// make sure we are on unit 0 - we may change this when setting shader samplers
1168
	// before glEnable or else the shader gets confused
1169
	/// ps: maybe if bUsingArbTex is enabled we should use glActiveTextureARB?
1170
	//glActiveTexture(GL_TEXTURE0);
1171
	std::shared_ptr<ofBaseGLRenderer> renderer = ofGetGLRenderer();
1172
	if(renderer){
1173
		bind(0);
1174
		renderer->draw(getQuad(p1,p2,p3,p4),OF_MESH_FILL);
1175
		unbind(0);
1176
	}
1177
}
1178

1179
ofMesh ofTexture::getQuad(const glm::vec3 & p1, const glm::vec3 & p2, const glm::vec3 & p3, const glm::vec3 & p4) const{
1180
	// -------------------------------------------------
1181
	// complete hack to remove border artifacts.
1182
	// slightly, slightly alters an image, scaling...
1183
	// to remove the border.
1184
	// we need a better solution for this, but
1185
	// to constantly add a 2 pixel border on all uploaded images
1186
	// is insane..
1187
	
1188
	GLfloat offsetw = 0.0f;
1189
	GLfloat offseth = 0.0f;
1190
	
1191
	if (texData.textureTarget == GL_TEXTURE_2D && bTexHackEnabled) {
1192
		offsetw = 1.0f / (texData.tex_w);
1193
		offseth = 1.0f / (texData.tex_h);
1194
	}
1195
	// -------------------------------------------------
1196
	
1197
	GLfloat tx0 = 0+offsetw;
1198
	GLfloat ty0 = 0+offseth;
1199
	GLfloat tx1 = texData.tex_t - offsetw;
1200
	GLfloat ty1 = texData.tex_u - offseth;
1201

1202
	ofMesh quad;
1203
	quad.getVertices().resize(4);
1204
	quad.getTexCoords().resize(4);
1205
	quad.setMode(OF_PRIMITIVE_TRIANGLE_FAN);
1206
	quad.getVertices()[0] = {p1.x, p1.y, p1.z};
1207
	quad.getVertices()[1] = {p2.x, p2.y, p2.z};
1208
	quad.getVertices()[2] = {p3.x, p3.y, p3.z};
1209
	quad.getVertices()[3] = {p4.x, p4.y, p4.z};
1210
	
1211
	quad.getTexCoords()[0] = {tx0,ty0};
1212
	quad.getTexCoords()[1] = {tx1,ty0};
1213
	quad.getTexCoords()[2] = {tx1,ty1};
1214
	quad.getTexCoords()[3] = {tx0,ty1};
1215
	return quad;
1216
}
1217

1218
//----------------------------------------------------------
1219
void ofTexture::readToPixels(ofPixels & pixels) const {
1220
#ifndef TARGET_OPENGLES
1221
	pixels.allocate(texData.width,texData.height,ofGetImageTypeFromGLType(texData.glInternalFormat));
1222
	ofSetPixelStoreiAlignment(GL_PACK_ALIGNMENT,pixels.getWidth(),pixels.getBytesPerChannel(),pixels.getNumChannels());
1223
	glBindTexture(texData.textureTarget,texData.textureID);
1224
	glGetTexImage(texData.textureTarget,0,ofGetGLFormat(pixels),GL_UNSIGNED_BYTE, pixels.getData());
1225
	glBindTexture(texData.textureTarget,0);
1226
#endif
1227
}
1228

1229
//----------------------------------------------------------
1230
void ofTexture::readToPixels(ofShortPixels & pixels) const {
1231
#ifndef TARGET_OPENGLES
1232
	pixels.allocate(texData.width,texData.height,ofGetImageTypeFromGLType(texData.glInternalFormat));
1233
	ofSetPixelStoreiAlignment(GL_PACK_ALIGNMENT,pixels.getWidth(),pixels.getBytesPerChannel(),pixels.getNumChannels());
1234
	glBindTexture(texData.textureTarget,texData.textureID);
1235
	glGetTexImage(texData.textureTarget,0,ofGetGLFormat(pixels),GL_UNSIGNED_SHORT,pixels.getData());
1236
	glBindTexture(texData.textureTarget,0);
1237
#endif
1238
}
1239

1240
void ofTexture::readToPixels(ofFloatPixels & pixels) const {
1241
#ifndef TARGET_OPENGLES
1242
	pixels.allocate(texData.width,texData.height,ofGetImageTypeFromGLType(texData.glInternalFormat));
1243
	ofSetPixelStoreiAlignment(GL_PACK_ALIGNMENT,pixels.getWidth(),pixels.getBytesPerChannel(),pixels.getNumChannels());
1244
	glBindTexture(texData.textureTarget,texData.textureID);
1245
	glGetTexImage(texData.textureTarget,0,ofGetGLFormat(pixels),GL_FLOAT,pixels.getData());
1246
	glBindTexture(texData.textureTarget,0);
1247
#endif
1248
}
1249

1250
#ifndef TARGET_OPENGLES
1251
//----------------------------------------------------------
1252
void ofTexture::copyTo(ofBufferObject & buffer) const{
1253
	ofSetPixelStoreiAlignment(GL_PACK_ALIGNMENT,getWidth(),ofGetBytesPerChannelFromGLType(ofGetGLTypeFromInternal(texData.glInternalFormat)),ofGetNumChannelsFromGLFormat(ofGetGLFormatFromInternal(texData.glInternalFormat)));
1254
	buffer.bind(GL_PIXEL_PACK_BUFFER);
1255
	glBindTexture(texData.textureTarget,texData.textureID);
1256
	glGetTexImage(texData.textureTarget,0,ofGetGLFormatFromInternal(texData.glInternalFormat),ofGetGLTypeFromInternal(texData.glInternalFormat),0);
1257
	glBindTexture(texData.textureTarget,0);
1258
	buffer.unbind(GL_PIXEL_PACK_BUFFER);
1259

1260
}
1261
#endif
1262

1263
//----------------------------------------------------------
1264
float ofTexture::getHeight() const {
1265
	return texData.height;
1266
}
1267

1268
//----------------------------------------------------------
1269
float ofTexture::getWidth() const {
1270
	return texData.width;
1271
}
1272

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.