示例#1
0
////////////////////////////////////////////////////////
// render
//
/////////////////////////////////////////////////////////
void pix_cubemap :: render(GemState *state) {
  m_didTexture=false;
  pushTexCoords(state);

  if(!m_textureOnOff)return;

  /* here comes the work: a new image has to be transfered from main memory to GPU and attached to a texture object */
  if(state) {
    pixBlock*img=NULL;
    state->get(GemState::_PIX, img);
    if(img) {
      if(img->newimage)
        m_img[0]=&img->image;
    }
  }


  if(GLEW_VERSION_1_3) {
    glActiveTexture(GL_TEXTURE0_ARB + m_texunit);
  }
  glEnable(m_textureType);
  glBindTexture(m_textureType, m_textureObj);

  int i=0;
  for(i=0; i<6; i++) {
    applyTex(GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, m_img[i]);
    m_img[i]=NULL;
    }

  int mode = GL_NORMAL_MAP;
  switch(m_map) {
  case 0: mode = GL_NORMAL_MAP; break;
  case 1: mode = GL_REFLECTION_MAP; break;
  case 2: mode = GL_SPHERE_MAP; break;
  default: mode=m_map;
  }


  glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, mode);
  glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, mode);
  glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, mode);
  glEnable(GL_TEXTURE_GEN_S);
  glEnable(GL_TEXTURE_GEN_T);
  glEnable(GL_TEXTURE_GEN_R);

  /* cleanup */
  m_rebuildList = 0;
  m_didTexture=true;

  state->set(GemState::_GL_TEX_UNITS, m_numTexUnits);
  state->set(GemState::_GL_TEX_TYPE, 0); // ?

  //  sendExtTexture(m_textureObj, m_xRatio, m_yRatio, m_textureType, upsidedown);
}
示例#2
0
////////////////////////////////////////////////////////
// render
//
/////////////////////////////////////////////////////////
void pix_texture :: render(GemState *state) {
  m_didTexture=false;
  pushTexCoords(state);

  if(!m_textureOnOff)return;

  bool upsidedown=false;
  bool normalized=true;
  bool canMipmap=m_canMipmap;

  int texType = m_textureType;
  int x_2=1, y_2=1;
  bool useExternalTexture=false;
  int do_rectangle = (m_rectangle)?m_canRectangle:0;
  int newfilm = 0;
  pixBlock*img=NULL;


  state->get(GemState::_PIX, img);
  if(img)
    newfilm = img->newfilm;

  if (!img || !img->image.data){
    if(m_extTextureObj>0) {
      useExternalTexture= true;
      m_rebuildList     = false;
      m_textureObj      = m_extTextureObj;
      if(m_extType)m_textureType=m_extType;
      texType=m_textureType;
      upsidedown=m_extUpsidedown;
      m_xRatio=m_extWidth;
      m_yRatio=m_extHeight;
      m_upsidedown=upsidedown;
    } else
      /* neither do we have an image nor an external texture */
      return;
  }
  tex2state(state, m_coords, 4);

  if(!useExternalTexture){
    upsidedown = img->image.upsidedown;
    if (img->newimage) m_rebuildList = true;

    m_imagebuf.xsize =img->image.xsize;
    m_imagebuf.ysize =img->image.ysize;
    m_imagebuf.csize =img->image.csize;
    m_imagebuf.format=img->image.format;
    m_imagebuf.type  =img->image.type;
    m_imagebuf.data  =img->image.data;

    x_2 = powerOfTwo(m_imagebuf.xsize);
    y_2 = powerOfTwo(m_imagebuf.ysize);

    normalized = ((m_imagebuf.xsize==x_2) && (m_imagebuf.ysize==y_2));

    debug("normalized=%d\t%d - %d\t%d - %d", normalized, m_imagebuf.xsize, x_2, m_imagebuf.ysize, y_2);

    switch(do_rectangle) {
    case 2:
      m_textureType = GL_TEXTURE_RECTANGLE_ARB;
      debug("using mode 1:GL_TEXTURE_RECTANGLE_ARB");
      normalized = 0;
      canMipmap = false;
      break;
    case 1:
      m_textureType = GL_TEXTURE_RECTANGLE_EXT;
      debug("using mode 1:GL_TEXTURE_RECTANGLE_EXT");
      normalized = 0;
      canMipmap = false;
      break;
    default:
      m_textureType = GL_TEXTURE_2D;
      debug("using mode 0:GL_TEXTURE_2D");
      normalized = 0;
      break;
    }

    debug("normalized=%d", normalized);
  }

  if (m_textureType!=texType){
    debug("texType != m_textureType");
    stopRendering();startRendering();
  }

  if(GLEW_VERSION_1_3) {
    glActiveTexture(GL_TEXTURE0_ARB + m_texunit);
  }
  glEnable(m_textureType);
  glBindTexture(m_textureType, m_textureObj);

  if ((!useExternalTexture)&&newfilm ){
    //  tigital:  shouldn't we also allow TEXTURE_2D here?
    if(NULL!=glTextureRangeAPPLE) {
      if ( GLEW_APPLE_texture_range ){
        if(glTextureRangeAPPLE == NULL) {
          glTextureRangeAPPLE( m_textureType,
                               m_imagebuf.xsize * m_imagebuf.ysize * m_imagebuf.csize,
                               m_imagebuf.data );
          debug("using glTextureRangeAPPLE()");
        }else{
          glTextureRangeAPPLE( m_textureType, 0, NULL );
        }
      }
    }

    /* hmm, GL_TEXTURE_STORAGE_HINT_APPLE throws a GL-error on linux (and probably on w32 too)
     * how to do a run-time check for it?
     *
     * according to http://developer.apple.com/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_texturedata/chapter_10_section_2.html
     * this seems to be a part of the texture_range extension, so we check for that!
     */
    if(GLEW_APPLE_texture_range)
       glTexParameteri( m_textureType, GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_SHARED_APPLE );
    // GL_STORAGE_SHARED_APPLE -  AGP texture path
    // GL_STORAGE_CACHED_APPLE - VRAM texture path
    // GL_STORAGE_PRIVATE_APPLE - normal texture path
    if(m_clientStorage) glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
  }



  /* here comes the work: a new image has to be transfered from main memory to GPU and attached to a texture object */

  if (m_rebuildList) {
    // if YUV is not supported on this platform, we have to convert it to RGB
    //(skip Alpha since it isnt used)
    const bool do_yuv = m_yuv && GLEW_APPLE_ycbcr_422;
    if (!do_yuv && m_imagebuf.format == GL_YUV422_GEM){
      m_imagebuf.format=GL_RGB;
      m_imagebuf.csize=3;
      m_imagebuf.reallocate();
      if(img)m_imagebuf.fromYUV422(img->image.data);
    }
    if (normalized) {
      m_buffer.xsize = m_imagebuf.xsize;
      m_buffer.ysize = m_imagebuf.ysize;
      m_buffer.csize  = m_imagebuf.csize;
      m_buffer.format = m_imagebuf.format;
      m_buffer.type   = m_imagebuf.type;
      m_buffer.reallocate();
      m_xRatio=1.0;
      m_yRatio=1.0;
      m_upsidedown=upsidedown;

      tex2state(state, m_coords, 4);
      if (m_buffer.csize != m_dataSize[0] ||
          m_buffer.xsize != m_dataSize[1] ||
          m_buffer.ysize != m_dataSize[2]){
        m_dataSize[0] = m_buffer.csize;
        m_dataSize[1] = m_buffer.xsize;
        m_dataSize[2] = m_buffer.ysize;

      }
      //if the texture is a power of two in size then there is no need to subtexture
      glTexImage2D(m_textureType, 0,
                   m_imagebuf.csize,
                   m_imagebuf.xsize,
                   m_imagebuf.ysize, 0,
                   m_imagebuf.format,
                   m_imagebuf.type,
                   m_imagebuf.data);
      m_hasMipmap = false;

    } else { // !normalized
      m_xRatio = (float)m_imagebuf.xsize;
      m_yRatio = (float)m_imagebuf.ysize;
      if ( !do_rectangle ) {
        m_xRatio /= (float)x_2;
        m_yRatio /= (float)y_2;
        m_buffer.xsize = x_2;
        m_buffer.ysize = y_2;
      } else {
        m_buffer.xsize = m_imagebuf.xsize;
        m_buffer.ysize = m_imagebuf.ysize;
      }

      m_buffer.csize  = m_imagebuf.csize;
      m_buffer.format = m_imagebuf.format;
      m_buffer.type   = m_imagebuf.type;
      m_buffer.reallocate();
      m_upsidedown=upsidedown;
      tex2state(state, m_coords, 4);

      if (m_buffer.csize != m_dataSize[0] ||
          m_buffer.xsize != m_dataSize[1] ||
          m_buffer.ysize != m_dataSize[2]){
        newfilm = 1;

      } //end of loop if size has changed

      // okay, load in the actual pixel data

      //when doing rectangle textures the buffer changes after every film is loaded this call makes sure the
      //texturing is updated as well to prevent crashes
      if(newfilm) {
        m_dataSize[0] = m_buffer.csize;
        m_dataSize[1] = m_buffer.xsize;
        m_dataSize[2] = m_buffer.ysize;

        if (m_buffer.format == GL_YUV422_GEM && !m_rectangle)m_buffer.setBlack();

        if(m_numPbo>0) {
          if(GLEW_ARB_pixel_buffer_object) {
            if(m_pbo) {
              delete[]m_pbo;
              m_pbo=NULL;
            }
            m_pbo=new GLuint[m_numPbo];
            glGenBuffersARB(m_numPbo, m_pbo);
            int i=0;
            for(i=0; i<m_numPbo; i++) {
              glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, m_pbo[i]);
              glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB,
                              m_buffer.xsize*m_buffer.ysize*m_buffer.csize,
                              0, GL_STREAM_DRAW_ARB);
            }
            glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);

          } else {
            verbose(1, "PBOs not supported! disabling");
            m_numPbo=0;

          }
        }

        //this is for dealing with power of 2 textures which need a buffer that's 2^n
        if ( !do_rectangle ) {
          glTexImage2D(	m_textureType, 0,
                        //m_buffer.csize,
                        GL_RGBA,
                        m_buffer.xsize,
                        m_buffer.ysize, 0,
                        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,
                       //  m_buffer.csize,
                       GL_RGBA,
                       m_imagebuf.xsize,
                       m_imagebuf.ysize, 0,
                       m_imagebuf.format,
                       m_imagebuf.type,
                       m_imagebuf.data);
          m_hasMipmap = false;
          debug("TexImage2D  rectangle");
        }

        // just to make sure...
        img->newfilm = 0;
      }

      if(m_pbo && m_numPbo) {
        m_curPbo=(m_curPbo+1)%m_numPbo;
        int index=m_curPbo;
        int nextIndex=(m_curPbo+1)%m_numPbo;

        glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, m_pbo[index]);
        glTexSubImage2D(m_textureType, 0,
                        0, 0,
                        m_imagebuf.xsize,
                        m_imagebuf.ysize,
                        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);

        GLubyte* ptr = (GLubyte*)glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB);
        if(ptr)
          {
            // update data off the mapped buffer
            memcpy(ptr, m_imagebuf.data,  m_imagebuf.xsize * m_imagebuf.ysize * m_imagebuf.csize);
            glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB); // release pointer to mapping buffer
          }

        /* unbind the current buffer */
        glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);

      } else {
        glTexSubImage2D(m_textureType, 0,
                        0, 0,				// position
                        m_imagebuf.xsize,
                        m_imagebuf.ysize,
                        m_imagebuf.format,
                        m_imagebuf.type,
                        m_imagebuf.data);
        m_hasMipmap = false;
      }
    }
  } // rebuildlist

  if (m_wantMipmap && canMipmap && !m_hasMipmap) {
    glGenerateMipmap(m_textureType);
    m_hasMipmap = true;
  }
  setTexFilters(m_textureMinQuality != GL_LINEAR_MIPMAP_LINEAR || (m_wantMipmap && canMipmap));

  setTexCoords(m_coords, m_xRatio, m_yRatio, m_upsidedown);

  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, m_env);

  /* cleanup */
  m_rebuildList = false;
  m_didTexture=true;

  state->set(GemState::_GL_TEX_UNITS, m_numTexUnits);

  // if we are using rectangle textures, this is a way to inform the downstream objects
  // (this is important for things like [pix_coordinate]

  // we don't use switch/case as _ARB and _EXT might be the same...
  if(m_textureType==GL_TEXTURE_RECTANGLE_ARB || m_textureType==GL_TEXTURE_RECTANGLE_EXT) {
    state->set(GemState::_GL_TEX_TYPE, 2);
  } else {
    state->set(GemState::_GL_TEX_TYPE, 1);
  }
  
  m_baseCoord.s=m_xRatio;
  m_baseCoord.t=m_yRatio;
  state->set(GemState::_GL_TEX_BASECOORD, m_baseCoord);
  state->set(GemState::_GL_TEX_ORIENTATION, upsidedown);

  sendExtTexture(m_textureObj, m_xRatio, m_yRatio, m_textureType, upsidedown);
}