framework2
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
16static bool bTexHackEnabled = true;
17static bool bUsingArbTex = true;
18static bool bUsingNormalizedTexCoords = false;
19static bool bUseCustomMinMagFilters = false;
20
21using std::set;
22
23//---------------------------------
24void ofEnableTextureEdgeHack(){
25bTexHackEnabled = true;
26}
27
28//---------------------------------
29void ofDisableTextureEdgeHack(){
30bTexHackEnabled = false;
31}
32
33//---------------------------------
34bool ofIsTextureEdgeHackEnabled(){
35return bTexHackEnabled;
36}
37
38//---------------------------------
39bool ofGetUsingNormalizedTexCoords(){
40return bUsingNormalizedTexCoords;
41}
42
43//---------------------------------
44void ofEnableNormalizedTexCoords(){
45bUsingNormalizedTexCoords = true;
46}
47
48//---------------------------------
49void ofDisableNormalizedTexCoords(){
50bUsingNormalizedTexCoords = false;
51}
52
53
54
55//***** add global functions to override texture settings
56//----------------------------------------------------------
57static bool bUseCustomTextureWrap = false;
58
59//----------------------------------------------------------
60void ofSetTextureWrap(GLfloat wrapS, GLfloat wrapT){
61bUseCustomTextureWrap = true;
62GLenum textureTarget = GL_TEXTURE_2D;
63#ifndef TARGET_OPENGLES
64if (ofGetUsingArbTex() && GL_ARB_texture_rectangle){
65textureTarget = GL_TEXTURE_RECTANGLE_ARB;
66};
67#endif
68glTexParameterf(textureTarget, GL_TEXTURE_WRAP_S, wrapS);
69glTexParameterf(textureTarget, GL_TEXTURE_WRAP_T, wrapT);
70}
71
72//----------------------------------------------------------
73bool ofGetUsingCustomTextureWrap(){
74return bUseCustomTextureWrap;
75}
76
77//----------------------------------------------------------
78void ofRestoreTextureWrap(){
79bUseCustomTextureWrap = false;
80}
81
82//----------------------------------------------------------
83void ofSetMinMagFilters(GLfloat minFilter, GLfloat magFilter){
84bUseCustomMinMagFilters = true;
85GLenum textureTarget = GL_TEXTURE_2D;
86#ifndef TARGET_OPENGLES
87if (ofGetUsingArbTex() && GL_ARB_texture_rectangle){
88textureTarget = GL_TEXTURE_RECTANGLE_ARB;
89};
90#endif
91glTexParameterf(textureTarget, GL_TEXTURE_MIN_FILTER, minFilter);
92glTexParameterf(textureTarget, GL_TEXTURE_MAG_FILTER, magFilter);
93}
94
95//----------------------------------------------------------
96bool ofGetUsingCustomMinMagFilters(){
97return bUseCustomMinMagFilters;
98}
99
100//----------------------------------------------------------
101void ofRestoreMinMagFilters(){
102bUseCustomMinMagFilters = false;
103}
104
105//***** global functions to override texture settings
106
107
108//----------------------------------------------------------
109bool ofGetUsingArbTex(){
110return bUsingArbTex;
111}
112
113//----------------------------------------------------------
114void ofEnableArbTex(){
115bUsingArbTex = true;
116}
117
118//----------------------------------------------------------
119void ofDisableArbTex(){
120bUsingArbTex = false;
121}
122
123
124static std::unordered_map<GLuint,int> & getTexturesIndex(){
125static std::unordered_map<GLuint,int> * textureReferences = new std::unordered_map<GLuint,int>;
126return *textureReferences;
127}
128
129static void retain(GLuint id){
130if(id!=0){
131if(getTexturesIndex().find(id)!=getTexturesIndex().end()){
132getTexturesIndex()[id]++;
133}else{
134getTexturesIndex()[id]=1;
135}
136}
137}
138
139static 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
142if (id != 0){
143if(getTexturesIndex().find(id)!=getTexturesIndex().end()){
144getTexturesIndex()[id]--;
145if(getTexturesIndex()[id]==0){
146
147#ifdef TARGET_ANDROID
148if (!ofAppAndroidWindow::isSurfaceDestroyed())
149#endif
150glDeleteTextures(1, (GLuint *)&id);
151
152getTexturesIndex().erase(id);
153}
154}else{
155ofLogError("ofTexture") << "release(): something's wrong here, releasing unknown texture id " << id;
156
157#ifdef TARGET_ANDROID
158if (!ofAppAndroidWindow::isSurfaceDestroyed())
159#endif
160glDeleteTextures(1, (GLuint *)&id);
161}
162}
163}
164
165#ifdef TARGET_ANDROID
166static set<ofTexture*> & allTextures(){
167static set<ofTexture*> * allTextures = new set<ofTexture*>;
168return *allTextures;
169}
170
171static void registerTexture(ofTexture * texture){
172allTextures().insert(texture);
173}
174
175static void unregisterTexture(ofTexture * texture){
176allTextures().erase(texture);
177}
178
179void ofRegenerateAllTextures(){
180for(auto tex: allTextures()){
181tex->clear();
182}
183}
184
185#endif
186
187//----------------------------------------------------------
188ofTexture::ofTexture(){
189resetAnchor();
190bWantsMipmap = false;
191}
192
193//----------------------------------------------------------
194ofTexture::ofTexture(const ofTexture & mom){
195anchor = mom.anchor;
196bAnchorIsPct = mom.bAnchorIsPct;
197texData = mom.texData;
198bWantsMipmap = mom.bWantsMipmap;
199retain(texData.textureID);
200#ifdef TARGET_ANDROID
201registerTexture(this);
202#endif
203}
204
205ofTexture::ofTexture(ofTexture && mom){
206anchor = mom.anchor;
207bAnchorIsPct = mom.bAnchorIsPct;
208texData = mom.texData;
209bWantsMipmap = mom.bWantsMipmap;
210mom.texData.bAllocated = 0;
211mom.texData.textureID = 0;
212#ifdef TARGET_ANDROID
213registerTexture(this);
214#endif
215}
216
217//----------------------------------------------------------
218ofTexture& ofTexture::operator=(const ofTexture & mom){
219if(!texData.bUseExternalTextureID){
220release(texData.textureID);
221}
222anchor = mom.anchor;
223bAnchorIsPct = mom.bAnchorIsPct;
224texData = mom.texData;
225bWantsMipmap = mom.bWantsMipmap;
226retain(texData.textureID);
227#ifdef TARGET_ANDROID
228unregisterTexture(this);
229#endif
230return *this;
231}
232
233//----------------------------------------------------------
234ofTexture& ofTexture::operator=(ofTexture && mom){
235if(!texData.bUseExternalTextureID){
236release(texData.textureID);
237}
238anchor = mom.anchor;
239bAnchorIsPct = mom.bAnchorIsPct;
240texData = mom.texData;
241bWantsMipmap = mom.bWantsMipmap;
242mom.texData.bAllocated = 0;
243mom.texData.textureID = 0;
244#ifdef TARGET_ANDROID
245unregisterTexture(this);
246#endif
247return *this;
248}
249
250//----------------------------------------------------------
251bool ofTexture::bAllocated() const {
252return texData.bAllocated;
253}
254
255//----------------------------------------------------------
256bool ofTexture::isAllocated() const {
257return texData.bAllocated;
258}
259
260
261//----------------------------------------------------------
262ofTextureData& ofTexture::getTextureData(){
263if(!texData.bAllocated){
264ofLogError("ofTexture") << "getTextureData(): texture has not been allocated";
265}
266
267return texData;
268}
269
270const ofTextureData& ofTexture::getTextureData() const {
271if(!texData.bAllocated){
272ofLogError("ofTexture") << "getTextureData(): texture has not been allocated";
273}
274
275return texData;
276}
277
278//----------------------------------------------------------
279ofTexture::~ofTexture(){
280if(!texData.bUseExternalTextureID){
281release(texData.textureID);
282}
283#ifdef TARGET_ANDROID
284unregisterTexture(this);
285#endif
286}
287
288//----------------------------------------------------------
289void ofTexture::clear(){
290if(!texData.bUseExternalTextureID){
291release(texData.textureID);
292}
293texData.bUseExternalTextureID = false;
294texData.textureID = 0;
295texData.bAllocated = false;
296}
297
298//----------------------------------------------------------
299void ofTexture::setUseExternalTextureID(GLuint externTexID){
300clear();
301texData.textureID = externTexID;
302texData.bAllocated = true;
303texData.bUseExternalTextureID = true;
304}
305
306//----------------------------------------------------------
307void ofTexture::allocate(int w, int h, int glInternalFormat){
308allocate(w, h, glInternalFormat, ofGetUsingArbTex(), ofGetGLFormatFromInternal(glInternalFormat), ofGetGLTypeFromInternal(glInternalFormat));
309}
310
311//----------------------------------------------------------
312void ofTexture::allocate(int w, int h, int glInternalFormat, bool bUseARBExtension){
313allocate(w, h, glInternalFormat, bUseARBExtension, ofGetGLFormatFromInternal(glInternalFormat), ofGetGLTypeFromInternal(glInternalFormat));
314}
315
316//----------------------------------------------------------
317void ofTexture::allocate(int w, int h, int glInternalFormat, int glFormat, int pixelType){
318allocate(w, h, glInternalFormat, ofGetUsingArbTex(), glFormat, pixelType);
319}
320
321//----------------------------------------------------------
322void ofTexture::allocate(const ofPixels& pix){
323allocate(pix.getWidth(), pix.getHeight(), ofGetGLInternalFormat(pix), ofGetUsingArbTex(), ofGetGLFormat(pix), ofGetGLType(pix));
324if((pix.getPixelFormat()==OF_PIXELS_GRAY || pix.getPixelFormat()==OF_PIXELS_GRAY_ALPHA) && ofIsGLProgrammableRenderer()){
325setRGToRGBASwizzles(true);
326}
327if(texData.bAllocated) loadData(pix);
328}
329
330//----------------------------------------------------------
331void ofTexture::allocate(const ofPixels& pix, bool bUseARBExtension){
332allocate(pix.getWidth(), pix.getHeight(), ofGetGLInternalFormat(pix), bUseARBExtension, ofGetGLFormat(pix), ofGetGLType(pix));
333if((pix.getPixelFormat()==OF_PIXELS_GRAY || pix.getPixelFormat()==OF_PIXELS_GRAY_ALPHA) && ofIsGLProgrammableRenderer()){
334setRGToRGBASwizzles(true);
335}
336if(texData.bAllocated) loadData(pix);
337}
338
339//----------------------------------------------------------
340void ofTexture::allocate(const ofShortPixels& pix){
341allocate(pix.getWidth(), pix.getHeight(), ofGetGLInternalFormat(pix), ofGetUsingArbTex(), ofGetGLFormat(pix), ofGetGLType(pix));
342if((pix.getPixelFormat()==OF_PIXELS_GRAY || pix.getPixelFormat()==OF_PIXELS_GRAY_ALPHA) && ofIsGLProgrammableRenderer()){
343setRGToRGBASwizzles(true);
344}
345if(texData.bAllocated) loadData(pix);
346}
347
348//----------------------------------------------------------
349void ofTexture::allocate(const ofShortPixels& pix, bool bUseARBExtension){
350allocate(pix.getWidth(), pix.getHeight(), ofGetGLInternalFormat(pix), bUseARBExtension, ofGetGLFormat(pix), ofGetGLType(pix));
351if((pix.getPixelFormat()==OF_PIXELS_GRAY || pix.getPixelFormat()==OF_PIXELS_GRAY_ALPHA) && ofIsGLProgrammableRenderer()){
352setRGToRGBASwizzles(true);
353}
354if(texData.bAllocated) loadData(pix);
355}
356
357
358//----------------------------------------------------------
359void ofTexture::allocate(const ofFloatPixels& pix){
360allocate(pix.getWidth(), pix.getHeight(), ofGetGLInternalFormat(pix), ofGetUsingArbTex(), ofGetGLFormat(pix), ofGetGLType(pix));
361if((pix.getPixelFormat()==OF_PIXELS_GRAY || pix.getPixelFormat()==OF_PIXELS_GRAY_ALPHA) && ofIsGLProgrammableRenderer()){
362setRGToRGBASwizzles(true);
363}
364if(texData.bAllocated) loadData(pix);
365}
366
367//----------------------------------------------------------
368void ofTexture::allocate(const ofFloatPixels& pix, bool bUseARBExtension){
369allocate(pix.getWidth(), pix.getHeight(), ofGetGLInternalFormat(pix), bUseARBExtension, ofGetGLFormat(pix), ofGetGLType(pix));
370if((pix.getPixelFormat()==OF_PIXELS_GRAY || pix.getPixelFormat()==OF_PIXELS_GRAY_ALPHA) && ofIsGLProgrammableRenderer()){
371setRGToRGBASwizzles(true);
372}
373if(texData.bAllocated) loadData(pix);
374}
375
376#ifndef TARGET_OPENGLES
377//----------------------------------------------------------
378void ofTexture::allocateAsBufferTexture(const ofBufferObject & buffer, int glInternalFormat){
379texData.glInternalFormat = glInternalFormat;
380texData.textureTarget = GL_TEXTURE_BUFFER;
381texData.bufferId = buffer.getId();
382allocate(texData,0,0);
383buffer.bind(GL_TEXTURE_BUFFER);
384}
385#endif
386
387//----------------------------------------------------------
388void ofTexture::allocate(int w, int h, int glInternalFormat, bool bUseARBExtension, int glFormat, int pixelType){
389texData.width = w;
390texData.height = h;
391texData.bFlipTexture = false;
392texData.glInternalFormat = glInternalFormat;
393//our graphics card might not support arb so we have to see if it is supported.
394#ifndef TARGET_OPENGLES
395if (bUseARBExtension && GL_ARB_texture_rectangle){
396texData.textureTarget = GL_TEXTURE_RECTANGLE_ARB;
397} else
398#endif
399{
400texData.textureTarget = GL_TEXTURE_2D;
401}
402
403allocate(texData,glFormat,pixelType);
404}
405
406//----------------------------------------------------------
407
408void ofTexture::allocate(const ofTextureData & textureData){
409allocate(textureData,ofGetGLFormatFromInternal(textureData.glInternalFormat),ofGetGLTypeFromInternal(textureData.glInternalFormat));
410}
411
412//----------------------------------------------------------
413
414void ofTexture::allocate(const ofTextureData & textureData, int glFormat, int pixelType){
415#ifndef TARGET_OPENGLES
416if(texData.textureTarget == GL_TEXTURE_2D || texData.textureTarget == GL_TEXTURE_RECTANGLE_ARB){
417#else
418if(texData.textureTarget == GL_TEXTURE_2D){
419#endif
420if( textureData.width <= 0.0 || textureData.height <= 0.0 ){
421ofLogError("ofTexture") << "allocate(): ofTextureData has 0 width and/or height: " << textureData.width << "x" << textureData.height;
422return;
423}
424}
425
426texData = textureData;
427//our graphics card might not support arb so we have to see if it is supported.
428#ifndef TARGET_OPENGLES
429if( texData.textureTarget==GL_TEXTURE_RECTANGLE_ARB && ofGLSupportsNPOTTextures() ){
430texData.tex_w = texData.width;
431texData.tex_h = texData.height;
432texData.tex_t = texData.width;
433texData.tex_u = texData.height;
434}else if(texData.textureTarget == GL_TEXTURE_2D)
435#endif
436{
437if(ofGLSupportsNPOTTextures()){
438texData.tex_w = texData.width;
439texData.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)
443texData.tex_w = ofNextPow2(texData.width);
444texData.tex_h = ofNextPow2(texData.height);
445}
446
447texData.tex_t = texData.width / texData.tex_w;
448texData.tex_u = texData.height / texData.tex_h;
449}
450
451// attempt to free the previous bound texture, if we can:
452clear();
453
454glGenTextures(1, (GLuint *)&texData.textureID); // could be more then one, but for now, just one
455retain(texData.textureID);
456
457#ifndef TARGET_OPENGLES
458if(texData.textureTarget == GL_TEXTURE_2D || texData.textureTarget == GL_TEXTURE_RECTANGLE_ARB){
459#else
460if(texData.textureTarget == GL_TEXTURE_2D){
461#endif
462glBindTexture(texData.textureTarget,texData.textureID);
463glTexImage2D(texData.textureTarget, 0, texData.glInternalFormat, (GLint)texData.tex_w, (GLint)texData.tex_h, 0, glFormat, pixelType, 0); // init to black...
464
465glTexParameterf(texData.textureTarget, GL_TEXTURE_MAG_FILTER, texData.magFilter);
466glTexParameterf(texData.textureTarget, GL_TEXTURE_MIN_FILTER, texData.minFilter);
467glTexParameterf(texData.textureTarget, GL_TEXTURE_WRAP_S, texData.wrapModeHorizontal);
468glTexParameterf(texData.textureTarget, GL_TEXTURE_WRAP_T, texData.wrapModeVertical);
469
470#ifndef TARGET_PROGRAMMABLE_GL
471if (!ofIsGLProgrammableRenderer()){
472glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
473}
474#endif
475glBindTexture(texData.textureTarget,0);
476}
477
478texData.bAllocated = true;
479
480#ifdef TARGET_ANDROID
481registerTexture(this);
482#endif
483}
484
485
486void ofTexture::setRGToRGBASwizzles(bool rToRGBSwizzles){
487#ifndef TARGET_OPENGLES
488glBindTexture(texData.textureTarget,texData.textureID);
489if(rToRGBSwizzles){
490if(texData.glInternalFormat==GL_R8 ||
491texData.glInternalFormat==GL_R16 ||
492texData.glInternalFormat==GL_R32F||
493texData.glInternalFormat==GL_DEPTH_COMPONENT
494
495#ifndef TARGET_OPENGLES
496||
497texData.glInternalFormat==GL_DEPTH_COMPONENT16 ||
498texData.glInternalFormat==GL_DEPTH_COMPONENT24 ||
499texData.glInternalFormat==GL_DEPTH_COMPONENT32
500
501#endif
502){
503glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_R, GL_RED);
504glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_G, GL_RED);
505glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_B, GL_RED);
506
507}else if(texData.glInternalFormat==GL_RG8 ||
508texData.glInternalFormat==GL_RG16 ||
509texData.glInternalFormat==GL_RG32F){
510glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_R, GL_RED);
511glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_G, GL_RED);
512glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_B, GL_RED);
513glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_A, GL_GREEN);
514}
515}else{
516if(texData.glInternalFormat==GL_R8 ||
517texData.glInternalFormat==GL_R16 ||
518texData.glInternalFormat==GL_R32F){
519glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_R, GL_RED);
520glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
521glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
522
523}else if(texData.glInternalFormat==GL_RG8 ||
524texData.glInternalFormat==GL_RG16 ||
525texData.glInternalFormat==GL_RG32F){
526glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_R, GL_RED);
527glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
528glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
529glTexParameteri(texData.textureTarget, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);
530}
531}
532glBindTexture(texData.textureTarget,0);
533#endif
534}
535
536void ofTexture::setSwizzle(GLenum srcSwizzle, GLenum dstChannel){
537#ifndef TARGET_OPENGLES
538glBindTexture(texData.textureTarget,texData.textureID);
539glTexParameteri(texData.textureTarget, srcSwizzle, dstChannel);
540glBindTexture(texData.textureTarget,0);
541#endif
542}
543
544//----------------------------------------------------------
545void ofTexture::loadData(const uint8_t * data, int w, int h, int glFormat){
546ofSetPixelStoreiAlignment(GL_UNPACK_ALIGNMENT,w,1,ofGetNumChannelsFromGLFormat(glFormat));
547loadData(data, w, h, glFormat, GL_UNSIGNED_BYTE);
548}
549
550//----------------------------------------------------------
551void ofTexture::loadData(const uint16_t * data, int w, int h, int glFormat){
552ofSetPixelStoreiAlignment(GL_UNPACK_ALIGNMENT,w,2,ofGetNumChannelsFromGLFormat(glFormat));
553loadData(data, w, h, glFormat, GL_UNSIGNED_SHORT);
554}
555
556//----------------------------------------------------------
557void ofTexture::loadData(const uint32_t * data, int w, int h, int glFormat){
558ofSetPixelStoreiAlignment(GL_UNPACK_ALIGNMENT,w,2,ofGetNumChannelsFromGLFormat(glFormat));
559loadData(data, w, h, glFormat, GL_UNSIGNED_INT);
560}
561
562//----------------------------------------------------------
563void ofTexture::loadData(const int8_t * data, int w, int h, int glFormat){
564ofSetPixelStoreiAlignment(GL_UNPACK_ALIGNMENT,w,1,ofGetNumChannelsFromGLFormat(glFormat));
565loadData(data, w, h, glFormat, GL_BYTE);
566}
567
568//----------------------------------------------------------
569void ofTexture::loadData(const int16_t * data, int w, int h, int glFormat){
570ofSetPixelStoreiAlignment(GL_UNPACK_ALIGNMENT,w,2,ofGetNumChannelsFromGLFormat(glFormat));
571loadData(data, w, h, glFormat, GL_SHORT);
572}
573
574//----------------------------------------------------------
575void ofTexture::loadData(const int32_t * data, int w, int h, int glFormat){
576ofSetPixelStoreiAlignment(GL_UNPACK_ALIGNMENT,w,2,ofGetNumChannelsFromGLFormat(glFormat));
577loadData(data, w, h, glFormat, GL_INT);
578}
579
580//----------------------------------------------------------
581void ofTexture::loadData(const float * data, int w, int h, int glFormat){
582ofSetPixelStoreiAlignment(GL_UNPACK_ALIGNMENT,w,4,ofGetNumChannelsFromGLFormat(glFormat));
583loadData(data, w, h, glFormat, GL_FLOAT);
584}
585
586//----------------------------------------------------------
587void ofTexture::loadData(const ofPixels & pix){
588if(!isAllocated()){
589allocate(pix);
590}else{
591ofSetPixelStoreiAlignment(GL_UNPACK_ALIGNMENT,pix.getBytesStride());
592loadData(pix.getData(), pix.getWidth(), pix.getHeight(), ofGetGLFormat(pix), ofGetGLType(pix));
593}
594}
595
596//----------------------------------------------------------
597void ofTexture::loadData(const ofShortPixels & pix){
598if(!isAllocated()){
599allocate(pix);
600}else{
601ofSetPixelStoreiAlignment(GL_UNPACK_ALIGNMENT,pix.getBytesStride());
602loadData(pix.getData(), pix.getWidth(), pix.getHeight(), ofGetGLFormat(pix), ofGetGLType(pix));
603}
604}
605
606//----------------------------------------------------------
607void ofTexture::loadData(const ofFloatPixels & pix){
608if(!isAllocated()){
609allocate(pix);
610}else{
611ofSetPixelStoreiAlignment(GL_UNPACK_ALIGNMENT,pix.getBytesStride());
612loadData(pix.getData(), pix.getWidth(), pix.getHeight(), ofGetGLFormat(pix), ofGetGLType(pix));
613}
614}
615
616//----------------------------------------------------------
617void ofTexture::loadData(const ofPixels & pix, int glFormat){
618if(!isAllocated()){
619allocate(pix.getWidth(), pix.getHeight(), ofGetGLInternalFormat(pix), ofGetUsingArbTex(), glFormat, ofGetGLType(pix));
620}
621ofSetPixelStoreiAlignment(GL_UNPACK_ALIGNMENT,pix.getWidth(),pix.getBytesPerChannel(),ofGetNumChannelsFromGLFormat(glFormat));
622loadData(pix.getData(), pix.getWidth(), pix.getHeight(), glFormat, ofGetGLType(pix));
623}
624
625//----------------------------------------------------------
626void ofTexture::loadData(const ofShortPixels & pix, int glFormat){
627if(!isAllocated()){
628allocate(pix.getWidth(), pix.getHeight(), ofGetGLInternalFormat(pix), ofGetUsingArbTex(), glFormat, ofGetGLType(pix));
629}
630ofSetPixelStoreiAlignment(GL_UNPACK_ALIGNMENT,pix.getWidth(),pix.getBytesPerChannel(),ofGetNumChannelsFromGLFormat(glFormat));
631loadData(pix.getData(), pix.getWidth(), pix.getHeight(), glFormat, ofGetGLType(pix));
632}
633
634//----------------------------------------------------------
635void ofTexture::loadData(const ofFloatPixels & pix, int glFormat){
636if(!isAllocated()){
637allocate(pix.getWidth(), pix.getHeight(), ofGetGLInternalFormat(pix), ofGetUsingArbTex(), glFormat, ofGetGLType(pix));
638}
639ofSetPixelStoreiAlignment(GL_UNPACK_ALIGNMENT,pix.getWidth(),pix.getBytesPerChannel(),ofGetNumChannelsFromGLFormat(glFormat));
640loadData(pix.getData(), pix.getWidth(), pix.getHeight(), glFormat, ofGetGLType(pix));
641}
642
643#ifndef TARGET_OPENGLES
644//----------------------------------------------------------
645void ofTexture::loadData(const ofBufferObject & buffer, int glFormat, int glType){
646buffer.bind(GL_PIXEL_UNPACK_BUFFER);
647loadData(0,texData.width,texData.height,glFormat,glType);
648buffer.unbind(GL_PIXEL_UNPACK_BUFFER);
649}
650#endif
651
652//----------------------------------------------------------
653void ofTexture::loadData(const void * data, int w, int h, int glFormat, int glType){
654
655if(w > texData.tex_w || h > texData.tex_h) {
656if(isAllocated()){
657allocate(w, h, texData.glInternalFormat, glFormat, glType);
658}else{
659// TODO: guess correct internal from glFormat
660allocate(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
666if (texData.textureTarget == GL_TEXTURE_RECTANGLE_ARB){
667texData.tex_t = w;
668texData.tex_u = h;
669} else
670#endif
671{
672texData.tex_t = (float)(w) / (float)texData.tex_w;
673texData.tex_u = (float)(h) / (float)texData.tex_h;
674}
675
676// bind texture
677glBindTexture(texData.textureTarget, (GLuint) texData.textureID);
678//update the texture image:
679#ifdef TARGET_OF_IOS
680glTexImage2D(texData.textureTarget, 0, texData.glInternalFormat, texData.tex_w, texData.tex_h, 0, glFormat, glType, 0);
681#endif
682glTexSubImage2D(texData.textureTarget, 0, 0, 0, w, h, glFormat, glType, data);
683// unbind texture target by binding 0
684glBindTexture(texData.textureTarget, 0);
685
686if (bWantsMipmap) {
687// auto-generate mipmap, since this ofTexture wants us to.
688generateMipmap();
689}
690
691}
692
693//----------------------------------------------------------
694void 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
703bool isGlGenerateMipmapAvailable = false;
704if(ofIsGLProgrammableRenderer()){
705isGlGenerateMipmapAvailable = true;
706}
707
708
709if (!isGlGenerateMipmapAvailable && !ofGLCheckExtension("GL_EXT_framebuffer_object")) {
710static bool versionWarningIssued = false;
711if (!versionWarningIssued) ofLogWarning() << "Your current OpenGL version does not support mipmap generation via glGenerateMipmap().";
712versionWarningIssued = true;
713texData.hasMipmap = false;
714return;
715}
716
717// 2. Check whether the texture's texture target supports mipmap generation.
718
719switch (texData.textureTarget) {
720/// OpenGL ES only supports mipmap for the following two texture targets:
721case GL_TEXTURE_2D:
722case GL_TEXTURE_CUBE_MAP:
723#ifndef TARGET_OPENGLES
724/// OpenGL supports mipmaps for additional texture targets:
725case GL_TEXTURE_1D:
726case GL_TEXTURE_3D:
727case GL_TEXTURE_1D_ARRAY:
728case 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
736glBindTexture(texData.textureTarget, (GLuint) texData.textureID);
737glGenerateMipmap(texData.textureTarget);
738glBindTexture(texData.textureTarget, 0);
739texData.hasMipmap = true;
740break;
741}
742default:
743{
744// This particular texture target does not support mipmaps.
745static bool warningIssuedAlready = false;
746
747if (!warningIssuedAlready){
748ofLogWarning() << "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.";
751warningIssuedAlready = true;
752}
753texData.hasMipmap = false;
754break;
755}
756} // end switch(texData.textureTarget)
757
758}
759
760//----------------------------------------------------------
761void 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
764int screenHeight = ofGetViewportHeight();
765y = screenHeight - y;
766y -= h; // top, bottom issues
767texData.bFlipTexture = true;
768
769if ( w > texData.tex_w || h > texData.tex_h) {
770ofLogError("ofTexture") << "loadScreenData(): " << w << "x" << h << " image data too big for "
771<< texData.tex_w << "x " << texData.tex_h << " allocated texture, not uploading";
772return;
773}
774
775//update our size with the new dimensions - this should be the same size or smaller than the allocated texture size
776texData.width = w;
777texData.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
781if (texData.textureTarget == GL_TEXTURE_RECTANGLE_ARB){
782texData.tex_t = (float)(w);
783texData.tex_u = (float)(h);
784} else
785#endif
786{
787texData.tex_t = (float)(w) / (float)texData.tex_w;
788texData.tex_u = (float)(h) / (float)texData.tex_h;
789}
790
791
792glBindTexture(texData.textureTarget,texData.textureID);
793
794glCopyTexSubImage2D(texData.textureTarget, 0,0,0,x,y,w,h);
795
796glBindTexture(texData.textureTarget,0);
797
798if (bWantsMipmap) {
799generateMipmap();
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//----------------------------------------------------------
808void ofTexture::setAnchorPercent(float xPct, float yPct){
809anchor.x = xPct;
810anchor.y = yPct;
811
812bAnchorIsPct = true;
813}
814
815//----------------------------------------------------------
816void ofTexture::setAnchorPoint(float x, float y){
817anchor.x = x;
818anchor.y = y;
819
820bAnchorIsPct = false;
821}
822
823//----------------------------------------------------------
824void ofTexture::resetAnchor(){
825anchor = {0.f, 0.f, 0.f};
826bAnchorIsPct = false;
827}
828
829//----------------------------------------------------------
830void ofTexture::bind(int textureLocation) const{
831ofGetGLRenderer()->bind(*this,textureLocation);
832}
833
834//----------------------------------------------------------
835void ofTexture::unbind(int textureLocation) const{
836ofGetGLRenderer()->unbind(*this,textureLocation);
837}
838
839#if !defined(TARGET_OPENGLES) && defined(glBindImageTexture)
840//----------------------------------------------------------
841void ofTexture::bindAsImage(GLuint unit, GLenum access, GLint level, GLboolean layered, GLint layer){
842glBindImageTexture(unit,texData.textureID,level,layered,layer,access,texData.glInternalFormat);
843}
844#endif
845
846//----------------------------------------------------------
847void ofTexture::setAlphaMask(ofTexture & mask){
848if(mask.texData.textureTarget!=this->texData.textureTarget){
849ofLogError("ofTexture") << "Cannot set alpha mask with different texture target";
850}else{
851texData.alphaMask = std::make_shared<ofTexture>(mask);
852}
853}
854
855//----------------------------------------------------------
856const ofTexture * ofTexture::getAlphaMask() const{
857return texData.alphaMask.get();
858}
859
860//----------------------------------------------------------
861void ofTexture::disableAlphaMask(){
862if(texData.alphaMask){
863texData.alphaMask.reset();
864}
865}
866
867
868//----------------------------------------------------------
869glm::vec2 ofTexture::getCoordFromPoint(float xPos, float yPos) const{
870
871glm::vec2 temp(0);
872
873if (!isAllocated()) return temp;
874
875#ifndef TARGET_OPENGLES
876if (texData.textureTarget == GL_TEXTURE_RECTANGLE_ARB){
877
878temp = {xPos, yPos};
879
880} else {
881#endif
882// non arb textures are 0 to 1, so we
883// (a) convert to a pct:
884
885float pctx = xPos / texData.width;
886float pcty = yPos / texData.height;
887
888// (b) mult by our internal pct (since we might not be 0-1 internally)
889
890pctx *= texData.tex_t;
891pcty *= texData.tex_u;
892
893temp = {pctx, pcty};
894
895#ifndef TARGET_OPENGLES
896}
897#endif
898
899return temp;
900
901}
902
903//----------------------------------------------------------
904/// Sets a texture matrix that will be uploaded whenever the texture is
905/// binded.
906void ofTexture::setTextureMatrix(const glm::mat4 & m){
907texData.textureMatrix = m;
908texData.useTextureMatrix = true;
909}
910
911//----------------------------------------------------------
912/// Disable the texture matrix.
913void ofTexture::disableTextureMatrix(){
914texData.useTextureMatrix = false;
915texData.textureMatrix = glm::mat4(1.0);
916}
917
918
919//----------------------------------------------------------
920const glm::mat4 & ofTexture::getTextureMatrix() const{
921return texData.textureMatrix;
922}
923
924//----------------------------------------------------------
925bool ofTexture::isUsingTextureMatrix() const{
926return texData.useTextureMatrix;
927}
928
929//----------------------------------------------------------
930glm::vec2 ofTexture::getCoordFromPercent(float xPct, float yPct) const{
931
932glm::vec2 temp(0);
933
934if (!isAllocated()) return temp;
935
936#ifndef TARGET_OPENGLES
937if (texData.textureTarget == GL_TEXTURE_RECTANGLE_ARB){
938
939temp = {xPct * texData.width, yPct * texData.height};
940
941} else {
942#endif
943xPct *= texData.tex_t;
944yPct *= texData.tex_u;
945temp = {xPct, yPct};
946
947#ifndef TARGET_OPENGLES
948}
949#endif
950return temp;
951}
952
953
954//----------------------------------------------------------
955void ofTexture::setTextureWrap(GLint wrapModeHorizontal, GLint wrapModeVertical) {
956glBindTexture(texData.textureTarget,texData.textureID);
957glTexParameteri(texData.textureTarget, GL_TEXTURE_WRAP_S, wrapModeHorizontal);
958glTexParameteri(texData.textureTarget, GL_TEXTURE_WRAP_T, wrapModeVertical);
959texData.wrapModeVertical = wrapModeVertical;
960texData.wrapModeHorizontal = wrapModeHorizontal;
961glBindTexture(texData.textureTarget,0);
962}
963
964//----------------------------------------------------------
965void ofTexture::setTextureMinMagFilter(GLint minFilter, GLint magFilter){
966
967// Issue warning if mipmaps not present for mipmap based min filter.
968
969if ( (minFilter > GL_LINEAR) && texData.hasMipmap == false ){
970static bool hasWarnedNoMipmapsForMinFilter = false;
971if(!hasWarnedNoMipmapsForMinFilter) {
972ofLogWarning() << "Texture has no mipmaps - but minFilter 0x"<< std::hex << minFilter << " requires mipmaps."
973<< std::endl << "Call ofTexture::generateMipmaps() first.";
974}
975hasWarnedNoMipmapsForMinFilter = true;
976return;
977}
978
979// Issue warning if invalid magFilter specified.
980
981if ( (magFilter > GL_LINEAR ) ) {
982static bool hasWarnedInvalidMagFilter = false;
983if (!hasWarnedInvalidMagFilter) {
984ofLogWarning() << "magFilter must be either GL_LINEAR or GL_NEAREST.";
985}
986hasWarnedInvalidMagFilter = true;
987return;
988}
989
990glBindTexture(texData.textureTarget,texData.textureID);
991glTexParameteri(texData.textureTarget, GL_TEXTURE_MAG_FILTER, magFilter);
992glTexParameteri(texData.textureTarget, GL_TEXTURE_MIN_FILTER, minFilter);
993texData.magFilter = magFilter;
994texData.minFilter = minFilter;
995glBindTexture(texData.textureTarget,0);
996}
997
998//----------------------------------------------------------
999void ofTexture::setCompression(ofTexCompression compression){
1000texData.compressionType = compression;
1001}
1002
1003//------------------------------------
1004void ofTexture::enableMipmap(){
1005bWantsMipmap = true;
1006texData.minFilter = GL_LINEAR_MIPMAP_LINEAR;
1007}
1008
1009//------------------------------------
1010void ofTexture::disableMipmap(){
1011bWantsMipmap = false;
1012texData.minFilter = GL_LINEAR;
1013}
1014
1015//------------------------------------
1016bool ofTexture::hasMipmap() const{
1017return texData.hasMipmap;
1018}
1019
1020//------------------------------------
1021void ofTexture::draw(float x, float y) const{
1022draw(x,y,0,getWidth(),getHeight());
1023}
1024
1025//------------------------------------
1026void ofTexture::draw(float x, float y, float z) const{
1027draw(x,y,z,getWidth(),getHeight());
1028}
1029
1030//------------------------------------
1031void ofTexture::draw(const glm::vec3 & pos) const{
1032draw(pos.x,pos.y,pos.z,getWidth(),getHeight());
1033}
1034
1035//------------------------------------
1036void ofTexture::draw(float x, float y, float w, float h) const{
1037draw(x,y,0,w,h);
1038}
1039
1040void ofTexture::draw(const glm::vec3 & pos, float w, float h) const{
1041draw(pos.x,pos.y,pos.z,w,h);
1042}
1043
1044//------------------------------------
1045void ofTexture::draw(float x, float y, float z, float w, float h) const{
1046drawSubsection(x,y,z,w,h,0,0,getWidth(),getHeight());
1047}
1048
1049//------------------------------------
1050void ofTexture::drawSubsection(float x, float y, float w, float h, float sx, float sy) const{
1051drawSubsection(x,y,0,w,h,sx,sy,w,h);
1052}
1053
1054//------------------------------------
1055void ofTexture::drawSubsection(float x, float y, float w, float h, float sx, float sy, float _sw, float _sh) const{
1056drawSubsection(x,y,0,w,h,sx,sy,_sw,_sh);
1057}
1058
1059//------------------------------------
1060void ofTexture::drawSubsection(const ofRectangle& drawBounds, const ofRectangle& subsectionBounds) const {
1061drawSubsection(drawBounds.x,drawBounds.y,0,drawBounds.width,drawBounds.height,subsectionBounds.x,subsectionBounds.y,subsectionBounds.width,subsectionBounds.height);
1062}
1063
1064//------------------------------------
1065void ofTexture::drawSubsection(float x, float y, float z, float w, float h, float sx, float sy) const{
1066drawSubsection(x,y,z,w,h,sx,sy,w,h);
1067}
1068
1069//----------------------------------------------------------
1070void ofTexture::drawSubsection(float x, float y, float z, float w, float h, float sx, float sy, float sw, float sh) const{
1071std::shared_ptr<ofBaseGLRenderer> renderer = ofGetGLRenderer();
1072if(renderer){
1073renderer->draw(*this,x,y,z,w,h,sx,sy,sw,sh);
1074}
1075}
1076
1077
1078//------------------------------------
1079ofMesh 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{
1080ofMesh quad;
1081if(!texData.bAllocated){
1082return quad;
1083}
1084
1085GLfloat px0 = x; // up to you to get the aspect ratio right
1086GLfloat py0 = y;
1087GLfloat px1 = w+x;
1088GLfloat py1 = h+y;
1089
1090if (texData.bFlipTexture == vflipped){
1091std::swap(py0,py1);
1092}
1093
1094// for rect mode center, let's do this:
1095if (rectMode == OF_RECTMODE_CENTER){
1096px0 -= w/2;
1097py0 -= h/2;
1098px1 -= w/2;
1099py1 -= 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.
1105GLfloat anchorX;
1106GLfloat anchorY;
1107
1108if(bAnchorIsPct){
1109anchorX = anchor.x * w;
1110anchorY = anchor.y * h;
1111}else{
1112anchorX = anchor.x;
1113anchorY = anchor.y;
1114}
1115
1116px0 -= anchorX;
1117py0 -= anchorY;
1118px1 -= anchorX;
1119py1 -= 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
1130GLfloat offsetw = 0.0f;
1131GLfloat offseth = 0.0f;
1132
1133if (!ofGLSupportsNPOTTextures() && bTexHackEnabled) {
1134offsetw = 1.0f / (texData.tex_w);
1135offseth = 1.0f / (texData.tex_h);
1136}
1137// -------------------------------------------------
1138
1139auto topLeft = getCoordFromPoint(sx, sy);
1140auto bottomRight = getCoordFromPoint(sx + sw, sy + sh);
1141
1142GLfloat tx0 = topLeft.x + offsetw;
1143GLfloat ty0 = topLeft.y + offseth;
1144GLfloat tx1 = bottomRight.x - offsetw;
1145GLfloat ty1 = bottomRight.y - offseth;
1146
1147quad.setMode(OF_PRIMITIVE_TRIANGLE_FAN);
1148quad.getVertices().resize(4);
1149quad.getTexCoords().resize(4);
1150quad.getVertices()[0] = {px0,py0,z};
1151quad.getVertices()[1] = {px1,py0,z};
1152quad.getVertices()[2] = {px1,py1,z};
1153quad.getVertices()[3] = {px0,py1,z};
1154
1155quad.getTexCoords()[0] = {tx0,ty0};
1156quad.getTexCoords()[1] = {tx1,ty0};
1157quad.getTexCoords()[2] = {tx1,ty1};
1158quad.getTexCoords()[3] = {tx0,ty1};
1159
1160return quad;
1161}
1162
1163// ROGER
1164//----------------------------------------------------------
1165void 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);
1171std::shared_ptr<ofBaseGLRenderer> renderer = ofGetGLRenderer();
1172if(renderer){
1173bind(0);
1174renderer->draw(getQuad(p1,p2,p3,p4),OF_MESH_FILL);
1175unbind(0);
1176}
1177}
1178
1179ofMesh 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
1188GLfloat offsetw = 0.0f;
1189GLfloat offseth = 0.0f;
1190
1191if (texData.textureTarget == GL_TEXTURE_2D && bTexHackEnabled) {
1192offsetw = 1.0f / (texData.tex_w);
1193offseth = 1.0f / (texData.tex_h);
1194}
1195// -------------------------------------------------
1196
1197GLfloat tx0 = 0+offsetw;
1198GLfloat ty0 = 0+offseth;
1199GLfloat tx1 = texData.tex_t - offsetw;
1200GLfloat ty1 = texData.tex_u - offseth;
1201
1202ofMesh quad;
1203quad.getVertices().resize(4);
1204quad.getTexCoords().resize(4);
1205quad.setMode(OF_PRIMITIVE_TRIANGLE_FAN);
1206quad.getVertices()[0] = {p1.x, p1.y, p1.z};
1207quad.getVertices()[1] = {p2.x, p2.y, p2.z};
1208quad.getVertices()[2] = {p3.x, p3.y, p3.z};
1209quad.getVertices()[3] = {p4.x, p4.y, p4.z};
1210
1211quad.getTexCoords()[0] = {tx0,ty0};
1212quad.getTexCoords()[1] = {tx1,ty0};
1213quad.getTexCoords()[2] = {tx1,ty1};
1214quad.getTexCoords()[3] = {tx0,ty1};
1215return quad;
1216}
1217
1218//----------------------------------------------------------
1219void ofTexture::readToPixels(ofPixels & pixels) const {
1220#ifndef TARGET_OPENGLES
1221pixels.allocate(texData.width,texData.height,ofGetImageTypeFromGLType(texData.glInternalFormat));
1222ofSetPixelStoreiAlignment(GL_PACK_ALIGNMENT,pixels.getWidth(),pixels.getBytesPerChannel(),pixels.getNumChannels());
1223glBindTexture(texData.textureTarget,texData.textureID);
1224glGetTexImage(texData.textureTarget,0,ofGetGLFormat(pixels),GL_UNSIGNED_BYTE, pixels.getData());
1225glBindTexture(texData.textureTarget,0);
1226#endif
1227}
1228
1229//----------------------------------------------------------
1230void ofTexture::readToPixels(ofShortPixels & pixels) const {
1231#ifndef TARGET_OPENGLES
1232pixels.allocate(texData.width,texData.height,ofGetImageTypeFromGLType(texData.glInternalFormat));
1233ofSetPixelStoreiAlignment(GL_PACK_ALIGNMENT,pixels.getWidth(),pixels.getBytesPerChannel(),pixels.getNumChannels());
1234glBindTexture(texData.textureTarget,texData.textureID);
1235glGetTexImage(texData.textureTarget,0,ofGetGLFormat(pixels),GL_UNSIGNED_SHORT,pixels.getData());
1236glBindTexture(texData.textureTarget,0);
1237#endif
1238}
1239
1240void ofTexture::readToPixels(ofFloatPixels & pixels) const {
1241#ifndef TARGET_OPENGLES
1242pixels.allocate(texData.width,texData.height,ofGetImageTypeFromGLType(texData.glInternalFormat));
1243ofSetPixelStoreiAlignment(GL_PACK_ALIGNMENT,pixels.getWidth(),pixels.getBytesPerChannel(),pixels.getNumChannels());
1244glBindTexture(texData.textureTarget,texData.textureID);
1245glGetTexImage(texData.textureTarget,0,ofGetGLFormat(pixels),GL_FLOAT,pixels.getData());
1246glBindTexture(texData.textureTarget,0);
1247#endif
1248}
1249
1250#ifndef TARGET_OPENGLES
1251//----------------------------------------------------------
1252void ofTexture::copyTo(ofBufferObject & buffer) const{
1253ofSetPixelStoreiAlignment(GL_PACK_ALIGNMENT,getWidth(),ofGetBytesPerChannelFromGLType(ofGetGLTypeFromInternal(texData.glInternalFormat)),ofGetNumChannelsFromGLFormat(ofGetGLFormatFromInternal(texData.glInternalFormat)));
1254buffer.bind(GL_PIXEL_PACK_BUFFER);
1255glBindTexture(texData.textureTarget,texData.textureID);
1256glGetTexImage(texData.textureTarget,0,ofGetGLFormatFromInternal(texData.glInternalFormat),ofGetGLTypeFromInternal(texData.glInternalFormat),0);
1257glBindTexture(texData.textureTarget,0);
1258buffer.unbind(GL_PIXEL_PACK_BUFFER);
1259
1260}
1261#endif
1262
1263//----------------------------------------------------------
1264float ofTexture::getHeight() const {
1265return texData.height;
1266}
1267
1268//----------------------------------------------------------
1269float ofTexture::getWidth() const {
1270return texData.width;
1271}
1272