[PATCH] first try at mipmap support for pix_texture

Claude Heiland-Allen claude at mathr.co.uk
Tue Mar 26 03:47:56 CET 2013


---
 src/Pixes/pix_texture.cpp |   58 ++++++++++++++++++++++++++++++++-------------
 src/Pixes/pix_texture.h   |    4 +++-
 2 files changed, 45 insertions(+), 17 deletions(-)

diff --git a/src/Pixes/pix_texture.cpp b/src/Pixes/pix_texture.cpp
index 2209f09..ec57790 100644
--- a/src/Pixes/pix_texture.cpp
+++ b/src/Pixes/pix_texture.cpp
@@ -45,7 +45,9 @@ CPPEXTERN_NEW(pix_texture);
 /////////////////////////////////////////////////////////
 pix_texture :: pix_texture()
   : m_textureOnOff(1),
-    m_textureQuality(GL_LINEAR), m_repeat(GL_REPEAT), m_doRepeat(GL_REPEAT),
+    m_textureMinQuality(GL_LINEAR), m_textureMagQuality(GL_LINEAR),
+    m_wantMipmap(false), m_canMipmap(false), m_hasMipmap(false),
+    m_repeat(GL_REPEAT), m_doRepeat(GL_REPEAT),
     m_didTexture(false), m_rebuildList(false),
     m_textureObj(0),
     m_extTextureObj(0), m_extWidth(1.), m_extHeight(1.), m_extType(GL_TEXTURE_2D),
@@ -135,12 +137,20 @@ void pix_texture :: setUpTextureState() {
   } else
     glPixelStoref(GL_UNPACK_ALIGNMENT, 1);
 
-  glTexParameterf(m_textureType, GL_TEXTURE_MIN_FILTER, m_textureQuality);
-  glTexParameterf(m_textureType, GL_TEXTURE_MAG_FILTER, m_textureQuality);
+  setTexFilters();
   glTexParameterf(m_textureType, GL_TEXTURE_WRAP_S, m_doRepeat);
   glTexParameterf(m_textureType, GL_TEXTURE_WRAP_T, m_doRepeat);
 }
 
+void pix_texture :: setTexFilters() {
+  glTexParameterf(m_textureType, GL_TEXTURE_MAG_FILTER, m_textureMagQuality);
+  if (m_textureMinQuality != GL_LINEAR_MIPMAP_LINEAR || (m_wantMipmap && m_canMipmap)) {
+    glTexParameterf(m_textureType, GL_TEXTURE_MIN_FILTER, m_textureMinQuality);
+  } else {
+    glTexParameterf(m_textureType, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+  }
+}
+
 ////////////////////////////////////////////////////////
 // setTexCoords
 //
@@ -300,16 +310,19 @@ void pix_texture :: render(GemState *state) {
       m_textureType = GL_TEXTURE_RECTANGLE_ARB;
       debug("using mode 1:GL_TEXTURE_RECTANGLE_ARB");
       normalized = 0;
+      m_canMipmap = false;
       break;
     case 1:
       m_textureType = GL_TEXTURE_RECTANGLE_EXT;
       debug("using mode 1:GL_TEXTURE_RECTANGLE_EXT");
       normalized = 0;
+      m_canMipmap = false;
       break;
     default:
       m_textureType = GL_TEXTURE_2D;
       debug("using mode 0:GL_TEXTURE_2D");
       normalized = 0;
+      m_canMipmap = true;
       break;
     }
 
@@ -327,11 +340,6 @@ void pix_texture :: render(GemState *state) {
   glEnable(m_textureType);
   glBindTexture(m_textureType, m_textureObj);
 
-  if(useExternalTexture) {
-    glTexParameterf(m_textureType, GL_TEXTURE_MAG_FILTER, m_textureQuality);
-    glTexParameterf(m_textureType, GL_TEXTURE_MIN_FILTER, m_textureQuality);
-  }
-
   if ((!useExternalTexture)&&newfilm ){
     //  tigital:  shouldn't we also allow TEXTURE_2D here?
     if(NULL!=glTextureRangeAPPLE) {
@@ -403,6 +411,7 @@ void pix_texture :: render(GemState *state) {
                    m_imagebuf.format,
                    m_imagebuf.type,
                    m_imagebuf.data);
+      m_hasMipmap = false;
 
     } else { // !normalized
       m_xRatio = (float)m_imagebuf.xsize;
@@ -476,7 +485,7 @@ void pix_texture :: render(GemState *state) {
                         m_buffer.format,
                         m_buffer.type,
                         m_buffer.data);
-
+          m_hasMipmap = false;
           debug("TexImage2D non rectangle");
         } else {//this deals with rectangle textures that are h*w
           glTexImage2D(m_textureType, 0,
@@ -487,6 +496,7 @@ void pix_texture :: render(GemState *state) {
                        m_imagebuf.format,
                        m_imagebuf.type,
                        m_imagebuf.data);
+          m_hasMipmap = false;
           debug("TexImage2D  rectangle");
         }
 
@@ -507,7 +517,7 @@ void pix_texture :: render(GemState *state) {
                         m_imagebuf.format,
                         m_imagebuf.type,
                         NULL); /* <-- that's the key */
-
+        m_hasMipmap = false;
 
         glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, m_pbo[nextIndex]);
         glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB,  m_imagebuf.xsize * m_imagebuf.ysize * m_imagebuf.csize, 0, GL_STREAM_DRAW_ARB);
@@ -531,10 +541,17 @@ void pix_texture :: render(GemState *state) {
                         m_imagebuf.format,
                         m_imagebuf.type,
                         m_imagebuf.data);
+        m_hasMipmap = false;
       }
     }
   } // rebuildlist
 
+  if (m_wantMipmap && m_canMipmap && !m_hasMipmap) {
+    glGenerateMipmap(m_textureType);
+    m_hasMipmap = true;
+  }
+  setTexFilters();
+
   setTexCoords(m_coords, m_xRatio, m_yRatio, m_upsidedown);
 
   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, m_env);
@@ -656,18 +673,27 @@ void pix_texture :: textureOnOff(int on)
 /////////////////////////////////////////////////////////
 void pix_texture :: textureQuality(int type)
 {
-  if (type)
-    m_textureQuality = GL_LINEAR;
-  else
-    m_textureQuality = GL_NEAREST;
+  if (type == 2) {
+    m_textureMinQuality = GL_LINEAR_MIPMAP_LINEAR;
+    m_textureMagQuality = GL_LINEAR;
+    m_wantMipmap = true;
+  } else {
+    m_wantMipmap = false;
+    if (type) {
+      m_textureMinQuality = GL_LINEAR;
+      m_textureMagQuality = GL_LINEAR;
+    } else {
+      m_textureMinQuality = GL_NEAREST;
+      m_textureMagQuality = GL_NEAREST;
+    }
+  }
 
   if (m_textureObj) {
     if(GLEW_VERSION_1_3) {
       glActiveTexture(GL_TEXTURE0_ARB + m_texunit);
     }
     glBindTexture(m_textureType, m_textureObj);
-    glTexParameterf(m_textureType, GL_TEXTURE_MAG_FILTER, m_textureQuality);
-    glTexParameterf(m_textureType, GL_TEXTURE_MIN_FILTER, m_textureQuality);
+    setTexFilters();
   }
   setModified();
 }
diff --git a/src/Pixes/pix_texture.h b/src/Pixes/pix_texture.h
index 2145b4d..fe2c39a 100644
--- a/src/Pixes/pix_texture.h
+++ b/src/Pixes/pix_texture.h
@@ -83,6 +83,7 @@ class GEM_EXTERN pix_texture : public GemBase
   //////////
   // Set up the texture state
   void		setUpTextureState(void);
+  void setTexFilters(void);
   void pushTexCoords(GemState*);
   void popTexCoords(GemState*);
 
@@ -111,7 +112,8 @@ class GEM_EXTERN pix_texture : public GemBase
 
   //////////
   // Set the texture quality
-  GLuint		  m_textureQuality;
+  GLuint      m_textureMinQuality, m_textureMagQuality;
+  bool        m_wantMipmap, m_canMipmap, m_hasMipmap;
 
   //////////
   // Set the texture quality
-- 
1.7.10.4


--------------070005050809030303080602
Content-Type: text/plain;
 name="pix_texture-help.pd"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="pix_texture-help.pd"

#N canvas 43 49 647 715 10;
#X text 452 8 GEM object;
#X obj 8 392 cnv 15 430 360 empty empty empty 20 12 0 14 -233017 -66577
0;
#X text 19 394 Inlets:;
#X text 22 665 Outlets:;
#X obj 8 352 cnv 15 430 30 empty empty empty 20 12 0 14 -195568 -66577
0;
#X text 17 351 Arguments:;
#X obj 8 56 cnv 15 430 285 empty empty empty 20 12 0 14 -233017 -66577
0;
#X obj 449 77 cnv 15 170 600 empty empty empty 20 12 0 14 -228992 -66577
0;
#X text 453 60 Example:;
#X obj 515 572 cnv 15 100 60 empty empty empty 20 12 0 14 -195568 -66577
0;
#N canvas 0 50 450 300 gemwin 0;
#X obj 132 136 gemwin;
#X obj 67 89 outlet;
#X obj 67 10 inlet;
#X obj 67 41 route create;
#X msg 67 70 set destroy;
#X msg 142 68 set create;
#X msg 132 112 create \, 1;
#X msg 198 112 destroy;
#X msg 234 221 dimen 500 500;
#X msg 279 189 dimen 1024 768;
#X connect 2 0 3 0;
#X connect 3 0 4 0;
#X connect 3 0 6 0;
#X connect 3 1 5 0;
#X connect 3 1 7 0;
#X connect 4 0 1 0;
#X connect 5 0 1 0;
#X connect 6 0 0 0;
#X connect 7 0 0 0;
#X connect 8 0 0 0;
#X connect 9 0 0 0;
#X restore 520 611 pd gemwin;
#X msg 520 592 create;
#X text 516 571 Create window:;
#X obj 455 276 cnv 15 160 265 empty empty empty 20 12 0 14 -24198 -66577
0;
#X obj 451 84 gemhead;
#X text 71 31 Class: pix object;
#X obj 510 85 bng 15 250 50 0 empty empty pix_load 20 8 0 8 -262144
-1 -1;
#N canvas 0 50 587 366 image 0;
#X obj 77 48 inlet;
#X obj 77 344 outlet;
#X obj 77 205 pix_image examples/data/fractal.JPG;
#X obj 223 55 inlet;
#X msg 223 123 open \$1;
#X obj 223 100 openpanel;
#X text 312 85 re-send the image to the [pix_]-object;
#X text 231 37 open;
#X text 79 30 gemlist;
#X connect 0 0 2 0;
#X connect 2 0 1 0;
#X connect 3 0 5 0;
#X connect 4 0 2 0;
#X connect 5 0 4 0;
#X restore 451 113 pd image;
#X obj 454 547 pix_texture;
#X text 63 362 <none>;
#X text 57 682 Outlet 1: gemlist;
#X text 33 408 Inlet 1: gemlist;
#X obj 452 571 square 3;
#X text 516 105 open an image;
#X text 509 118 (JPEG \, TIFF \, ..);
#X text 50 12 Synopsis: [pix_texture];
#X text 29 57 Description: apply texture mapping;
#X text 16 79 enables texture mapping with the current pix. Whatever
pix values are in the network currently will be used (ie \, all processing
after the pix_texture will not have any effect).;
#X msg 461 451 quality \$1;
#X obj 461 432 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
1;
#X text 33 423 Inlet 1: 0|1 turn texturing On/off;
#X text 33 437 Inlet 1: quality 0|1 : GL_NEAREST | GL_LINEAR(default)
;
#X text 15 122 Send a quality message to change the quality of the
texture mapping. GL_LINEAR is better than GL_NEAREST (but also more
computationally expensive). However \, on many machines (especially
SGIs) \, there is no speed difference.;
#X text 14 233 [pix_texture] is able to texture images of ANY size
(even non-power of 2);
#X obj 542 472 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
1;
#X msg 542 491 rectangle \$1;
#X obj 469 497 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
1;
#X obj 542 432 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
1;
#X msg 469 516 client_storage \$1;
#X msg 542 451 repeat \$1;
#X text 33 453 Inlet 1: repeat 0|1 : CLAMP_TO_EDGE or REPEAT(default)
;
#X text 32 470 Inlet 1: rectangle 0|1 : use rectangle-texturing if
available (default=1);
#X text 32 498 Inlet 1: client_storage 0|1 : use client-storage if
available (default=1);
#X msg 493 407 env \$1;
#X obj 493 387 hradio 15 1 0 6 empty empty empty 0 -6 0 8 -262144 -1
-1 0;
#X obj 472 222 pack 0 0 1;
#X obj 452 243 color 0 0.5 0;
#X obj 498 196 t b f;
#X obj 499 177 nbx 3 14 0 1 0 0 empty empty green 0 -6 0 10 -262144
-1 -1 0 256;
#X obj 540 196 t b f;
#X obj 541 177 nbx 3 14 0 1 0 0 empty empty blue 0 -6 0 10 -262144
-1 -1 0 256;
#X obj 458 196 nbx 3 14 0 1 0 0 empty empty red 0 -6 0 10 -262144 -1
-1 0 256;
#X text 14 262 [pix_texture] tries to use the fastest way to get a
pix onto a texture. This implies using "rectangle"-texturing if available.
This \, in turn \, can lead to some problems with several geos. Try
using "rectangle 0" if you experience problems. Rectangle textures
cannot be REPEATed (they are always clamped-to-edge);
#X text 32 526 Inlet 1: env 0|1|2|3|4|5 : texture environment mode
;
#X text 57 541 0=GL_REPLACE \, 1=GL_DECAL \, 2=GL_BLEND \, 3=GL_ADD
\,;
#X text 57 556 4=GL_COMBINE \, >4=GL_MODULATE (default);
#X text 16 176 - env message changes the texture environment mode.
Some modes allow mixing with fragment colors (BLEND \, ADD \, COMBINE
\, MODULATE) \, while REPLACE and DECAL ignore the current fragment/texture
color.;
#X text 457 149 set base fragment color;
#X text 57 700 Outlet 2: texture info : <id> <width> <height> <type>
<upsidedown flag>;
#X text 32 576 Inlet 1: message: texunit <f>;
#X text 112 611 (usefull only with shader);
#X text 112 594 (change texunit of the texture);
#X floatatom 463 286 5 0 0 0 - - -;
#X msg 463 305 texunit \$1;
#X obj 473 331 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
1;
#X msg 473 351 yuv \$1;
#X text 32 646 Inlet 1: message: pbo : change pixel buffer object number
;
#X floatatom 537 332 5 0 0 0 - - -;
#X msg 537 351 pbo \$1;
#X text 32 626 Inlet 1: message: yuv : use native YUV-mode if available (default: 1);
#X connect 10 0 11 0;
#X connect 11 0 10 0;
#X connect 14 0 17 0;
#X connect 16 0 17 1;
#X connect 17 0 46 0;
#X connect 18 0 22 0;
#X connect 28 0 18 0;
#X connect 29 0 28 0;
#X connect 34 0 35 0;
#X connect 35 0 18 0;
#X connect 36 0 38 0;
#X connect 37 0 39 0;
#X connect 38 0 18 0;
#X connect 39 0 18 0;
#X connect 43 0 18 0;
#X connect 44 0 43 0;
#X connect 45 0 46 1;
#X connect 46 0 18 0;
#X connect 47 0 45 0;
#X connect 47 1 45 1;
#X connect 48 0 47 0;
#X connect 49 0 45 0;
#X connect 49 1 45 2;
#X connect 50 0 49 0;
#X connect 51 0 45 0;
#X connect 62 0 63 0;
#X connect 63 0 18 0;
#X connect 64 0 65 0;
#X connect 65 0 18 0;
#X connect 67 0 68 0;
#X connect 68 0 18 0;

--------------070005050809030303080602--



More information about the GEM-dev mailing list